📄 mystar.c
字号:
/* Mystar is an 802.1x client tool for Linux, which is compatible with MentoSupplicant3.8 for Windows. This file contains the main() function of mystar.*/#include "mystar.h"#include "global.h"#include "sendpacket.h"#include "myerr.h"#include "blog.h"#include "conn_monitor.h"/* Note that: in this file, the global variables (defined without a leading "static") from here to the beginning of the definition of main() are referenced by sendpacket.c ( we reference them in the form of "extern ..." in sendpacket.c) *//* These info should be retrieved from mystar.conf */char *m_name=NULL;//用户名char *m_password=NULL;//密码int m_authenticationMode=-1; //是哪种认证模式:0:标准 1:实达static char *m_nic=NULL;//网卡static int m_echoInterval= -1; //echo间隔, set to 0 to disable echostatic int m_intelligentReconnect=-1; // 0:don't use it, 1: ues it. NOTE: not supported NOW!!static char *m_fakeAddress=NULL; // or set to "123.45.67.89" etc./* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */static char *m_intelligentHost=NULL;static unsigned int m_DbgInfoLevel = 0;/* +++++++++++++++++++++++++++++++++++++++++++++++ By 夕霞孤雁 05.10.20 *//* These information should be worked out by initialization portion. */unsigned char m_localMAC[6];//本机的MAC地址unsigned char m_destMAC[6];//服务器的MAC地址.static unsigned char m_ip[4]; //当前选择的网卡的IP地址static unsigned char m_netmask[4];//当前选择的网卡的子网掩码static unsigned char m_netgate[4];//当前选择的网卡的网关static unsigned char m_dns1[4]; //当前选择的网卡的DNS/* 当前认证状态 0:未找到服务器 1:已找到服务器,未通过用户名认证 2:已通过用户名认证,未通过MD5认证 3:已通过MD5认证,通网成功 */static volatile sig_atomic_t m_state=0;//当前认证状态ULONG_BYTEARRAY m_serialNo; //序列号,收到第一个有效的Authentication-Success-packet时初始化ULONG_BYTEARRAY m_key; //密码加密键值,在main()函数开始时初始化/////////////////////////////////////////////////////////////////////////static void sig_intr(int signo); //do some cleanup work on exit with Ctrl+Cstatic void checkAndSetConfig(void); //configure related parametersint main(int argc, char* argv[]){ libnet_t * l=NULL; u_int32_t l_ip; char l_errbuf[LIBNET_ERRBUF_SIZE]; struct libnet_ether_addr *l_ether_addr; pcap_t *p=NULL; int p_fd; fd_set read_set; char filter_buf[256]; struct bpf_program filter_code; u_int32_t p_netaddr,p_netmask; struct pcap_pkthdr *pkt_hdr; const u_char *pkt_data; char p_errbuf[PCAP_ERRBUF_SIZE]; u_int16_t offset; int msgLen; char msgBuf[256]; char *pmsgBuf; ULONG_BYTEARRAY uTemp; int isFirstPacketFromServer=1; sigset_t sigset_full,sigset_zero; struct timespec timeout; int packetCount_SentFindServer=0; int packetCount_SentName=0; int packetCount_SentPassword=0; m_serialNo.ulValue = 0x1000002a; //the initial serial number, a magic number! Used to generate the Magic Numbers checkAndSetConfig(); //Set the arguments if((l=libnet_init(LIBNET_LINK, m_nic,l_errbuf))==NULL) err_quit("libnet_init: %s\n", l_errbuf); if((p=pcap_open_live(m_nic,65536,0, 500, p_errbuf))==NULL) //Get the libpcap handle { err_msg("pcap_open_live: %s\n",p_errbuf); goto err1; } p_fd=pcap_fileno(p); //we can pselect() it in the following code. //Get the Libpcap File Descriptor,Used by pselect() function //Get the Local Mac Address if((l_ether_addr=libnet_get_hwaddr(l))==NULL) { err_msg("unable to get local mac address :%s\n",libnet_geterror(l)); goto err2; }; memcpy(m_localMAC,l_ether_addr,sizeof(m_localMAC)); //Get the ip address if(m_fakeAddress==NULL) { if((l_ip=libnet_get_ipaddr4(l))==-1) { err_msg("unable to get ip address--ingored... :%s\n",libnet_geterror(l)); l_ip=0; } memcpy(m_ip,&l_ip,sizeof(m_ip)); } else {}; //in this case , m_ip has been initialized in checkandSetConfig() //Get the netmask if(pcap_lookupnet(m_nic,&p_netaddr,&p_netmask,p_errbuf)==-1) { err_msg("unable to get netmask--igored... %s\n",p_errbuf); p_netmask=0;} memcpy(m_netmask,&p_netmask,sizeof(m_netmask)); InitializeBlog(m_ip,m_netmask,m_netgate,m_dns1); //see blog.c and bloc.h for details //set the filter. Here I'm sure filter_buf is big enough. snprintf(filter_buf,sizeof(filter_buf),FILTER_STR, m_localMAC[0],m_localMAC[1], m_localMAC[2],m_localMAC[3],m_localMAC[4],m_localMAC[5]); // m_localMAC[2],m_localMAC[3],m_localMAC[4],m_localMAC[5],m_localMAC[6]); if(pcap_compile(p, &filter_code,filter_buf, 0, p_netmask)==-1) { err_msg("pcap_compile(): %s", pcap_geterr(p)); goto err2; } if(pcap_setfilter(p, &filter_code)==-1) { err_msg("pcap_setfilter(): %s", pcap_geterr(p)); goto err2; } pcap_freecode(&filter_code); // avoid memory-leak (void)signal(SIGINT,sig_intr); //We can exit with Ctrl+C (void)sigfillset(&sigset_full); (void)sigprocmask(SIG_BLOCK,&sigset_full,NULL); //block all signals. //search for the serverbeginAuthentication: m_state=0; (void)SendFindServerPacket(l); //the first time to search for server packetCount_SentFindServer=1; packetCount_SentName=0; packetCount_SentPassword=0; while(1) { (void)sigfillset(&sigset_full); (void)sigdelset(&sigset_full,SIGINT); FD_ZERO(&read_set); FD_SET(p_fd, &read_set); timeout.tv_sec =1; timeout.tv_nsec =0; // 1 second //wait with all signals(except SIGINT) blocked. switch ( pselect(p_fd+1,&read_set,NULL,NULL,&timeout,&sigset_full) ) { case -1: //Normally, this case should not happen since sig_intr() never returns! goto err2; case 0: //timed out switch(m_state) { case 0: if(++packetCount_SentFindServer>3) { puts("Restarting authenticaton!"); goto beginAuthentication; } (void)SendFindServerPacket(l); continue; //jump to next loop of while(1) to receive next packet case 1: if(++packetCount_SentName>3) { puts("Restarting authenticaton!"); goto beginAuthentication; } (void)SendNamePacket(l, pkt_data); continue; case 2: if(++packetCount_SentPassword>3) { puts("Restarting authenticaton!"); goto beginAuthentication; } (void)SendPasswordPacket(l, pkt_data); continue; default: goto err2; } } //Here return value of pselect must be 1 if((pcap_next_ex(p,&pkt_hdr,&pkt_data))!=1) continue; //收到的第二个及其以后的有效packet的源MAC必须等于头次收到的有效分组的源MAC if ((!isFirstPacketFromServer)&&(memcmp(m_destMAC,pkt_data+6,6)!=0)) continue; //received a packet successfully. for convenience, SUPPOSE it's the RIGHT packet!! but maybe WRONG!! //for example, we have NEVER vefified the length of packet, fancying the packet's length is 0x11 ?! switch( pkt_data[0x12] ) //分析EAP包类型 { case 0x01: //表示请求 switch( pkt_data[0x16] ) { case 0x01: //type 1,以用户名应答 if(m_state!=0) continue; m_state=1; fputs("@@ Server found, requesting user name...\n",stdout); if (isFirstPacketFromServer) //获得服务器的MAC地址 { memcpy( m_destMAC, pkt_data+6, 6); isFirstPacketFromServer=0;} ++packetCount_SentName; (void)SendNamePacket(l, pkt_data); break; case 0x04: //type 4,挑战,以MD5计算得到的值应答 if(m_state!=1) continue; m_state=2; fputs("@@ User name valid, requesting password...\n",stdout); ++packetCount_SentPassword; (void)SendPasswordPacket(l, pkt_data); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -