zoukankan      html  css  js  c++  java
  • 使用clamav模块对数据流进行病毒检测

    准备工作:linux下安装clamav成功,启动clamav并打开本地socket监听"/tmp/clamav.socket"

    clamav开源工程目录:/usr/local/

    修改配置文件:/usr/local/clamav/etc/clamd.conf

    # Path to a local socket file the daemon will listen on.
    # Default: disabled (must be specified by a user)
    LocalSocket /tmp/clamd.socket

    保存配置文件后,执行命令:

    [root@ext sbin]# /usr/local/clamav/sbin/clamd &
    [1] 25102
    [root@ext sbin]# LibClamAV Warning: **************************************************
    LibClamAV Warning: *** The virus database is older than 7 days! ***
    LibClamAV Warning: *** Please update it as soon as possible. ***
    LibClamAV Warning: **************************************************

    [root@ext sbin]#

    查看服务监听:

    netstat -an|grep cla
    unix  2      [ ACC ]     STREAM     LISTENING     53748    /tmp/clamd.socket

    该程序实现方式是通过读取文件内容,然后将文件内容以流的方式发送至clamav服务,通过对clamav服务的返回结果,来判断该文件是否存在病毒;

    流程:

    ①、创建与clamav.socket的连接;

    ②、发送字符串 "zINSTREAM"到clamav,表示开始对数据流进行检查; 

    ③、开始读取文件内容,然后讲文件内容以流的方式发送至clamav,发送内容 <= 10M ;(为了提高效率定为 10M ,可以根据自己实际情况调整该值大小)

    ④、数据发送完成后,发送 4 个字节的空字节至clamav,通过该方式通知clamav该次数据发送完成,可以开始返回检测结果;

    ⑤、读取clamav返回内容,其中包含内容 “stream: OK”时,表示该次检测的流中没有检测到病毒;否则,将会返回该病毒信息;

    代码示例:

    #define MAX_DATA_LEN 8000
    #define MAX_FILE_LEN 1024*1024*10
    #define START_CHECK_VIRUS  "zINSTREAM"
    
    int virus_check(const char *szFileName){
        int sock,fd;
        int tmperror = 0;
        int len;
        int revl = 0;
        unsigned long int todo = MAX_FILE_LEN;
        char rbuf[256];
        uint32_t buf[MAX_DATA_LEN/sizeof(uint32_t)];
        sock = CreateConnectLocaleSocket("/tmp/clamd.socket", &tmperror);
        if (sock < 0){
            zlog_debug(cat,"CreateConnectLocaleSocket error");
            return -1;
        }
        fd = open (szFileName, O_RDONLY|0);
        if (fd < 0){
            zlog_debug(cat,"open [%s] err!",szFileName);
            return -1;
        }
        if(sendln(sock,START_CHECK_VIRUS, 10)){
            zlog_debug(cat,"sendln zINSTREAM erro 
    ");
            close(sock);
            return -1;
        }
        
        while((len = read(fd, &buf[1], sizeof(buf) - sizeof(uint32_t))) > 0){
            if((unsigned int)len > todo) 
                len = todo;
            buf[0] = htonl(len);
            if(sendln(sock, (const char *)buf, len+sizeof(uint32_t))){
                close(fd);
                close(sock);
                return -1;
            }
            todo -= len;
            if(!todo){
                len = 0;
                break;
            }
        }
        close(fd);
    
        *buf=0;
        sendln(sock, (const char *)buf, 4);
    
        memset(rbuf,0x00,sizeof(rbuf));
        revl = recv(sock, rbuf, sizeof(rbuf), 0);
    
        close(sock);
        return parse_Check_results(rbuf,revl);
    }
    
    int parse_Check_results(const char *bufdata,int bufLen){
        zlog_debug(cat,"parse_Check_results = [%s] ----------",bufdata);
        if(!strcmp(bufdata,"stream: OK")){
            return 0;
        }
        else{
            zlog_error(cat, "parse_Check_results  err, info = [%s]",bufdata);
        }
        return -2;
    }
    
    int sendln(int sockd, const char *line, unsigned int len){
        while(len)
            {
            int sent = send(sockd, line, len, 0);
            if(sent <= 0)
                {
                if(sent && errno == EINTR)
                    {
                    continue;
                    }
                return 1;
                }
            line += sent;
            len -= sent;
            }
        return 0;
    }
    
    
    int CreateConnectLocaleSocket(char *pszHostString, int *pnResCode){
        int nConnectFd = 0;
        struct sockaddr_un struInAddr;//���� socket
        if((nConnectFd=socket(AF_UNIX,SOCK_STREAM,0))==-1){
            zlog_error(cat, "CreateConnectLocaleSocket err, errno = [%d] strerror(errno) = [%s]",
                       errno,strerror(errno));
            *pnResCode=errno;
            return -1;
            }
        struInAddr.sun_family = AF_UNIX;
        strcpy(struInAddr.sun_path, pszHostString);
        if(connect(nConnectFd,(struct sockaddr *)&struInAddr,sizeof(struct sockaddr_un))==-1)
            {
            zlog_error(cat, "CreateConnectLocaleSocket connect err, errno = [%d] strerror(errno) = [%s]",
                       errno,strerror(errno));
            close(nConnectFd);
            *pnResCode=errno;
            return -1;
            }
        return nConnectFd;
    }


    转载请注明出处

  • 相关阅读:
    vue-loader介绍和单页组件介绍
    webpack的插件 http-webpack-plugin。 webpack-dev-server
    webpack的介绍
    Axios 的基本使用
    如何使用 re模块的, spilt.
    为 JS 的字符串,添加一个 format 的功能。
    另一种分页器 不依赖Paginator模块的方法
    Socket初识
    网络协议
    双下方法补充以及异常处理
  • 原文地址:https://www.cnblogs.com/dpf-10/p/7898977.html
Copyright © 2011-2022 走看看