/*
 * この関数に届く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;
}
//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;
}
Beispiel #3
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;
}
Beispiel #4
0
/**
 * initialize ICAP Request.<br>
 * prev = recv Request<br>
 * next = java_check_preview_handler(char * preview_data, int preview_data_len, ci_request_t * req)<br>
 *
 * @see java_check_preview_handler(char * preview_data, int preview_data_len, ci_request_t * req)
 * @param req a pointer of request data.
 * @return service_data instance if OK else returns NULL(pass)
 */
void * java_init_request_data(ci_request_t * req) {
    const int REQ_TYPE = ci_req_type(req);
    const char * METHOD_TYPE = ci_method_string(REQ_TYPE);//Don't free!

    ci_headers_list_t *hdrs = NULL;

    //identify reqmod or respmod or else
    if (REQ_TYPE == ICAP_REQMOD) {
        hdrs = ci_http_request_headers(req);
    } else if (REQ_TYPE == ICAP_RESPMOD) {
        hdrs = ci_http_response_headers(req);
    } else if (REQ_TYPE == ICAP_OPTIONS){
        cij_debug_printf(CIJ_INFO_LEVEL, "ICAP OPTIONS comes. ignoring...");
        return NULL;//pass
    } else {
        //UNKNOWN ICAP METHOD
        cij_debug_printf(CIJ_INFO_LEVEL, "INVALID ICAP METHOD (NO. %d) has come. ignoring...", REQ_TYPE);
        return NULL;//pass
    }

    //Create service_data
    jServiceData_t * jServiceData = NULL;
    jServiceData = (jServiceData_t *)malloc(sizeof(jServiceData_t));
    if (jServiceData == NULL) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "Unable to allocate memory for jServiceData_t !");
        cij_debug_printf(CIJ_ERROR_LEVEL, "Dropping request...");
        return NULL;
    }

    //Get Java environment from mod_name
    const char * mod_name = (req->current_service_mod)->mod_name;
    jData_t * jdata = (jData_t *)ci_dyn_array_search(environments, mod_name);
    if (jdata == NULL) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "Invalid mod_name %s is not in environments array.", mod_name);
        free(jServiceData);
        return NULL;
    }

    //Attach service instance to JVM
    jServiceData->jdata = jdata;
    JNIEnv * jni = jdata->jni;

    //Create new HTTP headers array for java
    jclass jClass_String = (*jni)->FindClass(jni, "java/lang/String");
    jobjectArray jHeaders = (*jni)->NewObjectArray(jni, hdrs->used, jClass_String, NULL);
    if (jHeaders == NULL) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "Could not allocate memory for http headers. ignoring...");
        return NULL;
    }
    (*jni)->DeleteLocalRef(jni, jClass_String);
    int i;
    for(i=0;i<hdrs->used;i++) {
        jstring buf = (*jni)->NewStringUTF(jni, hdrs->headers[i]);
        if (buf == NULL) {
            cij_debug_printf(CIJ_ERROR_LEVEL, "Could not allocate memory for http headers string. ignoring...");
            return NULL;
        }
        (*jni)->SetObjectArrayElement(jni, jHeaders, i, buf);
        (*jni)->DeleteLocalRef(jni, buf);
    }

    //Create instance.
    jobject jInstance = (*jni)->NewObject(jni, jdata->jIcapClass, jdata->jServiceConstructor,METHOD_TYPE,jHeaders);
    (*jni)->DeleteLocalRef(jni, jHeaders);
    if (jInstance == NULL) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "Could not create instance of the class '%s'. Method='%s'. ignoring...", mod_name, METHOD_TYPE);
        return NULL;
    }
    jServiceData->instance = jInstance;//+REF
    ci_membuf_t * buffer = ci_membuf_new();
    if (buffer == NULL) {
        cij_debug_printf(CIJ_ERROR_LEVEL, "Could not allocate memory for http body ignoring...");
        return NULL;
    }
    return (void *)jServiceData;
}