Esempio n. 1
0
int srvclamav_write_to_net(char *buf, int len, ci_request_t * req)
{
     int bytes;
     av_req_data_t *data = ci_service_data(req);
     if (!data)
          return CI_ERROR;

#ifdef VIRALATOR_MODE
     if (data->must_scanned == VIR_SCAN) {
          return send_vir_mode_page(data, buf, len, req);
     }
#endif

     if (data->virus_name != NULL && data->error_page == 0) {
          /*Inform user. Q:How? Maybe with a mail...... */
          return CI_EOF;        /* Do not send more data if a virus found and data has sent (readpos!=0) */
     }
     /*if a virus found and no data sent, an inform page has already generated */

     if (data->error_page)
          return ci_membuf_read(data->error_page, buf, len);

     if(data->body)
	 bytes = ci_simple_file_read(data->body, buf, len);
     else
	 bytes =0;
     return bytes;
}
Esempio n. 2
0
/**
 * Preview HTTP Body and determine hook or unlock the request.<br>
 * prev = java_init_request_data(ci_request_t * req)<br>
 * MOD_CONTINUE = java_service_io(char * wbuf, int * wlen, char * rbuf, int * rlen, int iseof, ci_request_t * req)<br>
 * ALLOW204 = java_release_request_data(void * data)<br>
 *
 * @see java_init_request_data(ci_request_t * req)
 * @see java_service_io(char * wbuf, int * wlen, char * rbuf, int * rlen, int iseof, ci_request_t * req)
 * @see java_release_request_data(void * data)
 * @param preview_data preview body.
 * @param preview_data_len preview body byte length.
 * @param req a pointer of request data.
 * @return CI_MOD_ALLOW204 if unhooks the request. CI_MOD_CONTINUE if hook the request. CI_ERROR if an error occurred.
 */
