Пример #1
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;
}
Пример #2
0
static ngx_int_t 
ngx_http_session_header_filter(ngx_http_request_t *r)
{
    ngx_http_session_conf_t      *sscf;
    ngx_str_t                        sid;
    ngx_int_t                        ret;
    ngx_uint_t                       status;
    ngx_http_upstream_t              *u;
    ngx_table_elt_t                  *set_cookie;
    u_char                           *cookie;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
            "session filter begin\n");

    sscf = ngx_http_get_module_loc_conf(r, ngx_http_session_module);

    if (!sscf->enabled) {
        return NGX_DECLINED;
    }

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

    if (!ngx_http_session_test_create(r)) {
        return NGX_DECLINED;
    }

    /* r->session_create is set, create a new session */
    u = r->upstream;
    if (!u && !ngx_http_session_test_local(r)) {
        return NGX_DECLINED;
    }

    if (u) {
        status = u->state->status;

        if (status < 200 || status > 400) {
            return NGX_DECLINED;
        }
    }

    memset(&sid, 0, sizeof(ngx_str_t));
    
    sid.data = ngx_pcalloc(r->pool, 33);
    if (sid.data == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ret = ngx_http_session_gen_sid(r, &sid);
    if (ret != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ret = ngx_http_session_insert(r, &sid);
    if (ret != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    cookie = ngx_pcalloc(r->pool, (strlen((char *)sscf->keyword.data) + 2 +
		NGX_HTTP_SESSION_DEFAULT_SID_LEN + strlen("; Path=/; HttpOnly")));
    if (cookie == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ngx_sprintf(cookie, "%s=%s; Path=/; HttpOnly",
            sscf->keyword.data, sid.data);
    
    set_cookie = ngx_list_push(&r->headers_out.headers);
    if (set_cookie == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    set_cookie->hash = 1;
    set_cookie->key.len = sizeof ("Set-Cookie") - 1;
    set_cookie->key.data = (u_char *) "Set-Cookie";
    set_cookie->value.len = ngx_strlen(cookie);
    set_cookie->value.data = cookie;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
            "filter end\n");

    return NGX_OK;
}
Пример #3
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;
}
Пример #4
0
static ngx_int_t
ngx_http_session_handler(ngx_http_request_t *r)
{
    ngx_http_session_conf_t             *sscf;
    ngx_http_session_t                  *session;
    ngx_http_session_list_t             *session_list;
    ngx_str_t                           cookie;
    ngx_int_t                           ret;
    
    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
            "session handler begin");
    
    sscf = ngx_http_get_module_loc_conf(r, ngx_http_session_module);
    
    if (!sscf->enabled) {
        return NGX_DECLINED;
    }

    if (ngx_http_session_request_cleanup_init(r) == NGX_ERROR) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    if (sscf->session_show_enabled
            || ngx_http_session_is_favico(r)) {
        ngx_http_session_set_bypass(r);
        ngx_http_session_clr_found(r);
        ngx_http_session_clr_create(r);
        
        return NGX_DECLINED;
    }

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

    ret = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, 
            &sscf->keyword, &cookie);
    if (ret == NGX_DECLINED 
            || cookie.len == 0) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                "new session, create one when response");
        
        ngx_http_session_clr_found(r);
        ngx_http_session_set_create(r);

        ngx_http_session_set_location_handler(r);

        /* return NGX_OK to jump over other modules in NS layer */
        return NGX_OK;
    }

    session_list = ngx_http_session_shm_zone->data;
    
    ngx_shmtx_lock(&session_list->shpool->mutex);

    session = __ngx_http_session_search(r, &cookie);
    if (!session) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                "session time out!");
       
        ngx_http_session_clr_found(r);
        ngx_http_session_set_create(r);
        
        ngx_http_session_set_location_handler(r);
        
        ngx_shmtx_unlock(&session_list->shpool->mutex);
       
        return NGX_OK;
    } else {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                "find a session");

        ngx_http_session_set_found(r);
        ngx_http_session_clr_create(r);

        ngx_http_session_set_request_session(r, session);
        __ngx_http_session_get_ref(r);

        /* reset timer */
        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
            "reset timer: %p, timeout: %d, ref: %d\n", 
            session, session->timeout, session->ref);

        session->reset = 1;
        session->timeout = sscf->timeout;
        session->est = ngx_time();
        if (!ngx_queue_empty(&session->redirect_queue_node)) {
            ngx_queue_remove(&session->redirect_queue_node);
            ngx_queue_init(&session->redirect_queue_node);
            session_list->redirect_num--;
            if (session->ev.timer_set) {
                ngx_del_timer(&session->ev);
            }
        }
        __ngx_http_session_insert_to_new_chain(session_list, session);
    }

    ngx_shmtx_unlock(&session_list->shpool->mutex);

    /*In blacklist*/
    if (!ngx_http_session_test_bypass(r) && session->bl_timeout > ngx_time()) {
        return NGX_ERROR;
    }

    return NGX_DECLINED;
}