Beispiel #1
0
/* performs an HTTP post to the given URL, with callback */
int
netio_http_post_host(char *host, char *path, char *urlstr, char *content_type, char *data, int data_len,
		     void (*func) (char *url, int respcode, char *data, int data_len, void *pkg),
		     void *pkg) 
{
	addr_t addr;
	int ret = -1;
	struct sockaddr *sa = NULL;
	socklen_t sa_len;
	netio_http_conn_t *http_conn = NULL;

	ASSERT_ZERO(ident_addr_str_to_addr_lookup(host, &addr), err);
	addr.type = IPPROTO_TCP;
	if (addr.port < 1)
		addr.port = 80;
	
	ASSERT_ZERO(ident_addr_addr_to_sa(&addr, &sa, &sa_len), err);
	
	/* new managed api: */
	if ((http_conn = netio_http_wait_new(&addr, urlstr, host, path, content_type, data, data_len, func, pkg))) {
		ship_lock(conns);
		http_conn->socket = netio_man_connto(sa, sa_len, http_conn, __netio_http_cb_conn, __netio_http_cb_data);
		if (http_conn->socket != -1) {
			netio_http_track_conn(http_conn, http_conn->socket);
			ret = 0;
			ship_unlock(http_conn);
		}
		ship_unlock(conns);
	}
err:
	freez(sa);
	return ret;
}
Beispiel #2
0
/* inits the  */
int 
addrbook_init(processor_config_t *config)
{
	ASSERT_ZERO(processor_config_get_string(config, P2PSHIP_CONF_CONTACTS_FILE, &contacts_file), err);
	ASSERT_TRUE(addrbook_lock = ship_list_new(), err);
#ifdef CONFIG_LIBEBOOK_ENABLED
	ASSERT_ZERO(addrbook_libebook_init(), err);
#endif
	return 0;
 err:
	return -1;
}
Beispiel #3
0
int
ac_init(processor_config_t *config)
{
	processor_config_set_dynamic_update(config, P2PSHIP_CONF_AC_MAX_PATH, ac_cb_config_update);
	processor_config_set_dynamic_update(config, P2PSHIP_CONF_AC_HTTP, ac_cb_config_update);
	processor_config_set_dynamic_update(config, P2PSHIP_CONF_PDD_LOG, ac_cb_config_update);
	processor_config_set_dynamic_update(config, P2PSHIP_CONF_PDD_RESET_MODE, ac_cb_config_update);

	ASSERT_TRUE(filters = ship_obj_list_new(), err);

#ifdef DO_STATS
	ac_packetfilter_add(ac_packetfilter_stats, NULL, 1);
#endif
	ac_packetfilter_add(ac_packetfilter_debug, NULL, 1);

	ac_packetfilter_add(ac_packetfilter_simple, NULL, 0);
	ac_packetfilter_add(ac_packetfilter_blacklist, NULL, 0);
	ac_packetfilter_add(ac_packetfilter_whitelist, NULL, 0);
	ac_packetfilter_add(ac_packetfilter_trust, NULL, 0);
#ifdef AC_HTTP_PF
	ac_packetfilter_add(ac_packetfilter_http, NULL, 0);
#endif
#ifdef CONFIG_OP_ENABLED
	ac_packetfilter_add(ac_packetfilter_op, NULL, 0);
#endif

	ac_cb_config_update(config, NULL, NULL);

#ifdef CONFIG_OP_ENABLED
	processor_config_set_dynamic_update(config, P2PSHIP_CONF_IDENT_FILTERING, ac_cb_config_update);
#endif
#ifdef DO_STATS
	ASSERT_TRUE(stats = ship_ht_new(), err);
	ASSERT_TRUE(done_stats = ship_list_new(), err);
	ASSERT_TRUE(done_stats_ht = ship_ht_new(), err);
#endif
	/* whites / blacks */
	ASSERT_TRUE(white_list = ship_ht_new(), err);
	ASSERT_TRUE(black_list = ship_ht_new(), err);

	ASSERT_ZERO(processor_config_get_string(config, P2PSHIP_CONF_WHITELIST_FILE, &wl_file), err);
	ASSERT_ZERO(processor_config_get_string(config, P2PSHIP_CONF_BLACKLIST_FILE, &bl_file), err);

	ASSERT_ZERO(ac_lists_load(white_list, wl_file), err);
	ASSERT_ZERO(ac_lists_load(black_list, bl_file), err);
	
	ident_register_default_service(SERVICE_TYPE_STATS, &ac_stats_service);
	return 0;
 err:
	return -1;
}
Beispiel #4
0
static netio_http_conn_t *
netio_http_conn_new(int socket)
{
	netio_http_conn_t *ret = 0;

	if (socket != -1)
		while ((ret = netio_http_get_conn_by_socket(socket, 1))) {
			ret->owns_socket = 0;
			ship_unlock(ret);
		}

	ASSERT_TRUE(ret = mallocz(sizeof(netio_http_conn_t)), err);
	ret->socket = socket;
	ret->forward_socket = -1;
	ASSERT_ZERO(ship_lock_new(&ret->lock), err);
	netio_http_track_conn(ret, socket);
	ASSERT_TRUE(ret->params = ship_ht_new(), err);
	ASSERT_TRUE(ret->headers = ship_ht_new(), err);

	/* this last! */
	ret->owns_socket = 1;
	return ret;
err:
	netio_http_conn_close(ret);
	return 0;
}
Beispiel #5
0
/* callback for new connections */
static void 
__netio_http_conn_cb(int s, struct sockaddr *sa, socklen_t addrlen, int ss)
{
	netio_http_conn_t *conn = 0;
	LOG_DEBUG("Got connection on netio_http, socket %d (ss: %d)\n", s, ss);

	netio_http_conn_close_all(s);
	ASSERT_TRUE(conn = netio_http_conn_new(s), err);
	ASSERT_ZERO(ident_addr_sa_to_addr(sa, addrlen, &(conn->addr)), err);
	conn->ss = ss;
	ship_unlock(conn);
	ASSERT_ZERO(netio_read(s, __netio_http_conn_read_cb), err);
	return;
 err:
	netio_http_conn_close(conn);
}
Beispiel #6
0
/* modifies the port / host the server is listening to */
static int
__netio_http_server_listen(char *new_address)
{
	struct sockaddr *sa = 0;
	socklen_t salen;
	int ret = -1;
	char buf[1024];

	ASSERT_ZERO(ident_addr_str_to_sa(new_address, &sa, &salen), err);
	ASSERT_ZERO(ident_addr_sa_to_str(sa, salen, buf), err);
	LOG_INFO("Using %s for HTTP server\n", buf);
	
	ASSERT_TRUE((ret = netio_new_listener(sa, salen, __netio_http_conn_cb)) != -1, err);
	freez(sa);
 err:
	freez(sa);
	return ret;
}
Beispiel #7
0
/* loads / saves a white / black list */
static int
ac_lists_load(ship_ht_t *list, char *filename)
{
	int ret = -1;
	ASSERT_ZERO(ship_read_file(filename, list, _ac_lists_load_cb, NULL), err);
	ret = 0;
 err:
	return ret;
}
Beispiel #8
0
/* 
   Creates a new media proxy

   callid, local_aor, remote_aor should be clear
   mediatype is the mediatype (currently not used..)
   bindaddr is the address on which we should bind the listener
   targetaddr is where the media should be sent
   sendby indicates whether direct / through tunnel

 */
