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

校园网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;
}
//md5
int 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,0x00,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 eap
int 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;
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/28187.html