Exemple #1
0
Str
find_cookie(ParsedURL *pu)
{
    Str tmp;
    struct cookie *p, *p1, *fco = NULL;
    int version = 0;
    char *fq_domainname, *domainname;

    dump(Strnew_charp("GET"));

    load_cookies_sync();

    fq_domainname = FQDN(pu->host);
    check_expired_cookies();
    for (p = First_cookie; p; p = p->next) {
	domainname = (p->version == 0) ? fq_domainname : pu->host;
	if (p->flag & COO_USE && match_cookie(pu, p, domainname)) {
	    for (p1 = fco; p1 && Strcasecmp(p1->name, p->name);
		 p1 = p1->next) ;
	    if (p1)
		continue;
	    p1 = New(struct cookie);
	    bcopy(p, p1, sizeof(struct cookie));
	    p1->next = fco;
	    fco = p1;
	    if (p1->version > version)
		version = p1->version;
	}
    }

    if (!fco)
	return NULL;

    tmp = Strnew();
    if (version > 0)
	Strcat(tmp, Sprintf("$Version=\"%d\"; ", version));

    Strcat(tmp, make_cookie(fco));
    for (p1 = fco->next; p1; p1 = p1->next) {
	Strcat_charp(tmp, "; ");
	Strcat(tmp, make_cookie(p1));
	if (version > 0) {
	    if (p1->flag & COO_PATH)
		Strcat(tmp, Sprintf("; $Path=\"%s\"", p1->path->ptr));
	    if (p1->flag & COO_DOMAIN)
		Strcat(tmp, Sprintf("; $Domain=\"%s\"", p1->domain->ptr));
	    if (p1->portl)
		Strcat(tmp,
		       Sprintf("; $Port=\"%s\"", portlist2str(p1->portl)));
	}
    }
    return tmp;
}
Exemple #2
0
int
main(int argc, char **argv)
{
    char     cookie[37];
    make_cookie(cookie);
    printf("cookie: '%s'\n", cookie);
    if (strlen(cookie) != 36)
    {
	printf("Not 36 characters long!\n");
	exit(-1);
    }
    exit(0);
}
Exemple #3
0
static int spot_cookie(request_rec *r)
{
    cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config,
                                                &usertrack_module);
    const char *cookie_header;
    ap_regmatch_t regm[NUM_SUBS];

    /* Do not run in subrequests */
    if (!dcfg->enabled || r->main) {
        return DECLINED;
    }

    if ((cookie_header = apr_table_get(r->headers_in, "Cookie"))) {
        if (!ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0)) {
            char *cookieval = NULL;
            int err = 0;
            /* Our regexp,
             * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)
             * only allows for $1 or $2 to be available. ($0 is always
             * filled with the entire matched expression, not just
             * the part in parentheses.) So just check for either one
             * and assign to cookieval if present. */
            if (regm[1].rm_so != -1) {
                cookieval = ap_pregsub(r->pool, "$1", cookie_header,
                                       NUM_SUBS, regm);
                if (cookieval == NULL)
                    err = 1;
            }
            if (regm[2].rm_so != -1) {
                cookieval = ap_pregsub(r->pool, "$2", cookie_header,
                                       NUM_SUBS, regm);
                if (cookieval == NULL)
                    err = 1;
            }
            if (err) {
                ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01499)
                              "Failed to extract cookie value (out of mem?)");
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            /* Set the cookie in a note, for logging */
            apr_table_setn(r->notes, "cookie", cookieval);

            return DECLINED;    /* There's already a cookie, no new one */
        }
    }
    make_cookie(r);
    return OK;                  /* We set our cookie */
}
// Find the cookie and figure out what to do
static int spot_cookie(request_rec *r)
{
    cookietrack_settings_rec *dcfg = ap_get_module_config(r->per_dir_config,
                                                &cookietrack_module);

    const char *cookie_header;
    ap_regmatch_t regm[NUM_SUBS];

    /* Do not run in subrequests */
    if (!dcfg->enabled || r->main) {
        return DECLINED;
    }

    /* Is DNT set? */
    const char *dnt_is_set = apr_table_get( r->headers_in, "DNT" );
    _DEBUG && fprintf( stderr, "DNT: %s\n", dnt_is_set );

    /* Do we already have a cookie? */
    char *cur_cookie_value = NULL;
    if( (cookie_header = apr_table_get(r->headers_in, "Cookie")) ){

        // this will match the FIRST occurance of the cookiename, not
        // subsequent ones.
        if( !ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0) ) {
            /* Our regexp,
             * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)
             * only allows for $1 or $2 to be available. ($0 is always
             * filled with the entire matched expression, not just
             * the part in parentheses.) So just check for either one
             * and assign to cookieval if present. */
            if( regm[1].rm_so != -1 ) {
                cur_cookie_value = ap_pregsub(r->pool, "$1", cookie_header,
                                       NUM_SUBS, regm);
            }
            if( regm[2].rm_so != -1 ) {
                cur_cookie_value = ap_pregsub(r->pool, "$2", cookie_header,
                                       NUM_SUBS, regm);
            }
        }
    }

    _DEBUG && fprintf( stderr, "Current Cookie: %s\n", cur_cookie_value );

    /* XFF support inspired by this patch:
       http://www.mail-archive.com/[email protected]/msg17378.html

       And this implementation for scanning for remote ip:
       http://apache.wirebrain.de/lxr/source/modules/metadata/mod_remoteip.c?v=2.3-trunk#267
    */

    // Get the IP address of the originating request
    const char *rname = NULL;   // Originating IP address
    char *xff         = NULL;   // X-Forwarded-For, or equivalent header type

    // Should we look at a header?
    if( xff = apr_table_get(r->headers_in, dcfg->cookie_ip_header) ) {

        // There might be multiple addresses in the header
        // Check if there's a comma in there somewhere

        // no comma, this is the address we can use
        if( (rname = strrchr(xff, ',')) == NULL ) {
            rname = xff;

        // whitespace/commas left, remove 'm
        } else {

            // move past the comma
            rname++;

            // and any whitespace we might find
            while( *rname == ' ' ) {
                rname++;
            }
        }

    // otherwise, get it from the remote host
    } else {
        rname = ap_get_remote_host( r->connection, r->per_dir_config,
                                    REMOTE_NAME, NULL );
    }

    _DEBUG && fprintf( stderr, "Remote Address: %s\n", rname );

    /* Determine the value of the cookie we're going to set: */
    /* Make sure we have enough room here... */
    char new_cookie_value[ _MAX_COOKIE_LENGTH ];

    // dnt is set, and we care about that
    if( dnt_is_set && dcfg->comply_with_dnt ) {

        // you don't want us to set a cookie, alright then our work is done.
        if( !dcfg->set_dnt_cookie ) {
            return DECLINED;
        }

        char *dnt_value = dcfg->dnt_value;

        // you already ahve a cookie, but it might be whitelisted
        if( cur_cookie_value ) {

            // you might have whitelisted this value; let's check
            // Following tutorial code here again:
            // http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-19.html
            int i;
            for( i = 0; i < dcfg->dnt_exempt->nelts; i++ ) {
                _DEBUG && fprintf( stderr, "e: %d\n", i );

                char *exempt = ((char **)dcfg->dnt_exempt->elts)[i];

                //it's indeed whiteliested, we should use this value instead
                if( strcasecmp( cur_cookie_value, exempt ) == 0 ) {
                    _DEBUG && fprintf( stderr,
                        "Cookie %s is DNT exempt\n", cur_cookie_value );

                    dnt_value = exempt;
                }
            }
        }

        // dnt_value is a pointer, hence the sprintf
        sprintf( new_cookie_value, "%s", dnt_value );

    // No DNT header, so we need a cookie value to set
    } else {

        // there already is a cookie set
        if( cur_cookie_value ) {

            // but it's set to the DNT cookie
            if( strcasecmp( cur_cookie_value, dcfg->dnt_value ) == 0 ) {

                // if we have some sort of library that's generating the
                // UID, call that with the cookie we would be setting
                if( _EXTERNAL_UID_FUNCTION ) {
                    char ts[ _MAX_COOKIE_LENGTH ];
                    sprintf( ts, "%" APR_TIME_T_FMT, apr_time_now() );
                    gen_uid( new_cookie_value, ts, rname );

                // otherwise, just set it
                } else {
                    sprintf( new_cookie_value,
                             "%s.%" APR_TIME_T_FMT, rname, apr_time_now() );
                }

            // it's set to something reasonable - note we're still setting
            // a new cookie, even when there's no expires requested, because
            // we don't know if there's an expires on the /current/ cookie.
            // this could be added, but this seems to work for now.
            } else {
                // XXX we use a apr_pstrndup instead, so we can't overflow
                // the buffer if we get sent garbage
                // The return value is a
                sprintf( new_cookie_value, "%s",
                    apr_pstrndup( r->pool, cur_cookie_value, _MAX_COOKIE_LENGTH ) );

            }

        // it's either carbage, or not set; either way,
        // we need to generate a new one
        } else {
            // if we have some sort of library that's generating the
            // UID, call that with the cookie we would be setting
            if( _EXTERNAL_UID_FUNCTION ) {
                char ts[ _MAX_COOKIE_LENGTH ];
                sprintf( ts, "%" APR_TIME_T_FMT, apr_time_now() );
                gen_uid( new_cookie_value, ts, rname );

            // otherwise, just set it
            } else {
                sprintf( new_cookie_value,
                         "%s.%" APR_TIME_T_FMT, rname, apr_time_now() );
            }
        }
    }

    _DEBUG && fprintf( stderr, "New cookie: %s\n", new_cookie_value );

    /* Set the cookie in a note, for logging */
    apr_table_setn(r->notes, dcfg->note_name, new_cookie_value);

    make_cookie(r,  new_cookie_value,
                    cur_cookie_value,
                    (dnt_is_set && dcfg->comply_with_dnt)   // should we use dnt expires?
                );

    // We need to flush the stream for messages to appear right away.
    // Performing an fflush() in a production system is not good for
    // performance - don't do this for real.
    _DEBUG && fflush(stderr);

    return OK;                  /* We set our cookie */
}
Exemple #5
0
/*
 *  setup_session
 *
 *  Create a new session for the given handler
 */
