校园网802.1X的Linux联网客户端(1.3_20090815)

校园网802.1X的Linux联网客户端是Linuxidc转载自天空得博文,自己也看不懂,只为以后学习之用做摘记。

#include<sys/types.h>#include<stdlib.h>#include<stdio.h>#include<stdint.h>#include<string.h>#include<unistd.h>#include<sys/socket.h>#include<linux/if.h>#include<linux/if_ether.h>#include<linux/sockios.h>#include<netdb.h>#include<arpa/inet.h>#include<pcap.h>#include<signal.h>#include<fcntl.h>#include<time.h>//#include<ncurses.h>//注意此头文件位置#include<termios.h>#include”md5.c”#define Eap_Pack_Len 67#define EAP_REQUEST_LEN 60#define EAP_PWD_ERR_LEN 146#define EAP_NAME_ERR_LEN 63#define USER_NAME_LEN 40#define USER_PWD_LEN 50//#define EAP_MAC_ERR_LEN

const char *lock_file=”/tmp/802.1x_EAP_Client_lock-file_DW”;//锁文件u_char mac_client[6],base[32],EAP_Pack[Eap_Pack_Len];char user_name[USER_NAME_LEN],user_pwd[USER_PWD_LEN];//EAP_Pack为要发送给服务噐的数据u_char mac_server[6]={0x01,0x80,0xc2,0x00,0x00,0x03};struct pcap_pkthdr *header;u_char *pkt_data;unsigned int ID;struct termios old_set;const char *version=”Version:1.3_20090815″;const char VERSION_802_1X[16]=”CH V2.40-F0316″;const char KEY[]=”HuaWei3COM1X”;struct ifreq req;char network_name[30];pcap_t *fp;struct sigaction act;int sockfd;int file_desc,flag_sig_pro=1;int get_user_name(){ int j=0; char swap; printf(“input name:”); fflush(stdout); while((swap=user_name[j]=getchar())!=’\n’&&j<USER_NAME_LEN-1) j++; while(swap!=’\n’) swap=getchar(); if(j==0) return 1; user_name[j]=’\0′; return 0;}int get_user_pwd(){ int j=0; char swap; printf(“input password:”); fflush(stdout); while((swap=user_pwd[j]=getchar())!=’\n’&&j<USER_PWD_LEN-1) j++; while(swap!=’\n’) swap=getchar(); if(j==0) return 1; user_pwd[j]=’\0′; return 0;}int get_mac_client(){ sockfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(sockfd<0) return 1; if(-1==ioctl(sockfd,SIOCGIFHWADDR,&req)) { close(sockfd); return 1; } memcpy(mac_client,req.ifr_hwaddr.sa_data,6); //close(sockfd); return 0;}//md5int get_md5_digest(u_char EAP_Pack[],const char *str,unsigned int len)//对字符串进行16位md5加密{ md5_state_t state; md5_byte_t digest[16]; md5_init(&state); md5_append(&state,(const md5_byte_t *)str,len); md5_finish(&state,digest); memcpy(EAP_Pack,digest,16); return 0;}int Fill_Eapol_Start(u_char EAP_Pack[]){ EAP_Pack[15]=0x01; return 0;}int Fill_EAP_Name(u_char EAP_Pack[]){ EAP_Pack[15]=0x00;EAP_Pack[16]=0x00;EAP_Pack[17]=0x15;EAP_Pack[18]=0x02; EAP_Pack[19]=ID;EAP_Pack[20]=0x00;EAP_Pack[21]=0x15;EAP_Pack[22]=0x01; EAP_Pack[23]=0x15;EAP_Pack[24]=0x04; memset(EAP_Pack+25,0×00,Eap_Pack_Len-25); memcpy(EAP_Pack+29,user_name,strlen(user_name)); return 0;}int Fill_Eap_PWD(u_char EAP_Pack[],u_char pkt_data[]){ int pwdlen=strlen(user_pwd); u_char *pwdstring=(u_char *)malloc(1+pwdlen+16); pwdstring[0]=*(pkt_data+0x13); memcpy(pwdstring+1,user_pwd,pwdlen); memcpy(pwdstring+1+pwdlen,pkt_data+0x18,16); get_md5_digest(EAP_Pack+24,pwdstring,1+pwdlen+16); EAP_Pack[15]=0x00;EAP_Pack[16]=0x00;EAP_Pack[17]=0x20;EAP_Pack[18]=0x02; EAP_Pack[19]=ID;EAP_Pack[20]=0x00;EAP_Pack[21]=0x20;EAP_Pack[22]=0x04; EAP_Pack[23]=0x10; memcpy(EAP_Pack+40,user_name,strlen(user_name)); free(pwdstring); return 0;}void XOR(uint8_t data[], unsigned dlen, const char key[], unsigned klen){ unsigned int i,j; //先按正序处理一遍// for (i=0; i<dlen; i++) data[i] ^= key[i%klen]; // 再按倒序处理第二遍 for (i=dlen-1,j=0; j<dlen; i–,j++) data[i] ^= key[j%klen];}int Fill_Client_Version(int i){ uint32_t random; char RandomKey[8+1]; random = (uint32_t) time(NULL); // 注:可以选任意32位整数 sprintf(RandomKey, “%08x”, random);// 生成RandomKey[]字符串第一轮异或运算,以RandomKey为密钥加密16字节 memcpy(EAP_Pack+i, VERSION_802_1X, sizeof(VERSION_802_1X)); XOR(EAP_Pack+i, 16, RandomKey, strlen(RandomKey)); // 此16字节加上4字节的random,组成总计20字节 random = htonl(random); // (需调整为网络字节序) memcpy(EAP_Pack+i+16, &random, 4); // 第二轮异或运算,,以KEY为密钥加密前面生成的20字节 XOR(EAP_Pack+i, 20, KEY, strlen(KEY)); return 0;}int Fill_EAP_Notification(){ EAP_Pack[15]=0x00;EAP_Pack[16]=0x00;EAP_Pack[17]=0x31;EAP_Pack[18]=0x02; EAP_Pack[19]=ID;EAP_Pack[20]=0x00;EAP_Pack[21]=0x31;EAP_Pack[22]=0x02; EAP_Pack[23]=0x01;EAP_Pack[24]=0x16; Fill_Client_Version(25); EAP_Pack[45]=0x02;EAP_Pack[46]=0x16;EAP_Pack[47]=0x3a;EAP_Pack[48]=0x71; EAP_Pack[49]=0x38;EAP_Pack[50]=0x01;EAP_Pack[51]=0x0b;EAP_Pack[52]=0x3b; EAP_Pack[53]=0x7e;EAP_Pack[54]=0x3d;EAP_Pack[55]=0x26;EAP_Pack[56]=0x7c; EAP_Pack[57]=0x7c;EAP_Pack[58]=0x17;EAP_Pack[59]=0x0b;EAP_Pack[60]=0x46; EAP_Pack[61]=0x08;EAP_Pack[62]=0x32;EAP_Pack[63]=0x32;EAP_Pack[64]=0x08; EAP_Pack[65]=0x46;EAP_Pack[66]=0x0b; return 0;}int Fill_EAP_After_Suc(){ char ip[20]; int swap=0,k=0,j=0,len; EAP_Pack[19]=ID; ioctl(sockfd,SIOCGIFADDR,&req); sprintf(ip,”%s”,inet_ntoa(((struct sockaddr_in *)&req.ifr_ifru.ifru_addr)->sin_addr)); len=strlen(ip); for(j=0;j<len;j++) { if(‘.’==ip[j]) { EAP_Pack[25+k]=swap; swap=0; k++; continue; } swap=swap*10+ip[j]-‘0’; } EAP_Pack[28]=swap; return 0;}int Send_Eapol_Logoff(){ EAP_Pack[15]=0x02; memset(EAP_Pack+16,0,44); if(pcap_sendpacket(fp,EAP_Pack,60) != 0) return 1; return 0;}int Send_Eapol_Start(pcap_t *fp,u_char EAP_Pack[]){ Fill_Eapol_Start(EAP_Pack); if(pcap_sendpacket(fp,EAP_Pack,60) != 0) return 1; return 0;}int Send_Eap_Name(pcap_t *fp,u_char EAP_Pack[]){ Fill_EAP_Name(EAP_Pack); if(pcap_sendpacket(fp,EAP_Pack,60) != 0) return 1; return 0;}int Send_Eap_PWD(pcap_t *fp,u_char EAP_Pack[],u_char pkt_data[]){ Fill_Eap_PWD(EAP_Pack,pkt_data); if(pcap_sendpacket(fp,EAP_Pack,60)!=0) return 1; return 0;}int Send_Eap_Noti(pcap_t *fp,u_char Eap_Pack[]){ Fill_EAP_Notification(); if(pcap_sendpacket(fp,EAP_Pack,Eap_Pack_Len)!=0) return 1; return 0;}//compare to request eapint EAP_CMP_NOTI(u_char pkt_data[]){ int j; base[15]=0x00;base[16]=0x00;base[17]=0x05;base[18]=0x01; ID=base[19]=pkt_data[19];base[20]=0x00;base[21]=0x05;base[22]=0x02; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; for(j=12;j<23;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_MAC_Error(u_char pkt_data[]){ int j; //base[16]=pkt_data[16];base[17]=pkt_data[17];base[18]=0x04;base[19]=pkt_data[19];base[20]=pkt_data[20]; //base[21]=pkt_data[21];base[22]=pkt_data[22];base[23]=pkt_data[23]; base[24]=0x45;base[25]=0x32; base[26]=0x35;base[27]=0x34;base[28]=0x35;base[29]=0x3a; base[30]=0x20;base[31]=0x4d; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; //for(j=12;j<32;j++) // if(base[j]=pkt_data[j]) // return 1; for(j=24;j<32;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_Name(u_char pkt_data[]){ int j; base[17]=0x05;base[18]=0x01; ID=pkt_data[19];base[20]=0x00;base[21]=0x05;base[22]=0x01; //for(j=23;j<64;j++) // base[j]=0x00; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; for(j=12;j<23;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_PWD(u_char pkt_data[]){ int j; base[17]=0x16;base[18]=0x01;ID=base[19]=pkt_data[19]; base[20]=0x00;base[21]=0x16;base[22]=0x04;base[23]=0x10; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; for(j=12;j<18;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_Success(u_char pkt_data[]){ int j; base[17]=0x04;base[18]=0x03; //for(j=22;j<64;j++) // base[j]=0xa5; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; for(j=12;j<19;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_Name_Error(u_char pkt_data[]){ int j; base[17]=0x2d;base[18]=0x04;base[19]=pkt_data[19]; base[20]=pkt_data[20];base[21]=pkt_data[21];base[22]=pkt_data[22];base[23]=pkt_data[23];base[24]=0x45; base[25]=0x32;base[26]=0x35;base[27]=0x33;base[28]=0x31; base[29]=0x3a;base[30]=0x20;base[31]=0xd3;//base[31]=0xc3; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; //for(j=12;j<16;j++) // if(base[j]!=pkt_data[j]) // return 1; if(base[18]!=0x04) return 1; for(j=24;j<32;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_PWD_Error(u_char pkt_data[]){ int j; //base[17]=pkt_data[17];base[18]=0x04;base[19]=pkt_data[19]; //base[20]=pkt_data[20];base[21]=pkt_data[21];base[22]=pkt_data[22];base[23]=pkt_data[23]; base[24]=0x45; base[25]=0x32;base[26]=0x35;base[27]=0x35;base[28]=0x33; base[29]=0x3a;base[30]=0x20;base[31]=0xd3;//base[31]=0xc3; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; for(j=12;j<16;j++) if(base[j]!=pkt_data[j]) return 1; if(pkt_data[18]!=0x04) return 1; for(j=24;j<32;j++) if(base[j]!=pkt_data[j]) return 1; return 0;}int EAP_CMP_ERR(u_char pkt_data[]){ int j; for(j=0;j<6;j++) if(base[j]!=pkt_data[j]) return 1; for(j=12;j<16;j++) if(base[j]!=pkt_data[j]) return 1; if(pkt_data[18]!=0x04) return 1; return 0;}

