/* * この関数に届く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; }
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; }
/** * 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; }