void
setup_session(struct handler_args* hargs, 
    xmlHashTablePtr sessions, 
    struct qz_config* conf){ 

    struct session * this_session;

    // session_id is a number here, a string in the session struct,
    // and the encrypted contents of the session key, same value for each.
    uint64_t session_id;

    this_session = calloc(1, sizeof(struct session));

    // Assign a random number that has no zero octets 
    // as the session identifier, then test it.
    session_id = qzrandom64ch(this_session->session_id); 

    // There is a risk of session id collisions that
    // is larger than might be hoped from the 
    // birthday paradox.
    // With around 200 users, the chance of a hash key
    // collission is around 10^-15.  This is on the order
    // of random bit errors and cosmic ray bit flipping.
    // With around 6000 users, the chance goes up to
    // around 10^-6, or once in a million.
    // Or it could be the NSA is  messing with your PRNG, 
    // or it could be your  PRNG is setup wrong.
    // In any case, it is bad and wrong to continue.
    struct session* test_for_session;
    test_for_session = xmlHashLookup(sessions, this_session->session_id);

    if (test_for_session != NULL){
        fprintf(hargs->log, "%f %d %s:%d collision in session identifiers - %s\n",
            gettime(), hargs->request_id, __func__, __LINE__,
            "terminating application now");
        
       FCGX_FPrintF(hargs->err, 
           "collision in session identifiers - ending program now\n");

       exit(49);
    }

    if (pthread_mutex_init( &(this_session->session_lock), NULL) != 0){
        fprintf(hargs->log, "%f %d %s:%d mutex_init failed\n",
            gettime(), hargs->request_id, __func__, __LINE__);
        fflush(hargs->log);
        free(this_session);
        return;
    }

    make_etag(hargs->session_key, conf->tagger_socket_path, session_id);

    snprintf(this_session->tagger_socket_path, MAXPATHLEN, "%s", 
        conf->tagger_socket_path);  

    this_session->zero = 0;
    this_session->is_logged_in = false;
    this_session->logged_in_time = 0;
    this_session->logged_out_time = 0;
    this_session->last_activity_time = time(NULL);
    this_session->conn = NULL;
    
    // 197 is just an arbritrary value.
    // It is prime, hashes should be a prime size.
    // These should be in the config file. XXXXXXXXXXXXX
    this_session->opentables = xmlHashCreate(197);
    this_session->pgtype_datum = xmlHashCreate(197);
    this_session->form_tags = xmlHashCreate(197);
    this_session->form_sets = xmlHashCreate(197);

    this_session->integrity_token = conf->integrity_token;

    // index on session_id for crypto etag
    xmlHashAddEntry(sessions, this_session->session_id, this_session);

    // cookie path is /qz/ or whatever is used as the base path
    char* uri_parts[] = {hargs->uri_parts[0],"",NULL};
    char* path = build_path(uri_parts);

    make_cookie(hargs, "session_key", hargs->session_key, path,
        NULL, 0, false, true);
    free(path);

    hargs->session = this_session;

    fprintf(hargs->log, "%f %d %s:%d setup_session complete\n",
        gettime(), hargs->request_id, __func__, __LINE__);

    return;
}