void shut_reb_signal_pro(int sig)//后台进程的重启、关机信号处理{ flag_sig_pro=0; close(sockfd); (void)unlink(lock_file); Send_Eapol_Logoff(); (void)close(file_desc); pcap_close(fp); return;}void free_lock_file(){ (void)close(file_desc); (void)unlink(lock_file); if(tcsetattr(fileno(stdin),TCSANOW,&old_set)) printf(“restore terminal’s mode failed!\n”);}int main(int argc, char *argv[]){ int flag,flag_fail=1; pcap_if_t *alldevs,*d; char c,c1; int j=0,OvertimeCount=0,sendcount=1; char errbuf[PCAP_ERRBUF_SIZE]; char shell[100]={“/sbin/ifconfig “}; int rtrnval; pid_t pid; struct termios new_set; tcgetattr(fileno(stdin),&old_set); new_set=old_set; new_set.c_lflag&=~ISIG; //system(“clear;history -c;exit 0”); if(tcsetattr(fileno(stdin),TCSANOW,&new_set)) { printf(“set terminal’s mode failed!\n”); return 1; } new_set.c_lflag&=~ECHO; act.sa_handler=shut_reb_signal_pro; sigemptyset(&act.sa_mask); act.sa_flags=0; file_desc=open(lock_file,O_RDWR|O_CREAT|O_EXCL,0444);//建立锁文件 if(file_desc==-1) { printf(“%s_Lock already present\n”,argv[0]); printf(“If running %s is the first time after starting the PC,or you once ended it by closing the terminal,please remove %s!\nElse may you are running %s.\n”,argv[0],lock_file,argv[0]); return 1; } printf(“\nAttention:\n\nif the twisted-pair is pulled out of network_card,this programme may will hold on.If so, you will have to close this terminal to end it!\n\nPress ENTER to continue……\n”); c1=getchar(); while(c1!=’\n’) c1=getchar(); memset(EAP_Pack,0X00,Eap_Pack_Len); j=0; if(pcap_findalldevs(&alldevs,errbuf)==0) { d=alldevs; if(!alldevs) { printf(“try \”sudo %s \”\n”,argv[0]); free_lock_file(); return 1; } while(get_user_name()); //noecho(); if(tcsetattr(fileno(stdin),TCSAFLUSH,&new_set)) { printf(“set terminal’s mode failed!\n”); free_lock_file(); return 1; } while(get_user_pwd()); new_set.c_lflag|=ECHO; if(tcsetattr(fileno(stdin),TCSANOW,&new_set)) { printf(“set terminal’s mode failed!\n”); free_lock_file(); return 1; } //echo(); printf(“\n\n”); for(;d;d=d->next) { j++; printf(“%d:network_card_%d’s name:%s\n”,j,j,d->name); //if(d->description) // printf(“device %d’s description:%s\n”,j,d->description); // else // printf(“No description available for device %d.\n”,j); } printf(“Enter the interface number:\n”); scanf(“%c”,&c); c1=c; while(c1!=’\n’) c1=getchar(); c=c-‘0’; if(c>j||c<1) { printf(“out of range!\n”); pcap_freealldevs(alldevs); free_lock_file(); return 1; } d=alldevs; for(j=1;j<c;j++,d=d->next); } else { printf(“not found network_card!\n”); free_lock_file(); return 1; } strcpy(req.ifr_name,d->name); if(get_mac_client()) { printf(“got network_card’s mac error!\n”); pcap_freealldevs(alldevs); free_lock_file(); return 1; } // Open the adapter if((fp=pcap_open_live(d->name,150,1,200,errbuf))==NULL) { printf(“Unable to open the adapter. %s is not supported by WinPcap\n”,d->name); pcap_freealldevs(alldevs); free_lock_file(); return 1; } strcat(shell,d->name); strcat(shell,” down;/sbin/ifconfig “); strcat(shell,d->name); strcat(shell,” up;exit 0″); pcap_freealldevs(alldevs); memcpy(EAP_Pack,mac_server,6); memcpy(EAP_Pack+6,mac_client,6); //strcpy(user_name,argv[1]); EAP_Pack[12]=0x88;EAP_Pack[13]=0x8e;EAP_Pack[14]=0x01; memcpy(base,mac_client,6); base[12]=0x88;base[13]=0x8e;base[14]=0x01;base[15]=0x00;base[16]=0x00; if(!Send_Eapol_Start(fp,EAP_Pack)) printf(“start logging on!\n”); else { printf(“start logging on error!\n”); pcap_close(fp); free_lock_file(); return 1; } j=1; while(j) { flag=0; if(OvertimeCount>10)//超时次数 { printf(“OvertimeCount>10!Please check PC’s network_card!\n”); break; } rtrnval=pcap_next_ex(fp,&header,(const u_char **)&pkt_data); if(rtrnval) { j++; if(EAP_REQUEST_LEN==header->len||EAP_PWD_ERR_LEN==header->len||EAP_NAME_ERR_LEN==header->len) { if(!EAP_CMP_Name_Error(pkt_data)) { printf(“name does’n exist or is wrong!\n”); break; } if(!EAP_CMP_PWD_Error(pkt_data)) { printf(“password is wrong!check your password!\n”); break; } if(!EAP_CMP_MAC_Error(pkt_data)) { printf(“MAC error!Did you change your network_card?\n”); break; } if(!EAP_CMP_NOTI(pkt_data)) { flag=1; j=1; if(Send_Eap_Noti(fp,EAP_Pack)) { printf(“sent Eap_Notification_Packet error!\n”); break; } printf(“sent eap_notification packet successfully!\n”); continue; } if(!EAP_CMP_Name(pkt_data)) { flag=1; j=1; if(Send_Eap_Name(fp,EAP_Pack)) { printf(“sent Eap_Name_Packet error!\n”); break; } printf(“sent eap_name_packet successfully!\n”); continue; } if(!EAP_CMP_PWD(pkt_data)) { flag=1; j=1; if(Send_Eap_PWD(fp,EAP_Pack,pkt_data)) { printf(“sent Eap_PWD_Packet error!\n”); break; } printf(“sent eap_pwd_packet successfully!\n”); continue; } if(!EAP_CMP_Success(pkt_data)) { flag_fail=0; printf(“Logged on successfully!\n”); system((const char *)shell);//执行shell获取IP printf(“\nIF failed to automatically get IP,please manually operate to get IP.\n”); printf(“for example:\n”); printf(” run the following commands in terminal:\n\tsudo ifdown <network_card’s name> \n”); printf(“\tsudo ifup <network_card’s name>\n”); printf(“\n\t\t–good luck!\n”); printf(“\t\t%s by DW\n”,version); break; } if(!EAP_CMP_ERR(pkt_data)) { printf(“receive log-off packet!Please check your name,password and network_card!\n”); break; } } } else if(rtrnval==0) { OvertimeCount++; printf(“received package over time!\n”); if(OvertimeCount%2==0) { if(!Send_Eapol_Start(fp,EAP_Pack)) printf(“Restart logging on!\n”); else { printf(“restart logging on error!\n”); break; } } continue; } else { printf(“received package error!will exit!\n”); break; } if(flag==0&&j%50==0)//如果连续50个数据包都不是认证所需的,重新发起认证 { if(!Send_Eapol_Start(fp,EAP_Pack)) { printf(“Restart logging on!\n”); sendcount++; continue; } else { printf(“Restart logging on error!\n”); break; } } if(sendcount>5)//重新发起认证次数 { printf(“logged on failed!\n”); break; }}if(flag_fail){ close(sockfd); pcap_close(fp); free_lock_file(); printf(“exit……\n”);}else//进入后台处理{ free_lock_file(); if((pid=fork())>0) exit(0); else if(pid<0) { pcap_close(fp); exit(1); } file_desc=open(lock_file,O_RDWR|O_CREAT|O_EXCL,0444); if(file_desc==-1) return 1; setsid(); chdir(“/”); umask(0); sigaction(SIGTERM,&act,0); //处理认证成功后服务器持续发送确认包的情况 sockfd=socket(AF_INET,SOCK_STREAM,0);//用来获取指定网卡IP Fill_EAP_Name(EAP_Pack); base[15]=0x00;base[16]=0x00;base[17]=0x05;base[18]=0x01; base[20]=0x00;base[21]=0x05;base[22]=0x01; while(flag_sig_pro) { rtrnval=pcap_next_ex(fp,&header,(const u_char **)&pkt_data); if(rtrnval&&EAP_REQUEST_LEN==header->len) { ID=base[19]=pkt_data[19]; if(!strncmp(base,pkt_data,22)) { Fill_EAP_After_Suc(); if(pcap_sendpacket(fp,EAP_Pack,60)) shut_reb_signal_pro(-1); } } } //pause();}return 0;}//end

那么威尼斯就是一艘轻盈和流动的舟船,

校园网802.1X的Linux联网客户端(1.3_20090815)

相关文章:

你感兴趣的文章:

标签云: