///////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Filename:PKUIPGW.cpp
/// Author: Linxh
/// Version: 0.1
/// Date: 2007-01-01
///
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <iostream>
#include <fstream>
using namespace std;
#ifdef WIN32
#pragma comment(lib, "ws2_32")
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
#endif
#include <wx/wx.h>
#define UPLEN 16
typedef struct _operation {
char usr[UPLEN];
char passwd[UPLEN];
char op[32];
int range;
int timeout;
} op_t;
#define gateway_ip "162.105.67.5"
#define gateway_hostname "ipgw.pku.edu.cn"
char *httpheader="POST /ipgw/ipgw.ipgw HTTP/1.1\r\n"
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*\r\n"
"Accept-Language: zh-cn\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Accept-Encoding: gzip, deflate\r\n"
"User-Agent: PKUIPGW Certificating Client version 0.1(Alpha)\r\n"
"Host: ipgw.pku.edu.cn\r\n";
int format(char s[],char r[])
{
char * beg,*end,*nl;
beg=strstr(s,"<table");
if(beg==NULL) beg=strstr(s,"<TABLE");
end=strstr(s,"</table");
if(end==NULL) end=strstr(s,"</TABLE");
if(beg==NULL || end==NULL)
return -1;
nl=strstr(beg,"<br>");
while(nl && nl<end) {
*nl=' ';
*(nl+1)=' ';
*(nl+2)=' ';
*(nl+3)='\n';
nl=strstr(nl,"<br>");
}
int i=0;
while(beg<end) {
while(*beg!='>')
beg++;
beg++;
while(*beg!='<')
r[i++]=*beg++;
}
r[i]=0;
nl=strstr(r," ");
while(nl) {
for(i=0;i<6;i++)
*(nl+i)=' ';
nl=strstr(r," ");
}
return 0;
}
int ipgw_operation(op_t * opp)
{
char buffer[4096];
char info[1024];
#ifdef WIN32
WSADATA WSAData;
int nRetCode = 0;
if ((nRetCode=WSAStartup(MAKEWORD(2,2),&WSAData))!= 0 ) {
return nRetCode;
}
#endif
struct sockaddr_in server;
int sockfd;
SSL_CTX * ctx ;
SSL * ssl;
SSL_library_init();
ctx= SSL_CTX_new(SSLv3_client_method());
if(ctx==NULL) {
return -1;
}
ssl=SSL_new(ctx);
if(ssl==NULL) {
return -1;
}
sockfd=socket(PF_INET,SOCK_STREAM,0);
if(sockfd<0) {
return -1;
}
memset(&server,0,sizeof(server));
struct hostent * h;
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr(gateway_ip);
server.sin_port=htons(443);
if(connect(sockfd,(struct sockaddr*)&server,sizeof(server))<0) {
if((h=gethostbyname(gateway_hostname))!=NULL) {
server.sin_addr=*((struct in_addr*)h->h_addr);
if(connect(sockfd,(struct sockaddr*)&server,sizeof(server))<0) {
return -1;
}
}
else {
return -1;
}
}
SSL_set_fd(ssl,sockfd);
if(SSL_set_fd(ssl,sockfd)==0) {
return -1;
}
if(SSL_connect(ssl)!=1) {
return -1;
}
char request[1024];
char tmp[1024];
char data[1024];
char password[64];
size_t i,n;
password[0]=0;
n=strlen(opp->passwd);
for(i=0;i<n;i++) {
sprintf(tmp,"%%%02X",opp->passwd[i]);
if(tmp[1]>'1')
strcat(password,tmp);
}
sprintf(data,"uid=%s&password=%s&operation=%s&range=%d&timeout=%d",opp->usr,password,opp->op,opp->range,opp->timeout);
sprintf(request,"%s",httpheader);
sprintf(tmp,"Content-Length:%d\r\n\r\n",strlen(data));
strcat(request,tmp);
strcat(request,data);
int r=SSL_write(ssl,request,strlen(request));
if(SSL_get_error(ssl,r)!=SSL_ERROR_NONE || r!=strlen(request)) {
return -1;
}
int pos=0;
memset(buffer,0,4096);
while(1) {
r=SSL_read(ssl,buffer+pos,4095-pos);
switch(SSL_get_error(ssl,r)) {
case SSL_ERROR_NONE:
break;
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
goto endread;
default:
return -1;
}
pos+=r;
}
endread:
SSL_CTX_free(ctx);
#ifdef WIN32
WSACleanup();
#endif
format(buffer,(char*)info);
wxString wxInfo=wxString::Format(wxT("%s"),info);
wxMessageBox(wxInfo,wxT("Message"));
return 0;
}
class wxPKUIPGW : public wxApp
{
public:
virtual bool OnInit();
};
DECLARE_APP(wxPKUIPGW);
IMPLEMENT_APP(wxPKUIPGW);
class wxMainFrame: public wxFrame
{
public:
void OnOK(wxCommandEvent& event);
void OnCancel(wxCommandEvent& event);
wxMainFrame();
private:
wxTextCtrl *m_user,*m_passwd;
wxCheckBox *m_check;
wxRadioButton *rb8h,*rb20m;
wxRadioButton *rbcon, *rbdiscon, *rbconnect;
wxButton *ok,*cancel;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(wxMainFrame,wxFrame)
EVT_BUTTON(wxID_CANCEL,wxMainFrame::OnCancel)
EVT_BUTTON(wxID_OK,wxMainFrame::OnOK)
END_EVENT_TABLE()
bool wxPKUIPGW::OnInit()
{
wxMainFrame *frame = new wxMainFrame;
frame->Show(true);
SetTopWindow(frame);
return true;
}
wxMainFrame::wxMainFrame()
: wxFrame((wxFrame *) NULL, wxID_ANY, _T("wxPKUIPGW"),wxPoint(500,300), wxSize(200,250),wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU|wxCAPTION|wxRAISED_BORDER)
{
wxPanel *panel = new wxPanel(this);
(void)new wxStaticText(panel, wxID_ANY, _T("用户名"),wxPoint(10, 10), wxSize(50, 20));
m_user = new wxTextCtrl(panel, wxID_ANY, _T(""), wxPoint(60, 10), wxSize(100, 20));
(void)new wxStaticText(panel, wxID_ANY, _T("密码"),wxPoint(10, 40), wxSize(50, 20));
m_passwd = new wxTextCtrl(panel, wxID_ANY, _T(""), wxPoint(60, 40), wxSize(100, 20),wxTE_PASSWORD);
rb8h=new wxRadioButton(panel,wxID_ANY,wxT("8小时"),wxPoint(30, 75), wxSize(50, 20), wxRB_GROUP);
rb20m=new wxRadioButton(panel,wxID_ANY,wxT("20分钟"),wxPoint(90,75), wxSize(60, 20));
rbcon=new wxRadioButton(panel,wxID_ANY,wxT("连接"),wxPoint(10, 100), wxSize(50, 20), wxRB_GROUP);
rbdiscon=new wxRadioButton(panel,wxID_ANY,wxT("断开"),wxPoint(60,100), wxSize(50, 20));
rbconnect=new wxRadioButton(panel,wxID_ANY,wxT("断开并连接"),wxPoint(110,100), wxSize(80,20));
rbconnect->SetValue(true);
m_check = new wxCheckBox(panel, wxID_ANY, _T("保存密码"),wxPoint(10,130), wxSize(300, 20));
ok=new wxButton(panel,wxID_OK,wxT("确定"),wxPoint(20,160));
cancel=new wxButton(panel,wxID_CANCEL,wxT("取消"),wxPoint(100,160));
//检查是否存在已保存的信息
ifstream info;
info.open("PKUIPGWrc",ios::in);
if(info) {
op_t op;
info.read(reinterpret_cast<char*>(&op),sizeof(op));
wxString wxUser=wxString::Format(wxT("%s"),op.usr);
wxString wxPasswd=wxString::Format(wxT("%s"),op.passwd);
m_user->SetValue(wxUser);
m_passwd->SetValue(wxPasswd);
m_check->SetValue(true);
info.close();
}
}
void wxMainFrame::OnCancel(wxCommandEvent & event)
{
Close(true);
}
void wxMainFrame::OnOK(wxCommandEvent & event)
{
op_t op;
wxString user=m_user->GetValue();
wxString passwd=m_passwd->GetValue();
int len,i;
len=user.length();
if(len>=UPLEN)
len=UPLEN-1;
for(i=0;i<len;i++)
op.usr[i]=user[i];
op.usr[i]=0;
len=passwd.length();
if(len>=UPLEN)
len=UPLEN-1;
for(i=0;i<len;i++)
op.passwd[i]=passwd[i];
op.passwd[i]=0;
//检查是否选择保存密码
if(m_check->GetValue()) {
ofstream info;
info.open("PKUIPGWrc",ios::binary|ios::out);
if(!info) {
}
else {
info.write(reinterpret_cast<const char*>(&op),sizeof(op));
info.close();
}
}
else {
unlink("PKUIPGWrc");
}
//获得超时时间
if(rb8h->GetValue())
op.timeout=1;
else
op.timeout=0;
//范围
op.range=2;
//操作
if(rbcon->GetValue()) {
sprintf(op.op,"connect");
ipgw_operation(&op);
}
else if(rbdiscon->GetValue()) {
sprintf(op.op,"disconnectall");
ipgw_operation(&op);
}
else {
sprintf(op.op,"disconnectall");
ipgw_operation(&op);
sprintf(op.op,"connect");
ipgw_operation(&op);
}
}
|