折腾锐捷开机自动启动认证 » 荒野无灯weblog

Keep It Simple, Stupid.

荒野无灯weblog

折腾锐捷开机自动启动认证

学校用的是锐捷 802.1x 认证,其客户端支持开机自动启动、启动软件后自动认证。
由于我这里需要的是客户端在桌面用户没有登录系统之前就启动认证,使机器具有访问外部网络的功能。因此靠软件本身应该行不通。
想到WINDOWS系统的服务是在用户登录之前可以加载启动的,因此这里主要是把锐捷注册为服务来实现开机即认证。

首先,在锐捷客户端里设置“启动软件后自动认证”,“保存密码”等。
然后,用VC写个东东,作为服务,由它来创建锐捷认证的进程。就把生成后的程序命名为ruijie_service.exe 吧。
代码如下:
C:\\Program Files\\锐捷网络\\Ruijie Supplicant\\8021x.exe“为锐捷认证客户端的程序路径。

//////////////////////////////////////////////////////////////////////////////////////
//程序原作者:冷风
//修改:荒野无灯                                                               //
//////////////////////////////////////////////////////////////////////////////////////

#include 
#include 
#include 
#include 
#include 

SERVICE_STATUS          ServiceStatus;
SERVICE_STATUS_HANDLE   hStatus;

VOID    WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
VOID    WINAPI ServiceHandler( DWORD fdwControl );
DWORD   WINAPI mainfun(LPVOID lpParam);

int main(int argc,char *argv[])
{
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "8021x";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    StartServiceCtrlDispatcher(ServiceTable);     // 启动服务的控制分派机线程
    return 0;
}

VOID WINAPI ServiceHandler(DWORD fdwControl) 
{ 
    switch(fdwControl)
    {
    case SERVICE_CONTROL_PAUSE:
        ServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;

    case SERVICE_CONTROL_CONTINUE:
        ServiceStatus.dwCurrentState = SERVICE_RUNNING;
        break;

    case SERVICE_CONTROL_STOP: 
    case SERVICE_CONTROL_SHUTDOWN:
        ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
        ServiceStatus.dwWin32ExitCode = 0;
        ServiceStatus.dwCheckPoint    = 0;
        ServiceStatus.dwWaitHint      = 0;
        SetServiceStatus(hStatus,&ServiceStatus);
        return ;

    case SERVICE_CONTROL_INTERROGATE:
        break;

    default:
        break;
    }

    SetServiceStatus(hStatus,&ServiceStatus);
    return ;
}

VOID WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv )
{
    DWORD   status = 0; 
    DWORD   specificError = 0xfffffff; 

    ServiceStatus.dwServiceType        = SERVICE_WIN32; 
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; 
    ServiceStatus.dwWin32ExitCode      = 0; 
    ServiceStatus.dwServiceSpecificExitCode = 0; 
    ServiceStatus.dwCheckPoint         = 0; 
    ServiceStatus.dwWaitHint           = 0; 

    hStatus = RegisterServiceCtrlHandler("8021x",(LPHANDLER_FUNCTION)ServiceHandler); 
    if (hStatus==0) 
        return; 

    // Handle error condition 
    status = GetLastError(); 
    if (status!=NO_ERROR) 
    { 
        ServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
        ServiceStatus.dwCheckPoint         = 0; 
        ServiceStatus.dwWaitHint           = 0; 
        ServiceStatus.dwWin32ExitCode      = status; 
        ServiceStatus.dwServiceSpecificExitCode = specificError; 
        SetServiceStatus(hStatus, &ServiceStatus); 
        return; 
    } 

    // Initialization complete - report running status 
    ServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
    ServiceStatus.dwCheckPoint         = 0; 
    ServiceStatus.dwWaitHint           = 0;  
    SetServiceStatus(hStatus, &ServiceStatus);

  //do my job
   HANDLE hThread=CreateThread(NULL,0,mainfun,NULL,0,NULL);
   if(hThread==NULL)
       return;
    WaitForSingleObject(hThread,INFINITE);
}

DWORD WINAPI mainfun(LPVOID lpParam)
{

    STARTUPINFO          lpStartupInfo;
    PROCESS_INFORMATION  lpProcessInfo;

    int ret;

    GetStartupInfo(&lpStartupInfo);
    lpStartupInfo.cb           = sizeof(lpStartupInfo);
    lpStartupInfo.dwFlags      = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    lpStartupInfo.wShowWindow  = SW_HIDE;
    lpStartupInfo.lpDesktop = "WinSta0\\Default"; 
    //lpStartupInfo.lpDesktop = "NewDesktop"; 

    char cmdline[MAX_PATH];
/*  char path[MAX_PATH];
    ::GetCurrentDirectory(100,path);
    strcat(path,"\\config.txt");
    FILE *fp;
    fp=fopen(path,"r");
    if(( fp=fopen(path,"r") ) !=NULL )
    {
    fread(path,MAX_PATH,1,fp);
    fclose(fp);
    strcpy(cmdline,path);
    ret = CreateProcess(cmdline, NULL, NULL,NULL,TRUE,0,NULL,NULL,&lpStartupInfo,&lpProcessInfo);
    }
*/
    strcpy(cmdline,"C:\\Program Files\\锐捷网络\\Ruijie Supplicant\\8021x.exe");
    ret = CreateProcess(cmdline, NULL, NULL,NULL,TRUE,0,NULL,NULL,&lpStartupInfo,&lpProcessInfo);
    return 0;
}

把生成的程序置于:D:\ruijie_service.exe
最后,写一个BAT脚本。内容如下:
其中D:\ruijie_service.exe 为上一步生成的程序路径。

@echo off
color 2f
sc create 8021x binpath= "D:\ruijie_service.exe" displayname= "8021x" depend= Tcpip
sc config 8021x start= auto
echo 设置成功 
net start 8021x
pause

此脚本只需运行一遍即可。
如要删除该服务,运行如下命令即可:

sc delete 8021x

然后重启即可。

这样以后,只要电脑开机了,不用登录进去,机子就已经连网了。
在WIN2003 enterprise简体中文版 SP2 下测试成功。

Tagged in : 锐捷,认证,开机启动

All Comments (0)
Gravatar image
No Comments