sipp_media_proxy_t *
sipp_mp_create_new(char *callid, char *local_aor, char *remote_aor, char *mediatype, 
                   addr_t *bindaddr, addr_t *targetaddr, int sendby)
{
        sipp_media_proxy_t *ret;
        struct sockaddr *sa = NULL;
        socklen_t size;

        ASSERT_TRUE(ret = (sipp_media_proxy_t *)mallocz(sizeof(sipp_media_proxy_t)), err);
        ASSERT_TRUE(ret->callid = strdup(callid), err);
        ASSERT_TRUE(ret->mediatype = strdup(mediatype), err);
	ret->sendby = sendby;
        time(&ret->last);

	memcpy(&(ret->local_addr), bindaddr, sizeof(addr_t));

        ASSERT_TRUE(ret->sip_aor = strdup(local_aor), err);
        ASSERT_TRUE(ret->remote_aor = strdup(remote_aor), err);
        if (targetaddr) {
		memcpy(&(ret->remote_addr), targetaddr, sizeof(addr_t));
        } else {
		bzero(&(ret->remote_addr), sizeof(addr_t));
	}

	/* todo: this doesn't work for tcp or anything else */
	ASSERT_TRUE(ret->local_addr.type == IPPROTO_UDP, err);
	ASSERT_ZERO(ident_addr_addr_to_sa(&(ret->local_addr), &sa, &size), err);
	ret->socket = netio_new_packet_socket(sa, size);
        if (ret->socket == -1)
                goto err;
	
	ASSERT_ZERO(getsockname(ret->socket, sa, &size), err);
	ASSERT_ZERO(ident_addr_sa_to_addr(sa, size, &(ret->local_addr)), err);
	ret->local_addr.type = IPPROTO_UDP;

	ship_list_add(sipp_mps, ret);

	freez(sa);
        return ret;
 err:
	freez(sa);
        sipp_mp_close(ret);
        return 0;
}
Beispiel #9
0
/* retrieve a list of contacts from the address book */
static int
addrbook_libebook_retrieve(ship_list_t *list)
{
	int ret = -1;
	contact_t *ct = 0;
	GError *error = 0;
	GList *contacts = 0, *loop;
	EBookQuery *query = 0;

	ship_lock(addrbook_lock);
	ASSERT_TRUE(query = e_book_query_any_field_contains(""), err);
	ASSERT_TRUE(e_book_get_contacts(book, query, &contacts, &error), err);
	ASSERT_ZERO(error, err);

	for (loop = contacts; loop; loop = g_list_next(loop)) {
		EContact *c = loop->data;
		char *name = 0;
		
		name = e_contact_get(c, E_CONTACT_OSSO_CONTACT_STATE);
		if (!name || strcmp(name, "DELETED")) {
			char **arrs = 0;

			ASSERT_TRUE(ct = ident_contact_new(), cerr);
			ASSERT_TRUE(ct->name = e_contact_get(c, E_CONTACT_FULL_NAME), cerr);
			
			ASSERT_TRUE(arrs = e_contact_get(c, E_CONTACT_SIP), cerr);
			ASSERT_TRUE(ct->sip_aor = addrbook_normalize_aor(arrs[0]), cerr);
			
			/* apparently arrs doesn't need to be free'd afterwards */
			g_list_foreach((GList*)arrs, (GFunc)g_free, NULL);
			ship_list_add(list, ct);
			ct = 0;
		cerr:
			ident_contact_free(ct);
		}
		if (name)
			g_free(name);
	}
	ret = 0;
 err:
	if (contacts) {
		g_list_free(contacts);
	}
	
	if (query) {
		e_book_query_unref(query);
	}

	if (error) {
		LOG_ERROR("Error getting contacts: %s\n", error->message);
		g_error_free(error);
	}
	ship_unlock(addrbook_lock);

	return ret;
}
Beispiel #10
0
netio_http_conn_t*
netio_http_parse_data(char *data, int datalen)
{
	netio_http_conn_t *ret = 0;
	ASSERT_TRUE(ret = netio_http_conn_new(-1), err);
	ASSERT_ZERO(__netio_http_parse_data(ret, data, datalen), err);
	return ret;
 err:
	netio_http_conn_close(ret);
	return 0;
}
Beispiel #11
0
static int 
pdd_record_pdd(pdd_stat_t *stat)
{
	char *tmp = 0, *filename = 0;
	int ret = -1;
	FILE *f = NULL;
	
	int total = stat->end - stat->start, 
		lookup = stat->lookup_done - stat->lookup_start, 
		connect = stat->connect_done - stat->connect_start,
		auth = (stat->connect_done? stat->sip_sent - stat->connect_done : 0),
		remote = stat->remote_done - stat->remote_start;
	
	/* create the file name .. */
	ASSERT_ZERO(ship_get_homedir_file(PDD_LOG_FILE, &filename), err);
	ASSERT_ZERO(ship_ensure_file(filename, 
				     "From, To, Message type, Dot, Total, Lookup, Connect, Auth, Remote, Misc\n"),
		    err);

	ASSERT_TRUE(tmp = mallocz(strlen(stat->from) + strlen(stat->to) + strlen(stat->msg_type) + 128), err);
	sprintf(tmp, "%s, %s, %s, %d, %u, %u, %u, %u, %u, %u\n",
		stat->from, stat->to, stat->msg_type, (int)stat->created, 
		total, lookup, connect, auth, remote,
		(int)(total - lookup - connect - auth - remote));
	
	if ((f = fopen(filename, "a"))) {
		fwrite(tmp, sizeof(char), strlen(tmp), f);
		fclose(f);
	}
	
	LOG_INFO("recorded PDD into csv file %s..\n", filename);
	ret = 0;
 err:
	if (ret) {
		LOG_ERROR("could not record PDD: %d\n", ret);
	}

	freez(tmp);
	freez(filename);
	return ret;
}
Beispiel #12
0
static ac_sip_t*
ac_sip_new(sipp_request_t *req, ac_packetfilter_cb func)
{	
	ac_sip_t* ret = 0;

	ASSERT_TRUE(ret = mallocz(sizeof(ac_sip_t)), err);
	ASSERT_TRUE(ret->req = req, err);
	ASSERT_TRUE(ret->cb_func = func, err);
	ASSERT_TRUE(ret->filters = ship_obj_list_new(), err);
	
	ASSERT_ZERO(sipp_get_sip_aors(req->evt->sip, &ret->from, &ret->to, 0), err);
	ret->verdict = AC_VERDICT_NONE;
	return ret;
 err:
	ac_sip_free(ret);
	return 0;
}
Beispiel #13
0
static void
ac_cb_config_update(processor_config_t *config, char *k, char *v)
{
#ifdef DO_STATS
	processor_config_get_bool(config, P2PSHIP_CONF_PDD_RESET_MODE, &pdd_reset_mode);
	processor_config_get_bool(config, P2PSHIP_CONF_PDD_LOG, &pdd_log);
#endif
#ifdef CONFIG_OP_ENABLED
	processor_config_get_enum(config, P2PSHIP_CONF_IDENT_FILTERING, &op_filtering);
#endif
	ASSERT_ZERO(processor_config_get_int(config, P2PSHIP_CONF_AC_MAX_PATH, &max_path), err);
#ifdef AC_HTTP_PF
	freez(http_ac);
	ASSERT_TRUE((http_ac = strdup(processor_config_string(config, P2PSHIP_CONF_AC_HTTP))), err);
#endif
	return;
 err:
	PANIC();
}
Beispiel #14
0
int test1() {
    int child = fork();
    int i;
    data_t* smem;
    pid_t mypid;
    int cooloffs = 5;
    sched_param_t params = {1, 50, cooloffs};
    int status;
    int counter = 0;
        
    if (child != 0) {
        smem = (data_t*)make_shared(sizeof(data_t), 1);
        smem->curr = 0;
        
        mypid = getpid();
        ASSERT_POSITIVE(mypid);
        
        nice(1); // be nicer than child
        ASSERT_ZERO(sched_setscheduler(mypid, SCHED_SHORT, &params));
        ASSERT_EQUALS(sched_setscheduler(mypid, SCHED_SHORT, &params), -1);
        ASSERT_EQUALS(errno, EPERM);
        ASSERT_EQUALS(is_SHORT(mypid), 1);
        
        smem->arr[smem->curr] = FATHER+0; // init value
        
        ASSERT_ZERO(sched_setscheduler(child, SCHED_SHORT, &params)); // now we lost control until child will be overdue
        
        // child got into overdue. we gained control again. we should still be short here.
        smem->arr[++smem->curr] = FATHER+1;
        
        while (is_SHORT(mypid)) ;
        smem->arr[++smem->curr] = FATHER+(1*10)+OVERDUE_PERIOD; // got into first overdue period
        ASSERT_EQUALS(remaining_cooloffs(mypid), cooloffs-1);
        
        for (i = 1; i <= cooloffs; ++i) {
            while (!is_SHORT(mypid)) ;
            smem->arr[++smem->curr] = FATHER+(i*10); // got out of overdue period
            ASSERT_EQUALS(remaining_cooloffs(mypid), cooloffs-i);
            while (is_SHORT(mypid)) ;
            smem->arr[++smem->curr] = FATHER+((i+1)*10)+OVERDUE_PERIOD; // got into overdue period
            ASSERT_EQUALS(remaining_cooloffs(mypid), max(cooloffs-(i+1), 0));
        }
        
        // now should be overdue forever
        ASSERT_ZERO(remaining_cooloffs(mypid));
        
        waitpid(child, &status, 0);
        
        // use `gcc -DVERBOSE ...` in order to print the array state
        if (IS_VERBOSE()) {
            for (i = 0; i <= 24; i++) {
                printf("%d:\t%d\n", i, smem->arr[i]);
            }
        }
        
        // check array
        ASSERT_EQUALS(smem->arr[0], FATHER+0);
        ASSERT_EQUALS(smem->arr[1], SON+0);
        ASSERT_EQUALS(smem->arr[2], FATHER+1);
        ASSERT_EQUALS(smem->arr[3], SON+10+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[4], SON+10);
        ASSERT_EQUALS(smem->arr[5], FATHER+10+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[6], FATHER+10);
        ASSERT_EQUALS(smem->arr[7], SON+20+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[8], SON+20);
        ASSERT_EQUALS(smem->arr[9], FATHER+20+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[10], FATHER+20);
        ASSERT_EQUALS(smem->arr[11], SON+30+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[12], SON+30);
        ASSERT_EQUALS(smem->arr[13], FATHER+30+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[14], FATHER+30);
        ASSERT_EQUALS(smem->arr[15], SON+40+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[16], SON+40);
        ASSERT_EQUALS(smem->arr[17], FATHER+40+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[18], FATHER+40);
        ASSERT_EQUALS(smem->arr[19], SON+50+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[20], SON+50);
        ASSERT_EQUALS(smem->arr[21], FATHER+50+OVERDUE_PERIOD);
        ASSERT_EQUALS(smem->arr[22], FATHER+50);
        ASSERT_EQUALS(smem->arr[23], SON+60+OVERDUE_PERIOD);    // son finished
        ASSERT_EQUALS(smem->arr[24], FATHER+60+OVERDUE_PERIOD);
        
        return 1;
        
    } else {
        pid_t mypid = getpid();
        ASSERT_POSITIVE(mypid);
		
        while (is_SHORT(mypid) != 1) ;

        data_t* smem = (data_t*)make_shared(sizeof(data_t), 0);
        
        smem->arr[++smem->curr] = SON+0; // this is the first SHORT time slice
        
        while (is_SHORT(mypid)) ;
        smem->arr[++smem->curr] = SON+(1*10)+OVERDUE_PERIOD; // got into first overdue period

        ASSERT_EQUALS(remaining_cooloffs(mypid), cooloffs-1);

        for (i = 1; i <= cooloffs; ++i) {
            while (!is_SHORT(mypid)) ;

            smem->arr[++smem->curr] = SON+(i*10); // got out of overdue period
            ASSERT_EQUALS(remaining_cooloffs(mypid), cooloffs-i);
            while (is_SHORT(mypid)) ;
 
            smem->arr[++smem->curr] = SON+((i+1)*10)+OVERDUE_PERIOD; // got into overdue period
            ASSERT_EQUALS(remaining_cooloffs(mypid), max(cooloffs-(i+1), 0));
        }
        
        // now should be overdue forever
        ASSERT_ZERO(remaining_cooloffs(mypid));
        
        exit(0);
    }

    return 0;
}
Beispiel #15
0
/* callback when data is got */
static void 
__netio_http_conn_read_cb(int s, char *data, ssize_t datalen) 
{
	netio_http_conn_t *conn = 0;
	int ret = -1;
	char *newbuf = NULL;

	ASSERT_TRUE(conn = netio_http_get_conn_by_socket(s, 1), err);
	if (datalen < 1) {
		goto err;
	}


	// todo: some sort of half- ready handling #connect
	// forward-tunnel also!!
	if (conn->forward_socket != -1) {
		if (datalen > 0) {
			netio_send(conn->forward_socket, data, datalen);
			ret = 1;
		}
	} else if (conn->service_forward_service) {
		int l2;

		/* add tracking id to buffer */
		l2 = datalen + strlen(conn->tracking_id) + 1;
		ASSERT_TRUE(newbuf = mallocz(l2+1), err);
		strcpy(newbuf, conn->tracking_id);
		strcat(newbuf, "\n");
			
		memcpy(newbuf+strlen(newbuf), data, datalen);
		ASSERT_ZERO(conn_send_slow(conn->service_forward_to, conn->service_forward_from, 
					   conn->service_forward_service,
					   newbuf, l2, NULL, NULL), 
			    err);
		ret = 1;
	} else if (datalen > 0) {
		ret = __netio_http_parse_data(conn, data, datalen);
	}

	/* process.. */
	while (!ret) {
		netio_http_conn_t *new_conn = 0;

		ret = __netio_http_process_req(conn); // should ret be checked??
		if (!strcmp(conn->method, "CONNECT"))
			break;

		if (!strcmp(conn->http_version, "HTTP/1.0")) {
			ret = -1;
			goto err;
		}

		/* we create a new conn for this socket as there might
		   be another request coming. This instead of clearing
		   the one as .. the http proxy will close the http_conn if
		   after responding to just one request.
		*/
		netio_http_cut_overrun(conn, &data, &datalen);
		ship_unlock(conn);
		
		ASSERT_TRUE(new_conn = netio_http_conn_new(s), err);
		memcpy(&(new_conn->addr), &(conn->addr), sizeof(addr_t));
		new_conn->ss = conn->ss;
		conn->owns_socket = 0;

		/* ..parse the data at this point, it IS pointing at
		   the buffer in the old conn! */
		if (datalen > 0)
			ret = __netio_http_parse_data(new_conn, data, datalen);
		else
			ret = 1;
		ship_unlock(new_conn);

		netio_http_conn_lock(conn);
		if (ret < 1) {
			netio_http_conn_close(conn);
		} else {
			ship_unlock(conn);
		}
		netio_http_conn_lock(new_conn);
		conn = new_conn;
	}
 err:
	if (ret < 1) {
		netio_http_conn_close(conn);
	} else if (conn) {
		ship_unlock(conn);
	}
}
Beispiel #16
0
/* dumps the current status of all mediaproxies as a json blob */
int
sipp_mp_dump_json(char **msg)
{
	int buflen = 0, datalen = 0;
	char *buf = 0;
	void *ptr = 0, *ptr2 = 0;
        sipp_media_proxy_t *mp = NULL;
	char *tmpaddr1 = 0, *tmpaddr2 = 0, *tmp = 0;
	ship_list_t *callids = 0;
	char *str = 0;
	int ret = -1;
	ship_lock(sipp_mps);
	
	/* collect callids */
	ASSERT_TRUE(callids = ship_list_new(), err);
	while ((mp = ship_list_next(sipp_mps, &ptr))) {
		int found = 0;
		while (!found && (str = ship_list_next(callids, &ptr2))) {
			if (!strcmp(str, mp->callid))
				found = 1;
		}
		
		if (!found) {
			ship_list_add(callids, mp->callid);
		}
	}
	
	/* for each call id .. */
	ASSERT_TRUE(buf = append_str("var p2pship_mps = {\n", buf, &buflen, &datalen), err);
	ptr2 = 0;
	while ((str = ship_list_next(callids, &ptr2))) {
		ASSERT_TRUE(buf = append_str("     \"", buf, &buflen, &datalen), err);
		ASSERT_TRUE(buf = append_str(str, buf, &buflen, &datalen), err);
		ASSERT_TRUE(buf = append_str("\" : [\n", buf, &buflen, &datalen), err);

		ptr = 0;
		while ((mp = ship_list_next(sipp_mps, &ptr))) {
			int len = 0;
			
			if (!strcmp(mp->callid, str)) {
				ASSERT_ZERO(ident_addr_addr_to_str(&(mp->local_addr), &tmpaddr1), err);
				ASSERT_ZERO(ident_addr_addr_to_str(&(mp->remote_addr), &tmpaddr2), err);
				
				len = zstrlen(mp->sip_aor) + zstrlen(tmpaddr1) + zstrlen(mp->remote_aor) + zstrlen(tmpaddr2) + 
					zstrlen(mp->callid) + zstrlen(mp->mediatype) + 512;
				ASSERT_TRUE(tmp = mallocz(len), err);
				
				sprintf(tmp, "         [ \"%s\", \"%s\", \"%s\", \"%s\", \"%s\",\n           \"%s\", \"%s\", \"%d\", \"%d\", \"%d\", \"%d\" ],\n",
					mp->sip_aor, tmpaddr1, mp->remote_aor, tmpaddr2, sipp_mp_sendby_str(mp->sendby),
					mp->callid, mp->mediatype,
					mp->started, (int)mp->start_time, (int)mp->last, mp->counter);
				
				ASSERT_TRUE(buf = append_str(tmp, buf, &buflen, &datalen), err);
				freez(tmp);
				freez(tmpaddr1);
				freez(tmpaddr2);
			}
		}
		ASSERT_TRUE(replace_end(buf, &buflen, &datalen, ",\n", "\n"), err);
		ASSERT_TRUE(buf = append_str("     ],\n", buf, &buflen, &datalen), err);
	}

	ASSERT_TRUE(replace_end(buf, &buflen, &datalen, ",\n", "\n"), err);
	ASSERT_TRUE(buf = append_str("};\n", buf, &buflen, &datalen), err);
	*msg = buf;
	buf = 0;
	ret = 0;
 err:
	ship_unlock(sipp_mps);
	ship_list_free(callids);
	freez(buf);
	freez(tmpaddr1);
	freez(tmpaddr2);
	freez(tmp);
	return ret;
}
Beispiel #17
0
/* starts the media proxy */
int 
sipp_mp_start(sipp_media_proxy_t *mp, int remotely_got)
{
	sipp_media_proxy_t *mp2;
	void *ptr = NULL, *lastptr = NULL;

	sipp_mp_autoclean();

       	/* remove possible loops */

        ship_lock(sipp_mps);
	while ((mp2 = ship_list_next(sipp_mps, &ptr))) {
		if (!ident_addr_cmp(&mp->local_addr, &mp2->remote_addr)) {
			LOG_WARN("mediaproxy loop detected! local will be changed!\n");
			memcpy(&mp->local_addr, &mp2->local_addr, sizeof(addr_t));
		} else if (!ident_addr_cmp(&mp->remote_addr, &mp2->local_addr)) {
			LOG_WARN("mediaproxy loop detected! remote will be changed!\n");
			memcpy(&mp->remote_addr, &mp2->remote_addr, sizeof(addr_t));
		} else
			mp2 = NULL;

		if (mp2) {
			ship_list_remove(sipp_mps, mp2);
			sipp_mp_close(mp2);
			ptr = lastptr;
		}
		lastptr = ptr;
	}
	ship_unlock(sipp_mps);


	LOG_INFO("starting mp (type %d) for %s (%s:%d -> %s:%d)..\n", 
		 mp->sendby, mp->sip_aor, 
                 mp->local_addr.addr, mp->local_addr.port,
                 mp->remote_addr.addr, mp->remote_addr.port);

	if (remotely_got && sipp_mp_supports_fragmentation(mp->remote_aor, &(mp->remote_addr))) {
		mp->frag_support = 1;
		LOG_DEBUG("detected fragmentation-aware endpoint at %s:%d!\n",
			  mp->remote_addr.addr, mp->remote_addr.port);
	}
	
	/* start reading packets */
	switch (mp->sendby) {
	case SIPP_MP_SENDBY_DIRECT:
#ifdef USE_FF_DIRECT
		ASSERT_ZERO(netio_ff_add(mp->socket, &(mp->remote_addr), &(mp->counter),
					 mp->frag_support), err);
		break;
#endif
	default:
		ASSERT_ZERO(netio_packet_read(mp->socket, sipp_mp_cb_data_got), err);
	}
	
	mp->started = 1;
	time(&mp->start_time);

	if (!remotely_got) {
		LOG_DEBUG("sending fragmentation-support flag for the proxy at %s:%d\n", 
			  mp->local_addr.addr, mp->local_addr.port);
		
		sipp_mp_notify_fragmentation_support(mp);
	}
	return 0;
 err:
	return -1;
}
Beispiel #18
0
/* returns 0 = done, ok. 1 = not done yet, -1 = error */
static int 
__netio_http_parse_data(netio_http_conn_t* conn, char *data, int datalen)
{
	/* collect data. */
	if (!conn->buf || (conn->buf_len - conn->data_len < datalen)) {
		int ns = conn->buf_len + datalen + 1024;
		char *tmp = 0;
		ASSERT_TRUE(tmp = mallocz(ns+1), err);
		if (conn->buf)
			memcpy(tmp, conn->buf, conn->data_len);
		freez(conn->buf);
		conn->buf = tmp;
		conn->buf_len = ns;
	}
	
	if (datalen > 0) {
		memcpy(conn->buf + conn->data_len, data, datalen);
		conn->data_len += datalen;
	}

	/* check if we have the header, parse url & datalen (if present) */
	if (!conn->header_got && strstr(conn->buf, "\r\n\r\n")) {
		char *line = conn->buf, *le;
		
		conn->header_got = 1;
		conn->header_len = strstr(conn->buf, "\r\n\r\n") - conn->buf + 4;
		do {
			le = strstr(line, "\r\n");
			if (le == line)
				break;

			if (str_startswith(line, "POST") || 
			    str_startswith(line, "GET") ||  
			    str_startswith(line, "OPTIONS") ||  
			    str_startswith(line, "HEAD") ||  
			    str_startswith(line, "PUT") ||  
			    str_startswith(line, "DELETE") ||  
			    str_startswith(line, "TRACE") ||  
			    str_startswith(line, "CONNECT")) {
				/* requests! */
				char *tmple;
				
				/* store method */
				if ((tmple = strchr(line, ' '))) {
					char *t2;
					tmple++;
					
					freez(conn->url); freez(conn->http_version);
					if (le) {
						t2 = le;
						while ((t2 > tmple) && *t2 != ' ')
							t2--;
					} else 
						t2 = strrchr(tmple, ' ');
					if (t2) {
						conn->url = strndup(tmple, t2-tmple);
						conn->http_version = trim(strndup(t2, le-t2));
					} else {
						conn->url = strndup(tmple, le-tmple);
					}
					freez(conn->method);
					conn->method = strndup(line, tmple-line);
					trim(conn->method);
					trim(conn->url);
				}
			} else if (str_startswith(line, "HTTP")) {
				/* for responses! */
				freez(conn->resp_code_line);
				conn->resp_code_line = trim(strndup(line, le-line));
				if (strchr(line, ' '))
					conn->resp_code = atoi(strchr(line, ' ')+1);
			} else {
				/* generic parameter */
				char *tmple = strchr(line, ':');

				if (str_startswith(line, "Content-Length: ")) {
					conn->content_len = atoi(strchr(line, ' ') + 1);
				}

				if (tmple) {
					char *val = strndup(tmple+1, le-tmple+1);
					char *key = strndup(line, tmple-line);
					
					netio_http_set_header(conn, key, val);
					freez(val);
					freez(key);
				}
			}
			if (le)
				line = le+2;
		} while (le);
	}

	/* process data.. */
	if (conn->header_got && 
	    ((conn->content_len == -1 && datalen < 1) || 
	     (conn->content_len != -1 && (conn->content_len <= (conn->data_len - conn->header_len))))) {

		if (conn->content_len == -1) {
			conn->content_len = conn->data_len - conn->header_len;
		}
		
		if (conn->method) {
			LOG_DEBUG("Got total %d bytes, %d bytes data for %s on http\n",
				  conn->data_len, conn->content_len, conn->url);
			
			/* treat multipart & 'normal' posts differently */
			if (!strcmp(conn->method, "POST") && 
			    str_startswith(netio_http_get_header(conn, "Content-Type"), "multipart")) {
				char *bound, *ps, *pe;
				bound = strstr_after(netio_http_get_header(conn, "Content-Type"), "boundary=");

				/* go through parts one-by-one, parsing name & data */
				if (bound) {
					ps = memmem_after(&conn->buf[conn->header_len], conn->data_len - conn->header_len, bound, strlen(bound));
					while (ps) {
						char *tmp, *name, *tmp2 = 0;
						pe = (char*)memmem(ps, conn->data_len - (ps-conn->buf), bound, strlen(bound));
						if (!pe) {
							pe = conn->buf + conn->data_len;
							tmp = 0;
						} else
							tmp = pe + strlen(bound);

						if ((name = strstr(ps, "Content-Disposition: ")))
							tmp2 = strstr(name, "\r\n");
						ps = strstr_after(ps, "\r\n\r\n");
						if (ps && name && tmp2) {
							tmp2[0] = 0;
							if ((name = strstr_after(name, "name=\"")) &&
							    (tmp2 = strchr(name, '"'))) {
								int datalen = pe-ps-4;
								ASSERT_ZERO(netio_http_conn_set_param(conn, name, tmp2-name, ps, datalen), err);
							}
						}
						ps = tmp;
					}
				}
			} else {
				int parsedata = conn->header_len;
				char *ns;

				ns = &(conn->buf[parsedata]);
				
				/* if get, set parsedata to the url's first ?-char */
				if (!strcmp(conn->method, "GET")) {
					char *params = strchr(conn->url, '?');
					if (params) {
						params[0] = 0;
						ns = params+1;
						conn->url_extras = strdup(ns);
					}
				}

				while (ns) {
					char *tmp = 0, *pe = 0;
					char *ps = strchr(ns, '=');
					if (ps) {
						pe = strchr(ps, '&');
						if (!pe) {
							pe = ps + strlen(ps);
							tmp = 0;
						} else
							tmp = pe+1;
					}
					if (ps) {
						char *k = strndup(ns, ps-ns);
						char *v = strndup(ps+1, pe-ps-1);
						if (k && v) {
							ship_urldecode(k);
							ship_urldecode(v);
							ASSERT_ZERO(netio_http_conn_set_param(conn, k, strlen(k), v, strlen(v)), err);
						}
						freez(k); 
						freez(v);
					}
					ns = tmp;
				}
			}
		}
		
		/* ..and we're done! */
		if (conn->url) {
			conn->original_url = conn->url;
			conn->url = strdup(conn->original_url);
			ship_urldecode(conn->url);
		}
		return 0;
	} else if (datalen < 1)
		goto err;
	
	return 1;
 err:
	return -1;
}
Beispiel #19
0
/* point-of-entry */
int 
main(int argc, char **argv)
{
	int ret = -1, c, index, action = ACTION_NONE, tmp;
	char *action_param = NULL;
        processor_config_t *config = 0, *config2 = 0;
	char *conf_file = 0;
	int load_autoreg = 0;
	int flag_quiet = 0;
	int log_to_file = 0;
	int console_only = 0;
	int do_test = 0; // do whatever the test of the day is

	xmlInitParser();
	xmlInitThreads();
	//initGenericErrorDefaultFunc((xmlGenericErrorFunc *)xml_error_func);

        /* the getopt values */
        static struct option long_options[] =
                {                        
                        {"verbose", no_argument, 0, 0},
                        {"iface", required_argument, 0, 0},
                        {"threads", required_argument, 0, 0},
                        {"help", no_argument, 0, 0},
                        {"version", no_argument, 0, 0},
                        {"console", no_argument, 0, 0},
#ifdef CONFIG_PYTHON_ENABLED
                        {"shell", no_argument, 0, 0},
                        {"run", required_argument, 0, 0},
                        {"no-scripts", no_argument, 0, 0},
#endif
#ifdef CONFIG_SIP_ENABLED
                        {"proxy-iface", required_argument, 0, 0},
                        {"no-mp", no_argument, 0, 0},
                        {"tunnel-mp", no_argument, 0, 0},
                        {"force-mp", no_argument, 0, 0},
                        {"allow-unknown", no_argument, 0, 0},
                        {"allow-untrusted", no_argument, 0, 0},
#endif
                        {"list-ca", no_argument, 0, 0},
                        {"import-ca", required_argument, 0, 0},
                        {"remove-ca", required_argument, 0, 0},
                        {"list", no_argument, 0, 0},
                        {"import", required_argument, 0, 0},
                        {"remove", required_argument, 0, 0},
                        {"idents", required_argument, 0, 0},
                        {"log", required_argument, 0, 0},
#ifdef CONFIG_BROADCAST_ENABLED
                        {"bc-addr", required_argument, 0, 0},
#endif
#ifdef CONFIG_WEBCONF_ENABLED
                        {"webconf", required_argument, 0, 0},
#endif
#ifdef CONFIG_OPENDHT_ENABLED
                        {"opendht", required_argument, 0, 0},
#endif
#ifdef CONFIG_HIP_ENABLED
                        {"list-hits", no_argument, 0, 0},
                        {"rvs", required_argument, 0, 0},
                        {"provide-rvs", no_argument, 0, 0},
#endif
                        {0, 0, 0, 0}
                };        

#ifdef LOCK_DEBUG
	debug2_init();
#endif
#ifdef REF_DEBUG2
	ship_debug_initref();
#endif


	if (!(config = processor_config_new()) || !(config2 = processor_config_new())) {
                USER_ERROR("Error loading application\n");
		goto err;
	}

	if (processor_config_load_defaults(config2)) {
                USER_ERROR("Error loading default configurations\n");
                goto err;
	}
	processor_config_get_string(config2, P2PSHIP_CONF_CONF_FILE, &conf_file);

        opterr = 0;
        while ((c = getopt_long(argc, argv, "LqvhDVs:c:p:i:Rr:kKt", long_options, &index)) != -1) {
                
                if (!c) {
                        if (!strcmp(long_options[index].name, "threads")) {
				processor_config_set_int(config, P2PSHIP_CONF_WORKER_THREADS, atoi(optarg));
                        } else if (!strcmp(long_options[index].name, "help")) {
                                c = '?';
                        } else if (!strcmp(long_options[index].name, "version")) {
                                c = 'V';
                        } else if (!strcmp(long_options[index].name, "verbose")) {
                                c = 'v';
                        } else if (!strcmp(long_options[index].name, "iface")) {
                                c = 'i';
                        } else if (!strcmp(long_options[index].name, "console")) {
				console_only = 1;
#ifdef CONFIG_PYTHON_ENABLED
                        } else if (!strcmp(long_options[index].name, "shell")) {
				processor_config_set_true(config, P2PSHIP_CONF_START_SHELL);
                        } else if (!strcmp(long_options[index].name, "run")) {
				processor_config_set_string(config, P2PSHIP_CONF_RUN_SCRIPT, optarg);
                        } else if (!strcmp(long_options[index].name, "no-scripts")) {
				processor_config_set_false(config, P2PSHIP_CONF_STARTUP_SCRIPTS);
#endif
#ifdef CONFIG_SIP_ENABLED
                        } else if (!strcmp(long_options[index].name, "proxy-iface")) {
				processor_config_set_string(config, P2PSHIP_CONF_SIPP_PROXY_IFACES, optarg);
                        } else if (!strcmp(long_options[index].name, "no-mp")) {
				processor_config_set_string(config, P2PSHIP_CONF_SIPP_MEDIA_PROXY, "no");
                        } else if (!strcmp(long_options[index].name, "tunnel-mp")) {
				processor_config_set_string(config, P2PSHIP_CONF_SIPP_TUNNEL_PROXY, "yes");
                        } else if (!strcmp(long_options[index].name, "force-mp")) {
				processor_config_set_string(config, P2PSHIP_CONF_SIPP_FORCE_PROXY, "yes");
                        } else if (!strcmp(long_options[index].name, "allow-unknown")) {
				processor_config_set_string(config, P2PSHIP_CONF_IDENT_ALLOW_UNKNOWN_REGISTRATIONS, "yes");
                        } else if (!strcmp(long_options[index].name, "allow-untrusted")) {
				processor_config_set_string(config, P2PSHIP_CONF_IDENT_ALLOW_UNTRUSTED, "yes");
#endif
                        } else if (!action && !strcmp(long_options[index].name, "list-ca")) {
				action = ACTION_LIST_CA;
                        } else if (!action && !strcmp(long_options[index].name, "remove-ca")) {
				action = ACTION_REMOVE_CA;
				if (!action_param) action_param = strdup(optarg);
                        } else if (!action && !strcmp(long_options[index].name, "import-ca")) {
				action = ACTION_IMPORT_CA;
				if (!action_param) action_param = strdup(optarg);
			} else if (!action && !strcmp(long_options[index].name, "list")) {
				action = ACTION_LIST;
                        } else if (!action && !strcmp(long_options[index].name, "remove")) {
				action = ACTION_REMOVE;
				if (!action_param) action_param = strdup(optarg);
                        } else if (!action && !strcmp(long_options[index].name, "import")) {
				action = ACTION_IMPORT;
				if (!action_param) action_param = strdup(optarg);
                        } else if (!strcmp(long_options[index].name, "idents")) {
				processor_config_set_string(config, P2PSHIP_CONF_IDENTS_FILE, optarg);
                        } else if (!strcmp(long_options[index].name, "log")) {
				processor_config_set_string(config, P2PSHIP_CONF_LOG_FILE, optarg);
#ifdef CONFIG_BROADCAST_ENABLED
                        } else if (!strcmp(long_options[index].name, "bc-addr")) {
				processor_config_set_string(config, P2PSHIP_CONF_BC_ADDR, optarg);
#endif
#ifdef CONFIG_OPENDHT_ENABLED
                        } else if (!strcmp(long_options[index].name, "opendht")) {
				processor_config_set_string(config, P2PSHIP_CONF_OPENDHT_PROXY, optarg);
#endif
#ifdef CONFIG_HIP_ENABLED
                        } else if (!strcmp(long_options[index].name, "list-hits")) {
				action = ACTION_LIST_HITS;
                        } else if (!strcmp(long_options[index].name, "rvs")) {
				processor_config_set_string(config, P2PSHIP_CONF_RVS, optarg);
                        } else if (!strcmp(long_options[index].name, "provide-rvs")) {
				processor_config_set_string(config, P2PSHIP_CONF_PROVIDE_RVS, "yes");
#endif
#ifdef CONFIG_WEBCONF_ENABLED
                        } else if (!strcmp(long_options[index].name, "webconf")) {
				processor_config_set_string(config, P2PSHIP_CONF_WEBCONF_SS, optarg);
#endif
			} else {
				c  = '?';
			}
		}

                switch (c) {    
                case 0:
                        /* already processed */
                        break;
                case 'v':
                        if (p2pship_log_level > -1)
                                p2pship_log_level++;
                        break;
                case 'q':
                        flag_quiet = 1;
                        p2pship_log_level = -1;
                        break;
                case 'D':
			log_to_file = 1;
			processor_config_set_string(config, P2PSHIP_CONF_DAEMON, "yes");
                        break;
                case 'c':
                        conf_file = optarg;
			processor_config_set_string(config, P2PSHIP_CONF_CONF_FILE, conf_file);
                        break;
                case 'i':
			processor_config_set_string(config, P2PSHIP_CONF_IFACES, optarg);
                        break;
#ifdef CONFIG_SIP_ENABLED
                case 'p':
                        if (sscanf(optarg, "%u", &tmp) != 1) {
                                USER_ERROR("Invalid port %s\n", optarg);
                                return 1;
                        } else {
				processor_config_set_int(config, P2PSHIP_CONF_SIPP_PROXY_PORT, tmp);
			}
                        break;
#endif
                case 's':
                        if (sscanf(optarg, "%u", &tmp) != 1) {
                                USER_ERROR("Invalid port %s\n", optarg);
                                return 1;
                        } else {
				processor_config_set_int(config, P2PSHIP_CONF_SHIP_PORT, tmp);
			}
                        break;
                case 'V':
                        print_version();
                        return 0;
		case 'R':
			load_autoreg = 1;
			break;
		case 'r':
			processor_config_set_string(config, P2PSHIP_CONF_AUTOREG_FILE, optarg);
			break;
		case 'L':
			log_to_file = 1;
			break;
                case 'k':
			processor_kill_existing_pid();
			break;
                case 'K':
			processor_kill_all_existing();
			break;
                case 't':
			do_test = 1;
			break;
                case 'h':
                case '?':
                default:
                        print_version();
                        print_usage();
                        return 1;
                }
        }
        
        if (!flag_quiet)
                print_version();
     
        /* 1. load the defaults (done already), 2. load the conf file, 3. put on the manual overrides */
	/* ensure that we have a config file! */
	if (ship_ensure_file(conf_file, "# Autocreated\n\n") || 
	    processor_config_load(config2, conf_file)) {
		USER_ERROR("Error processing config file %s\n", conf_file);
		goto err;
	}
        
        if (processor_config_transfer(config2, config)) {
                USER_ERROR("Error processing configs\n");
                goto err;
        }

	/* transfer */
	processor_config_free(config);
	config = config2;
	config2 = NULL;

	/* ok, ready to rock! */
	processor_config_ensure_configs(config);
	if (log_to_file) {
		p2pship_log_file = processor_config_string(config, P2PSHIP_CONF_LOG_FILE);
	}

#ifdef CONFIG_START_GLIB_MAIN_LOOP
	if (!g_thread_supported())
		g_thread_init(NULL);
#endif
#ifdef CONFIG_START_GTK
	gdk_threads_init();
	gdk_threads_enter();
	gtk_init(&argc, &argv);
#endif

#ifdef CALL_DEBUG
	calldebug_init();
#endif
	/* mark starttime for uptime calcs */
	time(&p2pship_start);

	/* register each modules */
	ASSERT_ZERO(processor_init(config), err);
#ifdef CONFIG_HIP_ENABLED
	hipapi_register();
#endif
#ifdef CONFIG_SIP_ENABLED
	sipp_register();
#endif
	ident_addr_register();
	ident_register();
#ifdef CONFIG_WEBCONF_ENABLED
	webconf_register();
#endif
#ifdef CONFIG_EXTAPI_ENABLED
	extapi_register();
#endif
#ifdef CONFIG_WEBCACHE_ENABLED
	webcache_register();
#endif
	resourceman_register();
	olclient_register();
	conn_register();
	netio_register();
	netio_events_register();
	netio_ff_register();
	netio_man_register();
	netio_http_register();
	ui_register();
	ui_stdin_register();
	processor_init_module("ui_stdin", config);
	
#ifdef CONFIG_DBUS_ENABLED
	dbus_register();
#endif

	if (!console_only) {
#ifdef CONFIG_GTKUI_ENABLED
		ui_gtk_register();
		processor_init_module("ui_gtk", config);
#endif
	}
	addrbook_register();
#ifdef CONFIG_PYTHON_ENABLED
	pymod_register();	
#endif

#ifdef CONFIG_MEDIA_ENABLED
	media_register();
#endif
	/* check what we actually should do */
	switch (action) {
	case ACTION_LIST_CA: { /* list ca */
		if (processor_init_module("ident", config)) {
			USER_ERROR("Error initializing system\n");
		} else {
			ident_data_print_cas(ident_get_cas());
		}
		break;
	}

	case ACTION_REMOVE_CA: { /* remove ca */
		if (processor_init_module("ident", config)) {
			USER_ERROR("Error initializing system\n");
		} else {
			ident_remove_ca(action_param);
		}
		break;
	}

	case ACTION_LIST: { /* list */
		if (processor_init_module("ident", config)) {
			USER_ERROR("Error initializing system\n");
		} else {
			ident_data_print_idents(ident_get_identities());
		}
		break;
	}

	case ACTION_REMOVE: { /* remove */
		if (processor_init_module("ident", config)) {
			USER_ERROR("Error initializing system\n");
		} else {
			ident_remove_ident(action_param);
		}
		break;
	}

	case ACTION_IMPORT:  /* import */
	case ACTION_IMPORT_CA: { /* import ca */
		if (processor_init_module("ident", config)) {
			USER_ERROR("Error initializing system\n");
		} else {
			if (ident_import_file(action_param, 1)) {
				USER_ERROR("Error loading processing file %s\n", action_param);
			}
		}
		break;
	}
		
#ifdef CONFIG_HIP_ENABLED
	case ACTION_LIST_HITS: {
		if (processor_init_module("hipapi", config)) {
			USER_ERROR("Error initializing system\n");
		} else {
			hipapi_list_hits();
		}
		break;
	}
#endif
	case ACTION_NONE:
	default: {
		struct rlimit rl;
		int result;
		
#ifdef CONFIG_PYTHON_ENABLED
		if (processor_config_is_true(config, P2PSHIP_CONF_START_SHELL))
			processor_config_set_false(config, P2PSHIP_CONF_DAEMON);
#endif
		/* go daemon (..whee!) */
		if (processor_config_is_true(config, P2PSHIP_CONF_DAEMON)) {
			if (fork())
				goto err;			
		}
		
		/* check the stack size */
		if (!(result = getrlimit(RLIMIT_STACK, &rl))) {
			const rlim_t stacksize = 32L * 1024L * 1024L;
			if (rl.rlim_cur < stacksize) {
				LOG_INFO("increasing stack size to %d\n", stacksize);
				rl.rlim_cur = stacksize;
				if (setrlimit(RLIMIT_STACK, &rl)) {
					LOG_ERROR("could not set new stack size!\n");
				}
			}
		} else {
			LOG_ERROR("error checking stack size\n");
		}

		if (processor_init_modules(config) ||
		    (load_autoreg && ident_autoreg_load())) {
			USER_ERROR("Error initializing system\n");
		} else {
#ifdef REMOTE_DEBUG
			ship_remote_debug_init(config);
#endif
			/* start the main loop, blocks */
#ifdef REF_DEBUG2
			//			processor_tasks_add_periodic(ship_debug_reportref, 10000);
#endif

			if (do_test) {
				LOG_DEBUG("Run tests..\n");
			}

			processor_run();
		}
	}
	}
        
	ret = 0;
 err:
#ifdef REF_DEBUG2
	ship_debug_reportref();
#endif
	processor_close();
	freez(action_param);
	processor_config_free(config);
	processor_config_free(config2);

#ifdef LOCK_DEBUG
	debug2_close();
#endif
#ifdef REF_DEBUG2
	ship_debug_closeref();
#endif

	xmlCleanupThreads();
        if (!ret && !flag_quiet)
                USER_ERROR("ending ok\n");

	processor_cleanup_pid();
        return ret;
}
Beispiel #20
0
/* imports contacts */
int
addrbook_import_contacts(ship_list_t *newco, int *concount, int query)
{
	ship_list_t *imps = 0;
	int ret = -1;
	void *ptr = 0;
	contact_t *c = 0;
	*concount = 0;

#ifdef OLD_LOGIC
	void *last = 0;
	ship_list_t *done = 0;
	ship_list_t *imported = 0;

	/* this is the 'old' way - check whether we already have
	   imported an entry, skip if so. */

	/* copy over to an array for filtering */
	ASSERT_TRUE(imps = ship_list_new(), err);
	while (c = ship_list_next(newco, &ptr))
		ship_list_add(imps, c);

	/* load up what we've imported already */
	ASSERT_TRUE(imported = ship_list_new(), err);
	ASSERT_TRUE(done = ship_list_new(), err);
	ASSERT_ZERO(addrbook_load_imported(imported), err);
	ptr = 0;
	while (c = ship_list_next(imported, &ptr))
		ship_list_add(done, c);
	
	/* filter out those we already have based on the sip aor */
	ptr = 0;
	while (c = ship_list_next(imps, &ptr)) {
		void *ptr2 = 0;
		contact_t *c2 = 0;
		int found = 0;
		
		while (!found && (c2 = ship_list_next(imported, &ptr2))) {
			if (!strcmp(c2->sip_aor, c->sip_aor)) {
				found = 1;
				/* should we query whether to update the field if something
				   has changed? */
			}
		}	
		
		/* here we just skip those we already have imported */
		if (found) {
			ptr = last;
			ship_list_remove(imps, c);
		}
		last = ptr;
	}
		
	/* todo: check for ones with same sip aor? */
	/* todo: check for ones with same name? */
#else
	/* this is another way - check if we *have* the entry, skip if so */
	ASSERT_TRUE(imps = ship_list_new(), err);
	while ((c = ship_list_next(newco, &ptr))) {
		if (!addrbook_has_contact(NULL, c->sip_aor))
			ship_list_add(imps, c);
	}
#endif


#ifdef CONFIG_LIBEBOOK_ENABLED
	ret = addrbook_libebook_import(imps, concount, query);
#else	
	*concount = ship_list_length(imps);
	
	/* print out */
	while ((c = ship_list_next(newco, &ptr))) {
		LOG_WARN("Ignoring import of contact %s, sip: %s\n",
			 c->name, c->sip_aor);
	}
	ret = 0;
#endif

 err:
#ifdef OLD_LOGIC
	if (!ret)
		addrbook_save_imported(done);
	
	if (imported) {
		while (c = ship_list_pop(imported))
			ident_contact_free(c);
		ship_list_free(imported);
	}

	ship_list_free(imps);
	ship_list_free(done);
#endif
	return ret;
}
Beispiel #21
0
static int
ui_gtk_query_ident_operation(ident_t *ident, const char *operation, 
			       const char* true_op, const char *false_op)
{
	const char *templ = 
		"<big>%s identity?</big>\n\nYour confirmation is required for %sing the identity <b>%s</b> %s:\n  Name: <i>%s</i>\n  Certified name: <i>%s</i>\n  Issued by: <i>%s</i>\n  Valid from: <i>%s</i>\n  Until: <i>%s</i>\n";
	char *str = 0;
	time_t start, end;
	GtkDialog *diag = 0;
	char startb[64], endb[64], *issuer = 0, *cname = 0, *op2 = 0, *tmp, *aor = 0, *uname = 0;
	int ret = 0;

	gdk_threads_enter();
		
	/* cert data */
	if (!(issuer = ident_data_x509_get_cn(X509_get_issuer_name(ident->cert)))) {
		ASSERT_TRUE(issuer = strdup("UNKNOWN ISSUER"), err);
	}

	if (!(cname = ident_data_x509_get_cn(X509_get_subject_name(ident->cert)))) {
		ASSERT_TRUE(cname = strdup("UNKNOWN SUBJECT"), err);
	}
	
	/* validity */
	ASSERT_ZERO(ident_data_x509_get_validity(ident->cert, &start, &end), err);
	ship_format_time_human(start, startb, sizeof(startb));
	ship_format_time_human(end, endb, sizeof(endb));
	
	ASSERT_TRUE(op2 = strdup(operation), err);
	ASSERT_TRUE(aor = ship_pangoify(ident->sip_aor), err);
	ASSERT_TRUE(uname = ship_pangoify(ident->username), err);
	ASSERT_TRUE(tmp = ship_pangoify(cname), err);
	freez(cname); cname = tmp;
	ASSERT_TRUE(tmp = ship_pangoify(issuer), err);
	freez(issuer); issuer = tmp;
	
	str = malloc(strlen(templ) + strlen(startb) + strlen(endb) + strlen(issuer) 
		     + strlen(cname) 
		     + strlen(aor) + strlen(uname)
		     + 1024);

	op2[0] = toupper(op2[0]);
	if (!strcmp(operation, "replace")) {
		sprintf(str, templ,
			"Replace", "replace", aor, "New identity", uname,
			cname, issuer, startb, endb);
	} else {
		sprintf(str, templ,
			op2, operation, aor, "Details", uname,
			cname, issuer, startb, endb);
	}
	
	ASSERT_TRUE(diag = (GtkDialog*)gtk_message_dialog_new_with_markup(NULL,
									  GTK_DIALOG_MODAL,
									  GTK_MESSAGE_QUESTION,
									  GTK_BUTTONS_NONE,
									  str,
									  NULL), err);
	gtk_dialog_add_buttons(diag, op2, 1, "Cancel", 0, NULL);
	
	ret = gtk_dialog_run(diag);
	gtk_widget_destroy((GtkWidget*)diag);
 err:
	gdk_threads_leave();

	freez(op2);
	freez(str);
	freez(issuer);
	freez(cname);
	freez(uname);
	freez(aor);
	return ret;
}
Beispiel #22
0
int main(int argc, char **argv) {

  init_config(argc, argv);

  open_authorizations("r");

  init_webfinger();

  /** OPEN MAGIC DATABASE **/

  magic_cookie = magic_open(MAGIC_MIME);
  if(magic_load(magic_cookie, RS_MAGIC_DATABASE) != 0) {
    log_error("Failed to load magic database: %s", magic_error(magic_cookie));
    exit(EXIT_FAILURE);
  }

  log_info("starting process: main");

  if(prctl(PR_SET_NAME, "rs-serve [main]", 0, 0, 0) != 0) {
    log_error("Failed to set process name: %s", strerror(errno));
  }

  /** SETUP EVENT BASE **/

  rs_event_base = event_base_new();
  ASSERT_NOT_NULL(rs_event_base, "event_base_new()");
  log_debug("libevent method: %s", event_base_get_method(rs_event_base));
  event_set_log_callback(log_event_base_message);

  // TODO: add error cb to base

  /** SETUP AUTH TOKENS HASH TABLE **/

  auth_sessions = sm_new(1024); // FIXME: this a hardcoded value.

  /** SETUP MAIN LISTENER **/

  struct sockaddr_in sin;
  memset(&sin, 0, sizeof(struct sockaddr_in));
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = htonl(0);
  sin.sin_port = htons(RS_PORT);

  evhtp_t *server = evhtp_new(rs_event_base, NULL);

  if(RS_USE_SSL) {
    evhtp_ssl_cfg_t ssl_config = {
      .pemfile = RS_SSL_CERT_PATH,
      .privfile = RS_SSL_KEY_PATH,
      .cafile = RS_SSL_CA_PATH,
      // what's this???
      .capath = NULL,
      .ciphers = "RC4+RSA:HIGH:+MEDIUM:+LOW",
      .ssl_opts = SSL_OP_NO_SSLv2,
      .ssl_ctx_timeout = 60*60*48,
      .verify_peer = SSL_VERIFY_PEER,
      .verify_depth = 42,
      .x509_verify_cb = dummy_ssl_verify_callback,
      .x509_chk_issued_cb = dummy_check_issued_cb,
      .scache_type = evhtp_ssl_scache_type_internal,
      .scache_size = 1024,
      .scache_timeout = 1024,
      .scache_init = NULL,
      .scache_add = NULL,
      .scache_get = NULL,
      .scache_del = NULL
    };

    if(evhtp_ssl_init(server, &ssl_config) != 0) {
      log_error("evhtp_ssl_init() failed");
      exit(EXIT_FAILURE);
    }
  }

  /* WEBFINGER */

  evhtp_callback_cb webfinger_cb = (RS_WEBFINGER_ENABLED ?
                                    handle_webfinger : reject_webfinger);
  evhtp_set_cb(server, "/.well-known/webfinger", webfinger_cb, NULL);
  // support legacy webfinger clients (we don't support XRD though):
  evhtp_set_cb(server, "/.well-known/host-meta", webfinger_cb, NULL);
  evhtp_set_cb(server, "/.well-known/host-meta.json", webfinger_cb, NULL);

  /* REMOTESTORAGE */

  evhtp_callback_t *storage_cb = evhtp_set_regex_cb(server, "^/storage/([^/]+)/.*$", handle_storage, NULL);

  evhtp_set_hook(&storage_cb->hooks, evhtp_hook_on_request_fini, finish_request, NULL);

  if(evhtp_bind_sockaddr(server, (struct sockaddr*)&sin, sizeof(sin), 1024) != 0) {
    log_error("evhtp_bind_sockaddr() failed: %s", strerror(errno));
    exit(EXIT_FAILURE);
  }

  /** SETUP AUTH LISTENER **/

  memset(&sin, 0, sizeof(struct sockaddr_in));
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = htonl(0);
  sin.sin_port = htons(RS_AUTH_PORT);

  evhtp_t *server_auth = evhtp_new(rs_event_base, NULL);

  if(RS_USE_SSL) {
    evhtp_ssl_cfg_t ssl_config = {
      .pemfile = RS_SSL_CERT_PATH,
      .privfile = RS_SSL_KEY_PATH,
      .cafile = RS_SSL_CA_PATH,
      // what's this???
      .capath = NULL,
      .ciphers = "RC4+RSA:HIGH:+MEDIUM:+LOW",
      .ssl_opts = SSL_OP_NO_SSLv2,
      .ssl_ctx_timeout = 60*60*48,
      .verify_peer = SSL_VERIFY_PEER,
      .verify_depth = 42,
      .x509_verify_cb = dummy_ssl_verify_callback,
      .x509_chk_issued_cb = dummy_check_issued_cb,
      .scache_type = evhtp_ssl_scache_type_internal,
      .scache_size = 1024,
      .scache_timeout = 1024,
      .scache_init = NULL,
      .scache_add = NULL,
      .scache_get = NULL,
      .scache_del = NULL
    };

    if(evhtp_ssl_init(server_auth, &ssl_config) != 0) {
      log_error("evhtp_ssl_init() failed");
      exit(EXIT_FAILURE);
    }
  }

  /* AUTH */

  evhtp_set_cb(server_auth, "/authenticate", handle_authenticate, NULL);
  evhtp_set_cb(server_auth, "/authorizations", handle_authorizations, NULL);

  evhtp_set_hook(&storage_cb->hooks, evhtp_hook_on_request_fini, finish_request, NULL);

  if(evhtp_bind_sockaddr(server_auth, (struct sockaddr*)&sin, sizeof(sin), 1024) != 0) {
    log_error("evhtp_bind_sockaddr() failed: %s", strerror(errno));
    exit(EXIT_FAILURE);
  }

  /** SETUP SIGNALS **/

  sigset_t sigmask;
  sigemptyset(&sigmask);
  sigaddset(&sigmask, SIGINT);
  sigaddset(&sigmask, SIGTERM);
  sigaddset(&sigmask, SIGCHLD);
  ASSERT_ZERO(sigprocmask(SIG_BLOCK, &sigmask, NULL), "sigprocmask()");
  int sfd = signalfd(-1, &sigmask, SFD_NONBLOCK);
  ASSERT_NOT_EQ(sfd, -1, "signalfd()");

  struct event *signal_event = event_new(rs_event_base, sfd, EV_READ | EV_PERSIST,
                                         handle_signal, NULL);
  event_add(signal_event, NULL);

  /** RUN EVENT LOOP **/

  if(RS_DETACH) {
    int pid = fork();
    if(pid == 0) {
      event_reinit(rs_event_base);

      if(RS_LOG_FILE == stdout) {
        log_warn("No --log-file option given. Future output will be lost.");
        freopen("/dev/null", "r", stdout);
        freopen("/dev/null", "r", stderr);
      }

      return event_base_dispatch(rs_event_base);
    } else {
      printf("rs-serve detached with pid %d\n", pid);
      if(RS_PID_FILE) {
        fprintf(RS_PID_FILE, "%d", pid);
        fflush(RS_PID_FILE);
      }
      _exit(EXIT_SUCCESS);
    }
  } else {
    if(RS_PID_FILE) {
      fprintf(RS_PID_FILE, "%d", getpid());
      fflush(RS_PID_FILE);
    }
    return event_base_dispatch(rs_event_base);
  }
}