// RadiusClt1.h: interface for the RadiusClt class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(__RADIUSCLT_H__)
#define __RADIUSCLT_H__

//#if _MSC_VER > 1000
//#pragma once
//#endif // _MSC_VER > 1000
#define		MAX_HOSTLEN					20		//主机ip最大长度(*.*.*.*格式)
#define		MAX_SHARELEN				20		//共享密钥最大长度
#define		MAX_PWDLEN					128		//密码最大长度
#define		MAX_PACKETLEN				512		//请求包最大长度
#define		RD_ERROR_SUCCESS			0		//成功
#define		RD_ERROR_INVALID_USERNAME	-1		//用户名不可用
#define		RD_ERROR_INVALID_PWD		-2		//密码不可用
#define		RD_ERROR_INVALIDHOST		-3		//认证服务不可用
#define		RD_ERROR_INVALIDPCNAME		-4		//得到计算机名失败
#define		RD_ERROR_GENRAFAILED		-5		//生成请求认证字失败
#define		RD_ERROR_GENPWDFAILED		-6		//生成密码密文失败
#define		RD_ERROR_CREATEPKTFAILED	-7		//生成认证数据包失败
#define		RD_ERROR_CREATESOCKETFAILED -8		//初始化套接字失败
#define		RD_ERROR_SENDDATAFAILED		-9		//发送数据失败
#define		RD_ERROR_RECVDATAFAILED		-10		//接受数据失败
#define		RD_ERROR_INVALIDPKT			-11		//无效数据包
#define		RD_ERROR_NORESPONSE			-12		//请求无响应
#define		RD_ERROR_AUTHFAILED			-13		//接入请求失败
#define		RD_ERROR_GETCHALLENGEFAILED -14		//获得挑战失败
#define     RD_ERROR_REMOTESOCKETCLOSED -15		//服务套接字关闭
#define     RD_ERROR_INITSOCKFAILED		-16		//wsastartup失败(win)
#define		RD_ERROR_INVALIDCONFIGFILE	-17		//配置文件路径不可用

#define		RD_ERROR_CHALLENGENEED		1		//需要回应挑战


//////////////////////////////////////////////////////////
#define		RD_REQUESTCODE_AUTH		1		//请求接入
#define		RD_REQUESTCODE_ACCEPT	2		//认证成功
#define		RD_REQUESTCODE_REJECT	3		//接入拒绝
#define		RD_REQUESTCODE_CHALLENGE 11		//挑战应答

#ifndef NULL
#define NULL 0
#endif
#ifndef SOCKET_ERROR
#define SOCKET_ERROR -1
#endif

////////////////////////////////////////////////////////////////////////////////////////////////
// Class RadiusClt
// remark: 组织认证数据进行身份认证,并解析认证结果.该类的使用方法为
//		  1、实例化类对象(该类的构造函数需要提供:认证服务器IP、共享密钥、共享密钥长度、认证端口号)
//
//////////////////////////////////////////////////////////////////////////////////////////////////

class RadiusClt  
{
public:
	RadiusClt();
	RadiusClt(char *pHost, char *pshare, int nsharelen, unsigned short uPort = 1812, int nwaittime = 3);
	virtual ~RadiusClt();
	int parase(char *pUsername, int namelen, char *pPwd, int pwdlen);
	
	int initrad(char *pHost, char *pshare, int nsharelen, unsigned short uPort = 1812, int nwaittime = 3);
	int auth(int &nchallenge, int &bvalidresponse, char *pszresponse = NULL, int nmaxbuflen = 0);
	
private:
	int getpcname(char *pbuf, int len);
	int createauthpkt();
	void setattr(int atttype, unsigned char *pval, int vallen, int& noffset);
	bool genpwd(unsigned char *pra, unsigned char *pshare, int nshrelen, unsigned char *pinpwd, int ninpwdlen, unsigned char *poutpwd, int& noutpwdlen);
	bool checkpktvalid(unsigned char *precvpkt);
	bool getchallenge(unsigned char *pattr,  int npktlen, int &nchg, int &bvalidresponse, char *pszresponse = NULL, int nmaxbuflen = 0);
	//data
	unsigned char m_ra[16];
	//最长等待时间
	int m_nwaittime;

	unsigned char m_share[MAX_SHARELEN+1];
	int m_nsharelen;
	char m_host[MAX_HOSTLEN+1];
	char m_username[MAX_HOSTLEN+1];
	int m_nusernamelen;
	char m_userpwd[MAX_HOSTLEN+1];
	int m_nuserpwdlen;
	char m_hostpcname[2*MAX_HOSTLEN+1];
	unsigned char m_authpkt[MAX_PACKETLEN+1];
	unsigned short m_port;
	bool m_bvalidhost;
	bool m_bvalidpcname;
	int m_npacketlen;

};

#endif // !defined(__RADIUSCLT_H__)
