ngx_int_t ngx_http_neteye_security_body_filter(ngx_http_request_t *r,
        ngx_chain_t *in)
{
    ngx_int_t i = 1, ret;
    ngx_http_neteye_security_response_body_pt handler;
    ngx_http_neteye_security_module_t *module;
    ngx_http_ns_ctx_t           *ctx;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
            "neteye security response body begins, handler number: %d",
            nr_response_body_chain);

    if (ngx_http_ns_test_bypass_all(r)) {
        return ngx_http_next_body_filter(r, in);
    }

    if (nr_response_body_chain == 0) {
        return ngx_http_next_body_filter(r, in);
    }

    ctx = ngx_http_ns_get_request_ctx(r);
    if (ctx == NULL) {
        return ngx_http_next_body_filter(r, in);
    }

    while (1) {
        module = response_body_chain[i];

        if (module
                && !ngx_http_ns_jump_bit_is_set(r, module->id)) {
            handler = module->response_body_handler;
            ret = handler(r, in);
        } else {
            i++;

            if (i > max_response_body_chain) {
                /* all handlers have been called */
                break;
            }

            continue;
        }

        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "neteye security response body: %d - %s(ret: %d)",
                module->id, module->name, ret);

        /* terminate current process in nginx */
        if (ret == NGX_DONE) {
            return NGX_DONE;
        }

        /* skip other handlers */
        if (ret == NGX_OK) {
            break;
        }

        if (ret == NGX_ERROR) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "Request denied by handler: %d - %s",
                    module->id, module->name);
            return NGX_ERROR;
        }

        /* some internal error */
        if (ret >= 400) {
            return ret;
        }

        if (ngx_http_ns_test_bypass_all(r)) {
            break;
        }

        /* next handler in the list */
        if (ret == NGX_DECLINED) {
            i++;

            if (i > max_response_body_chain) {
                /* all handlers have been called */
                break;
            }

            continue;
        }

        /* jump to another handler, ret is the new handler id */
        if (ret > max_response_body_chain || ret < 0) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "jump to unkown handler");

            return NGX_ERROR;
        } else {
            if (response_body_chain[i] == NULL) {
                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "jump to unkown handler");

                return NGX_ERROR;
            }

            i = ret;
        }
    }

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
            "neteye security response body ends without any deny action");

    return ngx_http_next_body_filter(r, in);
}
예제 #2
0
ngx_int_t ngx_http_cp_header_handler(ngx_http_request_t *r)
{
    ngx_table_elt_t              *h;
    ngx_list_part_t              *part;
    ngx_http_upstream_t          *u;
    ngx_uint_t                   i, j, cmp_len;
    u_char                       *start, *end, *p;
    ngx_str_t                    cookie, cookie_name;
    ngx_str_t                    neteye_cookie;
    ngx_http_cp_loc_conf_t       *cplcf;
    ngx_uint_t                   magic;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 
            0, "cookie poison header handler");
    
    if (ngx_http_session_test_bypass(r)) {
        return NGX_DECLINED;
    }

    if (ngx_http_ns_test_bypass_all(r)) {
        return NGX_DECLINED;
    }
    
    cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cookie_poisoning_module);
    
    if (cplcf->enabled != 1) {
        /* Cookie Poison not enabled */
        return NGX_DECLINED;
    }

    u = r->upstream;
    if (u) {
        part = &u->headers_in.headers.part;
    } else {
	    /* response from local */
        part = &r->headers_out.headers.part;
    }

    if (part == NULL) {
        /* Have no headers */
        return NGX_DECLINED;
    }

    memset(&cookie, 0, sizeof(ngx_str_t));
    memset(&cookie_name, 0, sizeof(ngx_str_t));
    memset(&neteye_cookie, 0, sizeof(ngx_str_t));

    h = part->elts;

    for (i = 0; ; i++) {
        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }

            part = part->next;
            h = part->elts;
            i = 0;
        }

        if (h[i].key.len != strlen("Set-Cookie")) {
            continue;
        }

        if (!memcmp(h[i].key.data, "Set-Cookie", h[i].key.len)) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                    "found set cookie");

            start = p = h[i].value.data;
            end = h[i].value.data + h[i].value.len;
            
            for (j = 0; j < h[i].value.len; j++, p++) {
                if (*p == ' ' || *p == '=') {
                    cookie_name.data = start;
                    cookie_name.len = p - start;

                    /* store this cookie's value to cookie */
                    if (*p == ' ') {
                        for (; *p != '='; p++) ;
                    }

                    p++;

                    cookie.data = p;

                    for (; *p != ';' && p < end; p++) ;

                    cookie.len = p - cookie.data;

                    if (cookie.len == 0) {
                        break;
                    }

                    cmp_len = cookie.len >= strlen("deleted") ? 
                        strlen("deleted") : cookie.len;

                    if (!strncmp((char *)cookie.data, "deleted", cmp_len)) {
                        /* update monitored cookies in session*/
                        ngx_http_cp_delete_monitored_cookies(r, &cookie_name);
                        break;
                    }

                    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                            "cookie_name: %V, cookie_data: %V", 
                            &cookie_name, &cookie);
                    
                    /* md5 the cookie_data, and add it to the header */
                   
                    magic = ngx_random();
                    if (ngx_http_cp_gen_cookie_data(r, &cookie,
                                &neteye_cookie, magic)
                            != NGX_OK) {
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
                    }

                    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "neteye_cookie_data: %V",
                            &neteye_cookie);
                    
                    /* update monitored cookies in session*/
                    ngx_http_cp_update_monitored_cookies(r,
                            &cookie_name, &neteye_cookie, magic);

                    break;
                }
            }
        }
    }

    return NGX_DECLINED;
}
static ngx_int_t
ngx_http_neteye_security_request_handler(ngx_http_request_t *r)
{
    ngx_int_t i = 1, ret;
    ngx_http_neteye_security_request_pt handler;
    ngx_http_neteye_security_module_t *module;
    ngx_http_ns_loc_conf_t *nlcf;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
            "neteye security phase begins, handler number: %d",
            nr_request_chain);

    if (ngx_http_ns_test_bypass_all(r)) {
        return NGX_DECLINED;
    }

    if (nr_request_chain == 0) {
        return NGX_DECLINED;
    }

    nlcf = ngx_http_get_module_loc_conf(r, ngx_http_neteye_security_module);

    if (r->internal && !nlcf->force) {
        return NGX_DECLINED;
    }

    if (ngx_http_ns_ctx_init(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (ngx_http_ns_request_ctx_not_inited(r)
            && ngx_http_ns_request_ctx_init(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    while (1) {
        module = request_chain[i];

        if (r->se_handler != NULL) {
            if (module == NULL || r->se_handler != module->request_handler) {
                i++;
                continue;
            }
            r->se_handler = NULL;
        }

        if (module && !ngx_http_ns_jump_bit_is_set(r, module->id)) {
            handler = module->request_handler;
            ret = handler(r);
        } else {
            i++;

            if (i > max_request_chain) {
                /* all handlers have been called */
                break;
            }

            continue;
        }

        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                "neteye security handler: %d - %s(ret: %d)",
                module->id, module->name, ret);

        /* terminate current process in nginx */
        if (ret == NGX_DONE) {
            return NGX_DONE;
        }

        /* skip other handlers */
        if (ret == NGX_OK) {
            break;
        }

        if (ret == NGX_ERROR) {
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "Request denied by handler: %d - %s",
                    module->id, module->name);
            return NGX_ERROR;
        }

        if (ngx_http_ns_test_bypass_all(r)) {
            break;
        }

        /* next handler in the list */
        if (ret == NGX_DECLINED) {
            i++;

            if (i > max_request_chain) {
                /* all handlers have been called */
                break;
            }

            continue;
        }

        if (ret < 0) {
            return ret;
        }

        /* some internal error */
        if (ret >= 400) {
            return ret;
        }

        /* jump to another handler, ret is the new handler id */
        if (ret > max_request_chain) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "jump to unkown handler");

            return NGX_ERROR;
        } else {
            if (request_chain[i] == NULL) {
                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "jump to unkown handler");

                return NGX_ERROR;
            }

            i = ret;
        }
    }

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
            "neteye security phase ends without any deny action");

    return NGX_DECLINED;
}
예제 #4
0
static ngx_int_t
ngx_http_cp_handler(ngx_http_request_t *r)
{
    ngx_http_cp_loc_conf_t           *cplcf;
    ngx_str_t                        cookie, cookie_name;
    ngx_str_t                        neteye_cookie;
#if (NGX_DEBUG)
    ngx_str_t                        cookie_magic;
#endif
    ngx_int_t                        ret;
    ngx_uint_t                       i, j;
    ngx_table_elt_t                  **h;
    u_char                           *start, *end, *p;
    ngx_http_cp_monitored_cookie_t   *m_cookie;
    
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
            "cookie poison handler begin");
    
    if (ngx_http_session_test_bypass(r)) {
        return NGX_DECLINED;
    }

    cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cookie_poisoning_module);
    
    if (!cplcf->enabled) {
        return NGX_DECLINED;
    }

    if (ngx_http_ns_test_bypass_all(r)) {
        return NGX_DECLINED;
    }
    
    memset(&cookie, 0, sizeof(ngx_str_t));
    memset(&cookie_name, 0, sizeof(ngx_str_t));
    memset(&neteye_cookie, 0, sizeof(ngx_str_t));
                
    h = r->headers_in.cookies.elts;

    for (i = 0; i < r->headers_in.cookies.nelts; i++) {
        start = p = h[i]->value.data;
        end = start + h[i]->value.len;
       
        /* skip the spaces at head */
        for (; start < end && *start == ' '; start++) { }

        if (start == end) {
            /* no more in this value */
            continue;
        }

        for (j = 0; j < h[i]->value.len; j++, p++) {
            if (*p == '=') {
                cookie_name.data = start;
                cookie_name.len = p - start;

                if (cookie_name.len == strlen(NGX_HTTP_SESSION_DEFAULT_COOKIE)) {
                    if (!memcmp(cookie_name.data,
                                NGX_HTTP_SESSION_DEFAULT_COOKIE,
                                strlen(NGX_HTTP_SESSION_DEFAULT_COOKIE))) {
                        goto next;
                    }
                }

                /* store this cookie's value to cookie */
                ret = ngx_http_parse_multi_header_lines(&r->headers_in.cookies,
                        &cookie_name, &cookie);
                if (ret == NGX_DECLINED 
                        || cookie.len == 0) {
                    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "BIG ERROR!");

                    goto next;
                }

                ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "cookie_name: %V, cookie_data: %V",
                        &cookie_name, &cookie);

                m_cookie = ngx_http_cp_check_cookie(r, &cookie_name);
                if (m_cookie != NULL) {
                    /* this cookie is monitored */
                    if (ngx_http_cp_gen_cookie_data(r, &cookie,
                                &neteye_cookie, m_cookie->magic) != NGX_OK) {
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
                    }

#if (NGX_DEBUG)
                    cookie_magic.data = m_cookie->cookie_magic;
                    cookie_magic.len = NGX_HTTP_CP_MD5_LEN;

                    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "neteye_cookie_data: %V, expected: %V", 
                            &neteye_cookie, &cookie_magic);
#endif
                    
                    if (memcmp(m_cookie->cookie_magic, neteye_cookie.data,
                                NGX_HTTP_CP_MD5_LEN)) {
                        /* not matched, do action */
                        ret = ngx_http_cp_do_action(r, &cookie_name, &cookie);
                        if (ret != NGX_OK) {
                            return ret;
                        }
                    }
                } else {
                    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "cookie is not monitored");
                }

next:
                for (; start < end && *start != ';'; start++) { }

                if (start == end) {
                    /* no more in this value */
                    break;
                }

                /* *start == ';' */

                start++;
                for (; start < end && *start == ' '; start++) { }

                if (start == end) {
                    /* no more in this value */
                    break;
                }

                p = start;
            }
        }
    }

    return NGX_DECLINED;
}