int java_check_preview_handler(char * preview_data, int preview_data_len, ci_request_t * req) {
    jServiceData_t * jServiceData = (jServiceData_t *)ci_service_data(req);
    jData_t * jdata = jServiceData->jdata;
    JNIEnv * jni = jdata->jni;
    jobject jInstance = jServiceData->instance;

    //convert C-char* to Java-byte[]
    jbyteArray jba = (*jni)->NewByteArray(jni, preview_data_len);
    if (jba == NULL) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "Could not allocate memory for preview_data byte array object. ignoring...");
        return CI_ERROR;
    }
    //int i;
   //:******* (*jni)->SetByteArrayRegion(jni, preview_data, START_INDEX, jba, preview_data_len);

    //Call int preview(byte[])
    jint status = (*jni)->CallIntMethod(jni, jInstance, jdata->jPreview, jba);
    if (status) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "%s.initialize(...) returned not %d.", jdata->name, CI_OK);
        return CI_ERROR;
    }
    //check preview data
    //hasbody
    //lock or  unlock
    // send to service_io?
    return CI_MOD_CONTINUE;
}
Esempio n. 3
0
int srvclamav_read_from_net(char *buf, int len, int iseof, ci_request_t * req)
{
     /*We can put here scanning hor jscripts and html and raw data ...... */
     int allow_transfer;
     av_req_data_t *data = ci_service_data(req);
     if (!data)
          return CI_ERROR;

     if (!data->body) /*No body data? consume all content*/
	 return len;

     if (data->must_scanned == NO_SCAN
#ifdef VIRALATOR_MODE
         || data->must_scanned == VIR_SCAN
#endif
         ) {                    /*if must not scanned then simply write the data and exit..... */
          return ci_simple_file_write(data->body, buf, len, iseof);
     }

     if (data->args.sizelimit
         && ci_simple_file_size(data->body) >= MAX_OBJECT_SIZE) {
          data->must_scanned = 0;
          ci_req_unlock_data(req);      /*Allow ICAP to send data before receives the EOF....... */
          ci_simple_file_unlock_all(data->body);        /*Unlock all body data to continue send them..... */
     }                          /*else Allow transfer SEND_PERCENT_BYTES of the data */
     else if (data->args.mode != 1 &&   /*not in the simple mode */
              SEND_PERCENT_BYTES
              && START_SEND_AFTER < ci_simple_file_size(data->body)) {
          ci_req_unlock_data(req);
          allow_transfer =
              (SEND_PERCENT_BYTES * (data->body->endpos + len)) / 100;
          ci_simple_file_unlock(data->body, allow_transfer);
     }
     return ci_simple_file_write(data->body, buf, len, iseof);
}
Esempio n. 4
0
int url_check_io(char *wbuf, int *wlen, char *rbuf, int *rlen, int iseof,
                 ci_request_t * req)
{
     int ret;
     struct url_check_data *uc = ci_service_data(req);
     if (!uc->body)
          return CI_ERROR;

     ret = CI_OK;
     if (uc->denied == 0) {
          if (rbuf && rlen) {
               *rlen = ci_cached_file_write(uc->body, rbuf, *rlen, iseof);
               if (*rlen == CI_ERROR)
                    ret = CI_ERROR;
          }
          else if (iseof)
               ci_cached_file_write(uc->body, NULL, 0, iseof);
     }

     if (wbuf && wlen) {
          *wlen = ci_cached_file_read(uc->body, wbuf, *wlen);
          if (*wlen == CI_ERROR)
               ret = CI_ERROR;
     }

     return ret;
}
Esempio n. 5
0
int url_check_check_preview(char *preview_data,int preview_data_len, request_t *req){
    ci_headers_list_t* req_header;
    struct url_check_data *uc=ci_service_data(req);
    struct http_info httpinf;
    int allow=1;

    if((req_header=ci_reqmod_headers(req))==NULL) /*It is not possible but who knows .....*/
	return CI_ERROR;

    get_http_info(req,req_header, &httpinf);

    ci_debug_printf(9,"URL  to host %s\n",httpinf.site);
    ci_debug_printf(9,"URL  page %s\n",httpinf.page);

    allow=check_destination(&httpinf);


    if(!allow){
	 /*The URL is not a good one so....*/
	 ci_debug_printf(9,"Oh!!! we are going to deny this site.....\n");

	 uc->body=ci_cached_file_new(strlen(error_message)+10);
	 ci_request_create_respmod(req,1,1); /*Build the responce headers*/

	 ci_respmod_add_header(req,"HTTP/1.1 403 Forbidden");/*Send an 403 Forbidden http responce to web client*/
	 ci_respmod_add_header(req,"Server: C-ICAP");
	 ci_respmod_add_header(req,"Content-Type: text/html");
	 ci_respmod_add_header(req,"Content-Language: en");
	 
	 ci_cached_file_write(uc->body,error_message,strlen(error_message),1);

    }
    else{
	 /*if we are inside preview negotiation or client allow204 responces oudsite of preview then*/
	 if(preview_data || ci_req_allow204(req)) 
	      return CI_MOD_ALLOW204;
	 
	 /*
	   Squid does not support preview of data in reqmod requests neither 204 responces outside preview
	   so we need to read all the body if exists and send it back to squid.
	   Allocate a new body for it 
	 */
	 if(ci_req_hasbody(req)){
	      int clen=ci_content_lenght(req)+100;
	      uc->body=ci_cached_file_new(clen);
	 }

    }

    unlock_data(req);
    return CI_MOD_CONTINUE;
}
Esempio n. 6
0
int info_io(char *wbuf, int *wlen, char *rbuf, int *rlen, int iseof,
            ci_request_t * req)
{
     int ret;
     struct info_req_data *info_data = ci_service_data(req);
     ret = CI_OK;

     if (wbuf && wlen) {
         if (info_data->body)	 
             *wlen = ci_membuf_read(info_data->body, wbuf, *wlen);
	 else
	     *wlen = CI_EOF;
     }

     return ret;
}
Esempio n. 7
0
int echo_io(char *rbuf,int *rlen,char *wbuf,int *wlen ,int iseof,request_t *req){
     int ret;
     ci_membuf_t *data=ci_service_data(req);
     ret=CI_OK;

     if(wbuf && wlen){
	  *wlen=ci_membuf_write(data,wbuf,*wlen,iseof);
	  if(*wlen<0)
	       ret=CI_ERROR;
     }
     else if(iseof)
	  ci_membuf_write(data,NULL,0,iseof);
     
     if(rbuf && rlen){
	  *rlen=ci_membuf_read(data,rbuf,*rlen);
     }
     
     return ret;
}
/*
 * この関数に届くreqは
 * check_preview_handlerでAllow204されなかったものです。
 */
