Beispiel #1
0
/** @brief Frees a TCP session **/
inline static void __tcp_free_session ( pntoh_tcp_session_t session )
{
	pntoh_tcp_session_t ptr = 0;
	pntoh_tcp_stream_t 	item = 0;
	ntoh_tcp_key_t		first = 0;

	if ( params.sessions_list == session )
		params.sessions_list = session->next;
	else{
		for ( ptr = params.sessions_list ; ptr != 0 && ptr->next != session ; ptr = ptr->next );

		if ( ptr != 0 )
			ptr->next = session->next;
	}

	lock_access( &session->lock );


	while ( ( first = htable_first ( session->timewait ) ) != 0 )
	{
	  item = (pntoh_tcp_stream_t)htable_remove(session->timewait,first,0);
		lock_access ( &item->lock );
		__tcp_free_stream ( session , &item , NTOH_REASON_SYNC , NTOH_REASON_EXIT );
	}

	while ( ( first = htable_first ( session->streams ) ) != 0 )
	{
	  item = (pntoh_tcp_stream_t)htable_remove(session->streams,first, 0);
		lock_access ( &item->lock );
		__tcp_free_stream ( session , &item , NTOH_REASON_SYNC , NTOH_REASON_EXIT );
	}

	unlock_access( &session->lock );

	pthread_cancel ( session->tID );
	pthread_join ( session->tID , 0 );
	sem_destroy ( &session->max_streams );
	sem_destroy ( &session->max_timewait );

	free_lockaccess ( &session->lock );

	htable_destroy ( &session->streams );
	htable_destroy ( &session->timewait );
    
    free ( session );

    return;
}
Beispiel #2
0
void expire_tls_sessions(main_server_st * s)
{
	tls_cache_st *cache;
	struct htable_iter iter;
	time_t now, exp;

	now = time(0);

	cache = htable_first(s->tls_db.ht, &iter);
	while (cache != NULL) {
		gnutls_datum_t d;

		d.data = (void *)cache->session_data;
		d.size = cache->session_data_size;

		exp = gnutls_db_check_entry_time(&d);

		if (now - exp > TLS_SESSION_EXPIRATION_TIME(s->config)) {
			cache->session_id_size = 0;

			htable_delval(s->tls_db.ht, &iter);

			safe_memset(cache->session_data, 0, cache->session_data_size);
			talloc_free(cache);
			s->tls_db.entries--;
		}
		cache = htable_next(s->tls_db.ht, &iter);
	}

	return;
}
Beispiel #3
0
void faup_snapshot_output(faup_handler_t *fh, faup_snapshot_t *snapshot, FILE *fd)
{
  size_t counter;
  size_t values_count;
  faup_snapshot_value_count_t *vc;
  struct htable_iter iter;
  char first_timebuf[200];
  char last_timebuf[200];

  fprintf(fd, "{\n");
  fprintf(fd,"\t\"snapshot name\": \"%s\",\n", snapshot->name);
  if (!snapshot->length) {
    fprintf(fd,"\t\"snapshot length\": %ld\n", snapshot->length);
  } else {
    fprintf(fd,"\t\"snapshot length\": %ld,\n", snapshot->length);
    fprintf(fd,"\t\"items\":[");
  for (counter = 0; counter < snapshot->length; counter++) {
    faup_snapshot_item_t *item = snapshot->items[counter];
    fprintf(fd,"\t\t{\n");
    fprintf(fd,"\t\t\"key\": \"%s\",\n", item->key);
    fprintf(fd,"\t\t\"length\": %ld,\n", item->length);
    fprintf(fd,"\t\t\"values\": [\n");

    if (item->length) {
      values_count = 1;
      vc = htable_first(&item->values, &iter);
      while (vc) {
	strftime(first_timebuf, sizeof(first_timebuf), "%Y-%m-%d %H:%M:%S %z", localtime(&vc->first_time_seen));
	strftime(last_timebuf, sizeof(last_timebuf), "%Y-%m-%d %H:%M:%S %z", localtime(&vc->last_time_seen));
	fprintf(fd,"\t\t\t{\"value\": \"%s\", \"count\": %ld, \"first seen\": \"%s\", \"last seen\": \"%s\"}", vc->value, vc->count, first_timebuf, last_timebuf);

	if (values_count == item->length) {
	  fprintf(fd,"\n");
	} else {
	  fprintf(fd,",\n");
	}
	  
	values_count++;
	vc = htable_next(&item->values, &iter);
      }
    }    
    fprintf(fd,"\t\t]\n\t}");     
    if (counter == snapshot->length - 1) {
      fprintf(fd,"\n");
      fprintf(fd, "\t]\n");
    } else {
      fprintf(fd,",\n");
    }
  }
  }
  fprintf(fd, "\n}\n");
}
Beispiel #4
0
void ip_lease_deinit(struct ip_lease_db_st* db)
{
struct ip_lease_st * cache;
struct htable_iter iter;

	cache = htable_first(&db->ht, &iter);
	while(cache != NULL) {
		free(cache);
		
		cache = htable_next(&db->ht, &iter);
	}
	
	htable_clear(&db->ht);
	
	return;
}
Beispiel #5
0
void ip_lease_deinit(struct ip_lease_db_st* db)
{
struct ip_lease_st * cache;
struct htable_iter iter;

	cache = htable_first(&db->ht, &iter);
	while(cache != NULL) {
		/* disable the destructor */
		cache->db = NULL;
		talloc_free(cache);
		
		cache = htable_next(&db->ht, &iter);
	}
	htable_clear(&db->ht);
	
	return;
}
Beispiel #6
0
void faup_snapshot_item_free(faup_snapshot_item_t *item)
{
  struct htable_iter iter;
  faup_snapshot_value_count_t *vc;
  
  vc = htable_first(&item->values, &iter);
  while (vc) {
    htable_del(&item->values, hash_string(vc->value), vc);
    faup_snapshot_value_count_free(vc);

    vc = htable_next(&item->values, &iter);
  }

  htable_clear(&item->values);
  
  free(item->key);
  free(item);
}
Beispiel #7
0
void cleanup_client_entries(sec_mod_st *sec)
{
	struct htable *db = sec->client_db;
	client_entry_st *t;
	struct htable_iter iter;
	time_t now = time(0);

	t = htable_first(db, &iter);
	while (t != NULL) {
		if (t->time != -1 && (now - t->time) > (sec->config->cookie_timeout + AUTH_SLACK_TIME) && 
		    t->in_use == 0) {
			htable_delval(db, &iter);
			clean_entry(sec, t);
		}
		t = htable_next(db, &iter);

	}
}
static void dump_firsttouch(void) {
  debug_print("%s", "Dump firsttouch.map\n");

  char path[MAX_PATH];
  snprintf(path, sizeof(path), "%s/%s", dump_path, firsttouch_suffix);

  FILE *ft_map = fopen(path, "w");
  if (!ft_map)
    errx(EXIT_FAILURE, "Could not create %s file : %s\n",
         firsttouch_suffix, strerror(errno));

  struct htable_iter iter;
  ft_entry * t;
  for (t = htable_first(&firsttouch, &iter);
       t;
       t = htable_next(&firsttouch, &iter)) {
    fprintf(ft_map, "%d %lx\n", t->tid, (unsigned long)t->start_of_page);
  }
  fclose(ft_map);
}
Beispiel #9
0
void kmscon_hashtable_free(struct kmscon_hashtable *tbl)
{
	struct htable_iter i;
	struct kmscon_hashentry *entry;

	if (!tbl)
		return;

	for (entry = htable_first(&tbl->tbl, &i);
	     entry;
	     entry = htable_next(&tbl->tbl, &i)) {
		htable_delval(&tbl->tbl, &i);
		if (tbl->free_key)
			tbl->free_key(entry->key);
		if (tbl->free_value)
			tbl->free_value(entry->value);
		free(entry);
	}

	htable_clear(&tbl->tbl);
	free(tbl);
}
Beispiel #10
0
void faup_snapshot_item_debug(faup_snapshot_item_t *item)
{
  struct htable_iter iter;
  faup_snapshot_value_count_t *vc;
  
  if (!item) {
    printf("** item empty, cannot debug!\n");
    return;
  }
  
  printf("** \titem\n");
  printf("** \tkey:%s\n", item->key);
  printf("** \tlength:%ld\n", item->length);

  if (item->length) {
    vc = htable_first(&item->values, &iter);
    while (vc) {
      faup_snapshot_value_count_debug(vc);
      vc = htable_next(&item->values, &iter);
    }
  }
}
Beispiel #11
0
const char *likely_stats(unsigned int min_hits, unsigned int percent)
{
	struct get_stats_info info;
	struct htable_iter i;
	char *ret;
	struct trace *trace;

	if (!htable)
		return NULL;

	info.min_hits = min_hits;
	info.worst = NULL;
	info.worst_ratio = 2;

	/* This is O(n), but it's not likely called that often. */
	for (trace = htable_first(htable, &i);
	     trace;
	     trace = htable_next(htable,&i)) {
		get_stats(trace, &info);
	}

	if (info.worst_ratio * 100 > percent)
		return NULL;

	ret = malloc(strlen(info.worst->condstr) +
		     strlen(info.worst->file) +
		     sizeof(long int) * 8 +
		     sizeof("%s:%u:%slikely(%s) correct %u%% (%lu/%lu)"));
	sprintf(ret, "%s:%u:%slikely(%s) correct %u%% (%lu/%lu)",
		info.worst->file, info.worst->line,
		info.worst->expect ? "" : "un", info.worst->condstr,
		(unsigned)(info.worst_ratio * 100),
		info.worst->right, info.worst->count);

	htable_del(htable, hash_trace(info.worst), info.worst);
	free(info.worst);

	return ret;
}
Beispiel #12
0
static void plain_group_list(void *pool, void *additional, char ***groupname, unsigned *groupname_size)
{
    FILE *fp;
    char line[512];
    ssize_t ll;
    char *p, *sp;
    unsigned i;
    size_t hval;
    struct htable_iter iter;
    char *tgroup[MAX_GROUPS];
    unsigned tgroup_size;
    struct htable hash;
    struct plain_cfg_st *config = additional;

    htable_init(&hash, rehash, NULL);

    pool = talloc_init("plain");
    fp = fopen(config->passwd, "r");
    if (fp == NULL) {
        syslog(LOG_AUTH,
               "error in plain authentication; cannot open: %s",
               (char*)config->passwd);
        return;
    }

    line[sizeof(line)-1] = 0;
    while ((p=fgets(line, sizeof(line)-1, fp)) != NULL) {
        ll = strlen(p);

        if (ll <= 4)
            continue;

        if (line[ll - 1] == '\n') {
            ll--;
            line[ll] = 0;
        }
        if (line[ll - 1] == '\r') {
            ll--;
            line[ll] = 0;
        }

#ifdef HAVE_STRSEP
        sp = line;
        p = strsep(&sp, ":");

        if (p != NULL) {
            p = strsep(&sp, ":");
#else
        p = strtok_r(line, ":", &sp);

        if (p != NULL) {
            p = strtok_r(NULL, ":", &sp);
#endif
            if (p != NULL) {
                break_group_list(pool, p, tgroup, &tgroup_size);

                for (i=0; i<tgroup_size; i++) {
                    hval = rehash(tgroup[i], NULL);

                    if (htable_get(&hash, hval, str_cmp, tgroup[i]) == NULL) {
                        if (strlen(tgroup[i]) > 1)
                            htable_add(&hash, hval, tgroup[i]);
                    }
                }
            }
        }
    }

    *groupname_size = 0;
    *groupname = talloc_size(pool, sizeof(char*)*MAX_GROUPS);
    if (*groupname == NULL) {
        goto exit;
    }

    p = htable_first(&hash, &iter);
    while (p != NULL && (*groupname_size) < MAX_GROUPS) {
        (*groupname)[(*groupname_size)] = talloc_strdup(*groupname, p);
        p = htable_next(&hash, &iter);
        (*groupname_size)++;
    }

    /* always succeed */
exit:
    htable_clear(&hash);
    safe_memset(line, 0, sizeof(line));
    fclose(fp);
    return;
}

const struct auth_mod_st plain_auth_funcs = {
    .type = AUTH_TYPE_PLAIN | AUTH_TYPE_USERNAME_PASS,
    .allows_retries = 1,
    .global_init = plain_global_init,
    .auth_init = plain_auth_init,
    .auth_deinit = plain_auth_deinit,
    .auth_msg = plain_auth_msg,
    .auth_pass = plain_auth_pass,
    .auth_user = plain_auth_user,
    .auth_group = plain_auth_group,
    .group_list = plain_group_list
};
Beispiel #13
0
int main(int argc, char *argv[])
{
	unsigned int i;
	uintptr_t perfect_bit;
	struct htable ht;
	uint64_t val[NUM_VALS];
	uint64_t dne;
	void *p;
	struct htable_iter iter;

	plan_tests(29);
	for (i = 0; i < NUM_VALS; i++)
		val[i] = i;
	dne = i;

	htable_init(&ht, hash, NULL);
	ok1(ht.max == 0);
	ok1(ht.bits == 0);

	/* We cannot find an entry which doesn't exist. */
	ok1(!htable_get(&ht, hash(&dne, NULL), objcmp, &dne));

	/* This should increase it once. */
	add_vals(&ht, val, 0, 1);
	ok1(ht.bits == 1);
	ok1(ht.max == 1);
	ok1(ht.common_mask == -1);

	/* Mask should be set. */
	ok1(check_mask(&ht, val, 1));

	/* This should increase it again. */
	add_vals(&ht, val, 1, 1);
	ok1(ht.bits == 2);
	ok1(ht.max == 3);

	/* Mask should be set. */
	ok1(ht.common_mask != 0);
	ok1(ht.common_mask != -1);
	ok1(check_mask(&ht, val, 2));

	/* Now do the rest. */
	add_vals(&ht, val, 2, NUM_VALS - 2);

	/* Find all. */
	find_vals(&ht, val, NUM_VALS);
	ok1(!htable_get(&ht, hash(&dne, NULL), objcmp, &dne));

	/* Walk once, should get them all. */
	i = 0;
	for (p = htable_first(&ht,&iter); p; p = htable_next(&ht, &iter))
		i++;
	ok1(i == NUM_VALS);

	/* Delete all. */
	del_vals(&ht, val, NUM_VALS);
	ok1(!htable_get(&ht, hash(&val[0], NULL), objcmp, &val[0]));

	/* Worst case, a "pointer" which doesn't have any matching bits. */
	htable_add(&ht, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]);
	htable_add(&ht, hash(&val[NUM_VALS-1], NULL), &val[NUM_VALS-1]);
	ok1(ht.common_mask == 0);
	ok1(ht.common_bits == 0);
	/* Get rid of bogus pointer before we trip over it! */
	htable_del(&ht, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]);

	/* Add the rest. */
	add_vals(&ht, val, 0, NUM_VALS-1);

	/* Check we can find them all. */
	find_vals(&ht, val, NUM_VALS);
	ok1(!htable_get(&ht, hash(&dne, NULL), objcmp, &dne));

	/* Corner cases: wipe out the perfect bit using bogus pointer. */
	htable_clear(&ht);
	htable_add(&ht, 0, (void *)((uintptr_t)&val[NUM_VALS-1]));
	ok1(ht.perfect_bit);
	perfect_bit = ht.perfect_bit;
	htable_add(&ht, 0, (void *)((uintptr_t)&val[NUM_VALS-1]
				   | perfect_bit));
	ok1(ht.perfect_bit == 0);
	htable_del(&ht, 0, (void *)((uintptr_t)&val[NUM_VALS-1] | perfect_bit));

	/* Enlarging should restore it... */
	add_vals(&ht, val, 0, NUM_VALS-1);

	ok1(ht.perfect_bit != 0);
	htable_clear(&ht);

	return exit_status();
}
Beispiel #14
0
/** @brief Handles the closing of the connection **/
inline static void handle_closing_connection ( pntoh_tcp_session_t session , pntoh_tcp_stream_t stream , pntoh_tcp_peer_t origin , pntoh_tcp_peer_t destination , pntoh_tcp_segment_t segment, int who )
{
	static unsigned short count = 0;
	pntoh_tcp_peer_t	peer = origin;
	pntoh_tcp_peer_t	side = destination;
	pntoh_tcp_stream_t	twait = 0;
	ntoh_tcp_key_t		key = 0;

	if ( segment != 0 )
		queue_segment ( session , origin , segment );

	send_peer_segments ( session , stream , destination , origin , origin->next_seq , 0 , 0, who );

	if ( ! origin->segments )
		return;

	if ( count++ < 1 )
	{
		handle_closing_connection ( session , stream , destination , origin , 0, who );
		count = 0;
	}

	if ( stream->status == NTOH_STATUS_CLOSING )
	{
		if ( stream->closedby == NTOH_CLOSEDBY_CLIENT )
		{
			peer = &stream->client;
			side = &stream->server;
		}else{
			peer = &stream->server;
			side = &stream->client;
		}
	}

	/* check segment seq and ack */
    
    if (origin->segments == NULL) 
        return;

	if ( origin->segments->seq == origin->next_seq && origin->segments->ack == destination->next_seq )
	{
		/* unlink the first segment */
		segment = origin->segments;
		origin->segments = segment->next;
	}else
		return;

	switch ( peer->status )
	{
		case NTOH_STATUS_ESTABLISHED:
			if ( ! (segment->flags & TH_FIN) )
				break;

			origin->status = NTOH_STATUS_FINWAIT1;
			destination->status = NTOH_STATUS_CLOSEWAIT;
			stream->status = NTOH_STATUS_CLOSING;

			if ( origin == &stream->client )
				stream->closedby = NTOH_CLOSEDBY_CLIENT;
			else if ( origin == &stream->server )
				stream->closedby = NTOH_CLOSEDBY_SERVER;

			break;

		case NTOH_STATUS_FINWAIT1:
			if ( segment->flags & TH_FIN )
			{
				peer->status = NTOH_STATUS_CLOSING;
				side->status = NTOH_STATUS_LASTACK;
			}else if ( segment->flags & TH_ACK )
				peer->status = NTOH_STATUS_FINWAIT2;
			break;

		case NTOH_STATUS_CLOSING:
			if ( segment->flags & TH_ACK )
			{
				peer->status = NTOH_STATUS_TIMEWAIT;
				side->status = NTOH_STATUS_CLOSED;
				stream->status = NTOH_STATUS_CLOSED;
			}
			break;

		case NTOH_STATUS_FINWAIT2:
			if ( segment->flags & (TH_ACK | TH_FIN) )
			{
				peer->status = NTOH_STATUS_TIMEWAIT;

				if ( segment->flags & TH_FIN )
					side->status = NTOH_STATUS_LASTACK;
				else if ( segment->flags & TH_ACK )
					stream->status = side->status = NTOH_STATUS_CLOSED;
			}
			break;

		case NTOH_STATUS_TIMEWAIT:
			if ( segment->flags & TH_ACK )
				stream->status = side->status = NTOH_STATUS_CLOSED;
			break;
	}

	if ( segment->flags & (TH_FIN | TH_RST) )
		origin->next_seq++;

	free ( segment );

	if ( stream->status != NTOH_STATUS_CLOSED && origin->receive )
		((pntoh_tcp_callback_t)stream->function) ( stream , origin , destination , 0 , NTOH_REASON_SYNC , 0 );

	/* should we add this stream to TIMEWAIT queue? */
	if ( stream->status == NTOH_STATUS_CLOSING && IS_TIMEWAIT(stream->client , stream->server) )
	{
  if ( ! htable_find ( session->timewait , stream->key, 0 ) )
		{
            htable_remove ( session->streams , stream->key, 0 );
			sem_post ( &session->max_streams );

			while ( sem_trywait ( &session->max_timewait ) != 0 )
			{
				key = htable_first ( session->timewait );
				twait = htable_remove ( session->timewait , key, 0 );
				__tcp_free_stream ( session , &twait , NTOH_REASON_SYNC , NTOH_REASON_CLOSED );
			}

			htable_insert ( session->timewait , stream->key , stream );
		}
	}

	return;
}
Beispiel #15
0
void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
{
	SecmListCookiesReplyMsg msg = SECM_LIST_COOKIES_REPLY_MSG__INIT;
	struct htable *db = sec->client_db;
	client_entry_st *t;
	struct htable_iter iter;
	CookieIntMsg *cookies;
	int ret;
	time_t now = time(0);

	if (db == NULL) {
		send_empty_reply(pool, fd, sec);
		return;
	}

	seclog(sec, LOG_DEBUG, "sending list cookies reply to main");

	msg.cookies = talloc_size(pool, sizeof(CookieIntMsg*)*db->elems);
	if (msg.cookies == NULL) {
		send_empty_reply(pool, fd, sec);
		return;
	}

	cookies = talloc_size(pool, sizeof(CookieIntMsg)*db->elems);
	if (cookies == NULL) {
		send_empty_reply(pool, fd, sec);
		return;
	}

	t = htable_first(db, &iter);
	while (t != NULL) {
		if IS_CLIENT_ENTRY_EXPIRED(sec, t, now)
			goto cont;

		if (msg.n_cookies >= db->elems)
			break;

		cookie_int_msg__init(&cookies[msg.n_cookies]);
		cookies[msg.n_cookies].safe_id.data = (void*)t->acct_info.safe_id;
		cookies[msg.n_cookies].safe_id.len = sizeof(t->acct_info.safe_id);

		cookies[msg.n_cookies].session_is_open = t->session_is_open;
		cookies[msg.n_cookies].tls_auth_ok = t->tls_auth_ok;

		if (t->created > 0)
			cookies[msg.n_cookies].created = t->created;
		else
			cookies[msg.n_cookies].created = 0;

		/* a session which is in use, does not expire */
		if (t->exptime > 0 && t->in_use == 0)
			cookies[msg.n_cookies].expires = t->exptime;
		else
			cookies[msg.n_cookies].expires = 0;
		cookies[msg.n_cookies].username = t->acct_info.username;
		cookies[msg.n_cookies].groupname = t->acct_info.groupname;
		cookies[msg.n_cookies].user_agent = t->acct_info.user_agent;
		cookies[msg.n_cookies].remote_ip = t->acct_info.remote_ip;
		cookies[msg.n_cookies].status = t->status;
		cookies[msg.n_cookies].in_use = t->in_use;
		cookies[msg.n_cookies].vhost = VHOSTNAME(t->vhost);

		msg.cookies[msg.n_cookies] = &cookies[msg.n_cookies];
		msg.n_cookies++;

 cont:
		t = htable_next(db, &iter);
	}

	ret = send_msg(pool, fd, CMD_SECM_LIST_COOKIES_REPLY, &msg,
		(pack_size_func) secm_list_cookies_reply_msg__get_packed_size,
		(pack_func) secm_list_cookies_reply_msg__pack);
	if (ret < 0) {
		seclog(sec, LOG_ERR, "Error sending show cookies reply to main");
	}

	talloc_free(msg.cookies);
	talloc_free(cookies);
}