int cix_end_of_data_handler(ci_request_t *req) {
    cix_debug_printf(CIX_INFO_LEVEL, "starts");
    body::MemBuf * instance = (body::MemBuf *)ci_service_data(req);
    bool already_denied =  false;
    if (ci_req_type(req) == ICAP_REQMOD && req->data_locked) {
          if (ci_req_hasbody(req)) {
            const char * body = instance->getBuffer();
            //bodyには全てのPOSTデータが入っている

            //XSSがPOSTデータに入っているか調査
            if(RE2::PartialMatch(body, ms1) ) {
                cix_debug_printf(CIX_INFO_LEVEL, "MS1 MATCHED!");
                if (RE2::PartialMatch(body, ms2)) {
                    cix_debug_printf(CIX_INFO_LEVEL, "MS2 MATCHED!!");
                    rewriteResponse403(req);
                    instance->setBuffer("<body>DENIED! XSS in POST!</body>");
                    cix_debug_printf(CIX_MESSAGE_LEVEL,"XSS found in POST!");
                    already_denied = true;
                }
            }

            //カナリアCookieがPOSTデータに入っているか調査
            if (!already_denied) {
                if (strstr(body, "piyopiyopiyo%3D") ) {
                    rewriteResponse403(req);
                    instance->setBuffer("<body>canaria in POST!</body>");
                    cix_debug_printf(CIX_MESSAGE_LEVEL, "CANARIA found in POST!");
                }
            }
        }
    }/*
    cix_debug_printf(CIX_INFO_LEVEL, "-------------------------query!!");
    const http::Url * u = (instance->url);
    u->getQuery();
    const std::map<char *,char *> * q = (instance->url)->getQuery();
    std::map<char *,char *>::const_iterator it = q->begin();
    while( it != q->end() ) {
        cix_debug_printf(CIX_INFO_LEVEL, "%s=%s", (*it).first, (*it).second);
	    it++;
    }*/
    return CI_MOD_DONE;
}
Esempio n. 9
0
int echo_check_preview_handler(char *preview_data,int preview_data_len, request_t *req){
     int content_len;
     ci_membuf_t *data=ci_service_data(req);
     content_len=ci_content_lenght(req);
     ci_debug_printf(10,"We expect to read :%d body data\n",content_len);

     ci_req_unlock_data(req); /*Icap server can send data before all body has received*/
     if(!preview_data_len)
	  return CI_MOD_CONTINUE;

    if(whattodo==0){
 	    whattodo=1;
	    ci_membuf_write(data,preview_data,preview_data_len,ci_req_hasalldata(req));
            return CI_MOD_CONTINUE;
    }
    else{
        whattodo=0;
        return CI_MOD_ALLOW204;
    }
}
static void demonstrateDetection(image_session_t *mySession)
{
struct stat stat_buf;
classify_req_data_t *data = ci_service_data(mySession->req);
char imageFILENAME[CI_MAX_PATH + 1];

	// Go back to a file so we can save a modified version
	memBodyToDiskBody(mySession->req);

	ci_http_response_remove_header(mySession->req, "Content-Length");
	data->disk_body->readpos = 0;
	close(data->disk_body->fd);
	unlink(data->disk_body->filename);
	if(strstr(ci_http_response_get_header(mySession->req, "Content-Type"), "jpeg"))
	{
		snprintf(imageFILENAME, CI_MAX_PATH, "%s.jpg", data->disk_body->filename);
		imageFILENAME[CI_MAX_PATH] = '\0';
		cvSaveImage(imageFILENAME, mySession->origImage, jpeg_p);
	}
	else
	{
		snprintf(imageFILENAME, CI_MAX_PATH, "%s.png", data->disk_body->filename);
		imageFILENAME[CI_MAX_PATH] = '\0';
		cvSaveImage(imageFILENAME, mySession->origImage, png_p);
		ci_http_response_remove_header(mySession->req, "Content-Type");
		ci_http_response_add_header(mySession->req, "Content-Type: image/png");
	}
	snprintf(data->disk_body->filename, CI_FILENAME_LEN + 1, "%s", imageFILENAME);
	data->disk_body->filename[CI_FILENAME_LEN] = '\0';
	data->disk_body->fd = open(data->disk_body->filename, O_RDWR | O_EXCL, F_PERM);
	if(fstat(data->disk_body->fd, &stat_buf) == 0)
		data->disk_body->bytes_in = data->disk_body->endpos = stat_buf.st_size;
	else
		data->disk_body->bytes_in = data->disk_body->endpos = 0;
	// Make new content length header
	ci_http_response_remove_header(mySession->req, "Content-Length");
	snprintf(imageFILENAME, CI_MAX_PATH, "Content-Length: %ld", (long) data->disk_body->endpos);
	imageFILENAME[CI_MAX_PATH] = '\0';
	ci_http_response_add_header(mySession->req, imageFILENAME);
}
Esempio n. 11
0
int info_check_preview_handler(char *preview_data, int preview_data_len,
                               ci_request_t * req)
{
     struct info_req_data *info_data = ci_service_data(req);

     if (ci_req_hasbody(req))
         return CI_MOD_ALLOW204;
     
     ci_req_unlock_data(req);
    
     ci_http_response_create(req, 1, 1); /*Build the responce headers */

     ci_http_response_add_header(req, "HTTP/1.0 200 OK");
     ci_http_response_add_header(req, "Server: C-ICAP");
     ci_http_response_add_header(req, "Content-Type: text/html");
     ci_http_response_add_header(req, "Content-Language: en");
     ci_http_response_add_header(req, "Connection: close");
     if (info_data->body) {
         build_statistics (info_data);
     }
     
     return CI_MOD_CONTINUE;
}
Esempio n. 12
0
//TODO: 全く同じheaderを持っている場合はこの関数を実行しない
int replace_headers(ci_request_t *req) {
	const int REQ_TYPE = ci_req_type(req);
	const char * (*addHeader)(ci_request_t *,const char *) = NULL;
	//RESPMODとREQMODの違いによって、関数ポインタを変えることで、同じ処理を2度書かなくてすむ。
	if (REQ_TYPE == ICAP_REQMOD) {
		ci_http_request_reset_headers(req);//TODO: Error management
		addHeader = ci_http_request_add_header;
	}else if (REQ_TYPE == ICAP_RESPMOD) {
		ci_http_response_reset_headers(req);//TODO: Error management
		addHeader = ci_http_response_add_header;
	} else {
		goto replace_headers_ignore;
	}

	PyObject * pInstance = (PyObject *)ci_service_data(req);//Don't decref
	PyObject * pList = PyObject_GetAttrString(pInstance,PYCI_CLASS_LIST_HEADERS);//DECREF ME

	if (pList && PyList_Check(pList)) {
		PyObject * pHeader;
		char * header;
		int i,pList_size;
		pList_size = PyList_Size(pList);//E+ TODO: size check
		for (i=0; i < pList_size ; i++) {
			pHeader = PyList_GetItem(pList,i);//E+ Don't DECREF
			if (pHeader && PyString_Check(pHeader)) {
				header = PyString_AsString(pHeader);//E+ Don't free me. TODO: size check
				addHeader(req, header);//TODO: Error check
			} else {
				pyci_debug_printf(PYCI_MESSAGE_LEVEL, "http headers replacing must be string. ignoring...");
				goto replace_headers_ignore;
			}
		}
	}
replace_headers_ignore:
	Py_XDECREF(pList);
	return 0;
}
Esempio n. 13
0
int srvclamav_end_of_data_handler(ci_request_t * req)
{
     av_req_data_t *data = ci_service_data(req);
     CL_ENGINE *vdb;
     ci_simple_file_t *body;
     const char *virname;
     int ret = 0;
     unsigned long scanned_data = 0;

     if (!data || !data->body)
          return CI_MOD_DONE;

     body = data->body;
     data->virus_check_done = 1;
     if (data->must_scanned == NO_SCAN) {       /*If exceeds the MAX_OBJECT_SIZE for example ......  */
          ci_simple_file_unlock_all(body);      /*Unlock all data to continue send them . Not really needed here.... */
          return CI_MOD_DONE;
     }


     ci_debug_printf(8, "Scan from file\n");
     lseek(body->fd, 0, SEEK_SET);
     vdb = get_virusdb();
#ifndef HAVE_LIBCLAMAV_095
     ret =
         cl_scandesc(body->fd, &virname, &scanned_data, vdb, &limits,
                     CL_SCAN_STDOPT);
#else
     ret =
         cl_scandesc(body->fd, &virname, &scanned_data, vdb,
                     CL_SCAN_STDOPT);
#endif

     if (ret == CL_VIRUS) {
	 data->virus_name = ci_buffer_alloc(strlen(virname)+1);
	 strcpy(data->virus_name, virname);
     }
     release_virusdb(vdb);

     ci_debug_printf(9,
                     "Clamav engine scanned %lu blocks of  data. Data size: %"
                     PRINTF_OFF_T "...\n", 
		     scanned_data, (CAST_OFF_T) body->endpos);

     if (ret == CL_VIRUS) {
          ci_debug_printf(5, "VIRUS DETECTED: %s.\n ",
                          data->virus_name);
          if (!ci_req_sent_data(req))   /*If no data had sent we can send an error page  */
               generate_error_page(data, req);
          else if (data->must_scanned == VIR_SCAN) {
               endof_data_vir_mode(data, req);
          }
          else
               ci_debug_printf(5, "Simply no other data sent\n");
          return CI_MOD_DONE;
     }
     else if (ret != CL_CLEAN) {
          ci_debug_printf(1,
                          "srvClamAv module: An error occured while scanning the data\n");
     }

     if (data->must_scanned == VIR_SCAN) {
          endof_data_vir_mode(data, req);
     }
     else if (data->allow204 && !ci_req_sent_data(req)) {
          ci_debug_printf(7, "srvClamAv module: Respond with allow 204\n");
          return CI_MOD_ALLOW204;
     }

     ci_simple_file_unlock_all(body);   /*Unlock all data to continue send them..... */
     ci_debug_printf(7,
                     "file unlocked, flags :%d (unlocked:%" PRINTF_OFF_T ")\n",
                     body->flags, (CAST_OFF_T) body->unlocked);
     return CI_MOD_DONE;
}
Esempio n. 14
0
int srvclamav_check_preview_handler(char *preview_data, int preview_data_len,
                                    ci_request_t * req)
{
     ci_off_t content_size = 0;
     int file_type;
     av_req_data_t *data = ci_service_data(req);

     ci_debug_printf(9, "OK; the preview data size is %d\n", preview_data_len);

     if (!data || !ci_req_hasbody(req)){
	 ci_debug_printf(9, "No body data, allow 204\n");
          return CI_MOD_ALLOW204;
     }

     /*Going to determine the file type,get_filetype can take preview_data as null ....... */
     file_type = get_filetype(req);
     if ((data->must_scanned = must_scanned(file_type, data)) == 0) {
          ci_debug_printf(8, "Not in scan list. Allow it...... \n");
          return CI_MOD_ALLOW204;
     }

     content_size = ci_http_content_length(req);
#ifdef VIRALATOR_MODE
     /*Lets see ........... */
     if (data->must_scanned == VIR_SCAN && ci_req_type(req) != ICAP_RESPMOD)
          data->must_scanned = SCAN;

     if (data->must_scanned == VIR_SCAN) {
          init_vir_mode_data(req, data);
          data->expected_size = content_size;
     }
     else {
#endif

          if (data->args.sizelimit && MAX_OBJECT_SIZE
              && content_size > MAX_OBJECT_SIZE) {
               ci_debug_printf(1,
                               "Object size is %" PRINTF_OFF_T " ."
                               " Bigger than max scannable file size (%"
                               PRINTF_OFF_T "). Allow it.... \n", 
			       (CAST_OFF_T) content_size,
                               (CAST_OFF_T) MAX_OBJECT_SIZE);
               return CI_MOD_ALLOW204;
          }

          data->body = ci_simple_file_new(MAX_OBJECT_SIZE);

          if (SEND_PERCENT_BYTES >= 0 && START_SEND_AFTER == 0) {
               ci_req_unlock_data(req); /*Icap server can send data before all body has received */
               /*Let ci_simple_file api to control the percentage of data.For the beggining no data can send.. */
               ci_simple_file_lock_all(data->body);
          }
#ifdef VIRALATOR_MODE
     }
#endif
     if (!data->body)           /*Memory allocation or something else ..... */
          return CI_ERROR;

     if (preview_data_len) {
	 if (ci_simple_file_write(data->body, preview_data, preview_data_len,
				  ci_req_hasalldata(req)) == CI_ERROR)
	     return CI_ERROR;
     }
     return CI_MOD_CONTINUE;
}
Esempio n. 15
0
int url_check_check_preview(char *preview_data, int preview_data_len,
                            ci_request_t * req)
{
     ci_headers_list_t *req_header;
     struct url_check_data *uc = ci_service_data(req);
     struct http_info httpinf;
     struct profile *profile;
     int pass = DB_PASS;

     if ((req_header = ci_http_request_headers(req)) == NULL) /*It is not possible but who knows ..... */
          return CI_ERROR;

     if (!get_http_info(req, req_header, &httpinf)) /*Unknown method or something else...*/
	 return CI_MOD_ALLOW204;

     ci_debug_printf(9, "URL  to host %s\n", httpinf.site);
     ci_debug_printf(9, "URL  page %s\n", httpinf.url);

     profile = profile_select(req);

     if (!profile) {
          ci_debug_printf(1, "No Profile configured! Allowing the request...\n");
	  return CI_MOD_ALLOW204;
     }

     if ((pass=profile_access(profile, &httpinf)) == DB_ERROR) {
          ci_debug_printf(1,"Error searching in profile! Allow the request\n");
	  return CI_MOD_ALLOW204;;
     }


     if (pass == DB_BLOCK) {
          /*The URL is not a good one so.... */
          ci_debug_printf(9, "Oh!!! we are going to deny this site.....\n");

          uc->denied = 1;
          uc->body = ci_cached_file_new(strlen(error_message) + 10);
          ci_http_response_create(req, 1, 1); /*Build the responce headers */

          ci_http_response_add_header(req, "HTTP/1.0 403 Forbidden"); /*Send an 403 Forbidden http responce to web client */
          ci_http_response_add_header(req, "Server: C-ICAP");
          ci_http_response_add_header(req, "Content-Type: text/html");
          ci_http_response_add_header(req, "Content-Language: en");
          ci_http_response_add_header(req, "Connection: close");

          ci_cached_file_write(uc->body, error_message, strlen(error_message),
                               1);

     }
     else {
          /*if we are inside preview negotiation or client allow204 responces oudsite of preview then */
          if (preview_data || ci_req_allow204(req))
               return CI_MOD_ALLOW204;

          /*
             icap client does not support preview of data in reqmod requests neither 204 responces outside preview
             so we need to read all the body if exists and send it back to client.
             Allocate a new body for it 
           */
          if (ci_req_hasbody(req)) {
               int clen = ci_http_content_length(req) + 100;
               uc->body = ci_cached_file_new(clen);
          }

     }

     unlock_data(req);
     return CI_MOD_CONTINUE;
}