Пример #1
0
void handle_iscsi_events(int fd)
{
	struct session *session;
	struct iet_event event;
	int res;

retry:
	if ((res = nl_read(fd, &event, sizeof(event))) < 0) {
		if (errno == EAGAIN)
			return;
		if (errno == EINTR)
			goto retry;
		log_error("read netlink fd (%d)", errno);
		exit(1);
	}

	log_debug(1, "conn %u session %llu target %u, state %u",
		  event.cid, event.sid, event.tid, event.state);

	switch (event.state) {
	case E_CONN_CLOSE:
		if (!(session = session_find_id(event.tid, event.sid))) {
			log_warning("session %llu not found?", event.sid);
			goto retry;
		}

		if (--session->conn_cnt <= 0)
			session_remove(session);
		break;
	default:
		log_error("%s(%d) %u\n", __FUNCTION__, __LINE__, event.state);
		exit(-1);
		break;
	}
}
Пример #2
0
bool simple_bib_session(void)
{
	struct bib_entry *bib;
	struct session_entry *session;

	bib = create_bib_entry(0, 0);
	if (!bib) {
		log_warning("Could not allocate a BIB entry.");
		return false;
	}
	session = create_session_entry(1, 0, 1, 0, bib, IPPROTO_TCP, 12345);
	if (!session) {
		log_warning("Could not allocate a Session entry.");
		return false;
	}

	// Insert the BIB entry.
	if (!bib_add(bib, IPPROTO_TCP)) {
		log_warning("Test 'BIB insertion' failed: Call returned false.");
		return false;
	}
	if (!assert_bib("BIB insertion", bib, false, true, false))
		return false;

	// Insert the session entry.
	if (!session_add(session)) {
		log_warning("Test 'Session insertion' failed: Call returned false.");
		return false;
	}
	if (!assert_session("Session insertion", session, false, true, false))
		return false;

	// The BIB entry has a session entry, so it shouldn't be removable.
	if (bib_remove(bib, IPPROTO_TCP)) {
		log_warning("Test 'Bib removal' failed: Removal shouldn't have succeeded.");
		return false;
	}
	if (!assert_bib("Bib removal (bib table)", bib, false, true, false))
		return false;
	if (!assert_session("BIB removal (session table)", session, false, true, false))
		return false;

	// Remove the session entry.
	// Because the BIB entry no longer has sessions, it should be automatically removed as well.
	if (!session_remove(session)) {
		log_warning("Test 'Session removal' failed: Call returned false.");
		return false;
	}
	if (!assert_bib("Session removal (bib table)", bib, false, false, false))
		return false;
	if (!assert_session("Session removal (session table)", session, false, false, false))
		return false;

	// Quit.
	return true;
}
Пример #3
0
static int session_client_load(session_t *ss)
{
    session_opt_t *so = ss->so;
    char hmac[HMAC_HEX_SIZE], buf[COOKIE_MAX_SIZE];
    const char *cli_ebuf, *cli_hmac, *cli_mtime, *cli_iv;
    ssize_t c;

    dbg_err_if (ss == NULL);

    /* extract session data, mtime and hmac from cookies */
    cli_ebuf = request_get_cookie(ss->rq, KL1_CLISES_DATA);
    cli_mtime = request_get_cookie(ss->rq, KL1_CLISES_MTIME);
    cli_hmac = request_get_cookie(ss->rq, KL1_CLISES_HMAC);
    cli_iv = request_get_cookie(ss->rq, KL1_CLISES_IV);

    //nop_err_if(cli_ebuf == NULL || cli_mtime == NULL || cli_hmac == NULL);
    dbg_err_if(cli_ebuf == NULL || cli_mtime == NULL || cli_hmac == NULL);
    /* cli_iv may be NULL */

    /* calc the HMAC */
    dbg_err_if(session_client_hmac(&so->hmac_ctx, hmac, HMAC_HEX_SIZE, 
        cli_ebuf, ss->id, cli_mtime, ss->so->encrypt ? cli_iv : NULL));

    /* compare HMACs */
    if(strcmp(hmac, cli_hmac))
    {
        session_remove(ss); /* remove all bad stale data */
        warn_err("HMAC don't match, rejecting session data");
    }

    /* hash ckeched. decode/uncompress/decrypt session data */

    /* hex decode and save current cipher IV */
    dbg_err_if((c = u_hexncpy(ss->so->cipher_iv, cli_iv, strlen(cli_iv), 
        HEXCPY_DECODE)) <= 0);

    /* set client provided mtime */
    ss->mtime = strtoul(cli_mtime, NULL, 0);

    dbg_err_if(strlen(cli_ebuf) > COOKIE_MAX_SIZE);

    /* hex decode session data */
    dbg_err_if((c = u_hexncpy(buf, cli_ebuf, strlen(cli_ebuf), 
        HEXCPY_DECODE)) <= 0);

    /* load session data from the buffer */
    dbg_err_if(session_prv_load_from_buf(ss, buf, c));

    return 0;
err:
    return ~0;
}
Пример #4
0
static void fx_close(PurpleConnection *gc)
{
	fetion_account *ses;
	fetion_account *ac = purple_connection_get_protocol_data(gc);

	purple_input_remove(ac->conn);
	close(ac->sk);
	g_free(ac->data);
	ac->data = (gchar*)0;

	while(sessions) {
		ses = (fetion_account*)(sessions->data);
		session_remove(ses);
		session_destroy(ses);
	}
	fetion_user_free(ac->user);
	ac->user = NULL;
	purple_connection_set_protocol_data(gc, NULL);
}
Пример #5
0
static void resource_remove(Resource *r,int kill_session){
Session *s=r->session;

	debug(L_("Removing resource %s of %s"),r->name,s->jid);
	s->resources=g_list_remove(s->resources,r);
	/* HACK! when last resource is removed set session description to it's status */
	if (!s->resources && !s->user->status){
		g_free(s->gg_status_descr);
		if(r->status) s->gg_status_descr=g_strdup(r->status);
		else s->gg_status_descr=NULL;
	}
	if (r->name) g_free(r->name);
	if (r->show) g_free(r->show);
	if (r->status) g_free(r->status);
	g_free(r);
	session_send_status(s);
	if (!s->resources && kill_session){
		session_remove(s);
		return;
	}
}
Пример #6
0
bool simple_session(void)
{
	struct session_entry *session;
	bool success = true;

	session = create_session_entry(1, 0, 1, 0, NULL, IPPROTO_TCP, 12345);
	if (!assert_not_null(session, "Allocation of test session entry"))
		return false;

	success &= assert_equals_int(0, session_add(session), "Session insertion call");
	success &= assert_session("Session insertion state", session, false, true, false);
	if (!success)
		return false; /* See simple_bib(). */

	success &= assert_true(session_remove(session), "Session removal call");
	success &= assert_session("Session removal state", session, false, false, false);
	if (!success)
		return false;

	kfree(session);
	return true;
}
Пример #7
0
void session_broken(Session *s){

	if (s->req_id){
		jabber_iq_send_error(s->s,s->jid,NULL,s->req_id,502,_("Remote Server Error"));
	}
	else{
		GList *it;
		presence_send(s->s,NULL,s->user->jid,0,NULL,"Connection broken",0);
		for(it=g_list_first(s->user->contacts);it;it=g_list_next(it)){
			Contact *c=(Contact *)it->data;

			if (!GG_S_NA(c->status) && c->status!=-1){
				char *ujid;
				ujid=jid_build_full(c->uin);
				presence_send(s->s,ujid,s->user->jid,0,NULL,"Transport disconnected",0);
				g_free(ujid);
			}
		}
	}
	s->connected=0;
	session_schedule_reconnect(s);
	session_remove(s);
}
Пример #8
0
/**
 * Server session.
 * - Authenticate sessions.
 * - Upload accounting.
 * - Remove inactive sessions.
 */
static void overlord_serve_session(struct zsession *sess)
{
    uint64_t curr_time = ztime(true);
    zclock(true); // refresh

    // remove inactive, long duration or marked for deletion session
    uint32_t term_cause = 0;
    if (atomic_load_explicit(&sess->delete_flag, memory_order_acquire)) {
        term_cause = PW_ADMIN_RESET;
        zero_syslog(LOG_INFO, "Removed marked for deletion session %s", ipv4_to_str(htonl(sess->ip)));
    } else if (overlord_sess_is_idle_timeout(sess, curr_time)) {
        term_cause = PW_IDLE_TIMEOUT;
        zero_syslog(LOG_INFO, "Removed inactive session %s", ipv4_to_str(htonl(sess->ip)));
    } else if ((curr_time - sess->create_time) > atomic_load_explicit(&sess->max_duration, memory_order_acquire)) {
        term_cause = PW_SESSION_TIMEOUT;
        zero_syslog(LOG_INFO, "Removed long duration session %s", ipv4_to_str(htonl(sess->ip)));
    }

    if (term_cause) {
        if (sess->accounting_alive) {
            session_accounting(sess, PW_STATUS_STOP, term_cause);
        }
        session_remove(sess);
    } else {
        overlord_nat_cleanup(sess);
        overlord_apply_deferred_rules(sess);

        // authenticate session
        if (0 == sess->client->id) {
            overlord_auth(sess);

        } else if ((curr_time - atomic_load_explicit(&sess->last_acct, memory_order_acquire)) >
                   atomic_load_explicit(&sess->acct_interval, memory_order_acquire)) {
            overlord_acct(sess);
        }
    }
}
Пример #9
0
void async_event(char *data)
{
	struct tgt_event *ev = (struct tgt_event *) data;
	struct iet_msg *msg = (struct iet_msg *) ev->data;
	struct session *session;

	eprintf("%u %u\n", msg->msg_type, msg->result);

	switch (msg->k.conn_state_change.state) {
	case E_CONN_CLOSE:
		if (!(session = session_find_id(msg->k.conn_state_change.tid,
						msg->k.conn_state_change.sid))) {
			eprintf("session %#" PRIx64 " not found?",
				msg->k.conn_state_change.sid);
		}

		if (!--session->conn_cnt)
			session_remove(session);
		break;
	default:
		eprintf("%u\n", msg->k.conn_state_change.state);
		break;
	}
}
Пример #10
0
int session_io_handler(Session *s){
struct gg_event *event;
char *jid,*str;
int chat;
GIOCondition condition=s->g_pollfd.revents;
time_t timestamp;
gboolean state;

	user_load_locale(s->user);
	debug(L_("Checking error conditions..."));
	if (condition&(G_IO_ERR|G_IO_NVAL)){
		if (condition&G_IO_ERR) g_warning(N_("Error on connection for %s, GGid: %i"),s->jid,s->ggs->uin);
		if (condition&G_IO_HUP){
			g_warning(N_("Hangup on connection for %s, GGid: %i"),s->jid,s->ggs->uin);
			return session_error(s);
		}
		if (condition&G_IO_NVAL) g_warning(N_("Invalid channel on connection for %s"),s->jid);

		session_broken(s);
		return FALSE;
	}

	debug(L_("watching fd (gg_debug_level=%i)..."),gg_debug_level);
	event=gg_watch_fd(s->ggs);
	if (!event){
		g_warning(N_("Connection broken. Session of %s, GGid: %i"),s->jid,s->ggs->uin);
		return session_error(s);
	}

	switch(event->type){
		case GG_EVENT_DISCONNECT:
			g_warning(N_("Server closed connection of %s, GGid: %i"),s->jid,s->ggs->uin);
			session_error(s);
			gg_event_free(event);
			return FALSE;
		case GG_EVENT_CONN_FAILED:
			g_message(N_("Login failed (%d:%s) for %s, GGid: %i"),
					event->event.failure,
					(event->event.failure>GG_FAILURE_NUM_REASONS||event->event.failure<1)?"-UNKNOWN-":gg_failure_reason[event->event.failure-1],
					s->jid,
					s->ggs->uin);
			if (s->req_id)
				jabber_iq_send_error(s->s,s->jid,NULL,s->req_id,401,_("Unauthorized"));
			else {
				str=g_strdup(from_utf8(gg_failure_reason_txt[event->event.failure-1]));
				presence_send(s->s,NULL,s->user->jid,0,NULL,str,0);
				g_free(str);
			}
			state = FALSE;
			if (!s->req_id)
				switch(event->event.failure){
					case GG_FAILURE_RESOLVING:
					case GG_FAILURE_CONNECTING:
					case GG_FAILURE_INVALID:
					case GG_FAILURE_READING:
					case GG_FAILURE_WRITING:
					case GG_FAILURE_TLS:
						state = session_try_next(s);
					default:
						break;
				}
			if (state) {
				s->connected=0;
				session_schedule_reconnect(s);
			} else
				session_remove(s);
			gg_event_free(event);
			return FALSE;
		case GG_EVENT_CONN_SUCCESS:
			g_message(L_("Login succeed for %s, GGid: %i"),s->jid,s->ggs->uin);
			if (s->req_id)
				jabber_iq_send_result(s->s,s->jid,NULL,s->req_id,NULL);
			if (s->req_id){
				g_free(s->req_id);
				s->req_id=NULL;
			}
			if (s->query){
				xmlnode_free(s->query);
				s->query=NULL;
			}
			if (!s->user->confirmed){
				s->user->confirmed=1;
				user_save(s->user);
			}
			s->connected=1;
			session_send_status(s);
			session_send_notify(s);
			presence_send(s->s,NULL,s->user->jid,s->user->invisible?-1:1,NULL,s->gg_status_descr,0);

			if (s->timeout_func) g_source_remove(s->timeout_func);
			s->timeout_func=NULL;
			if (s->ping_timeout_func) g_source_remove(s->ping_timeout_func);
			s->ping_timeout_func=g_timeout_add(ping_interval*1000,session_ping,s);
			if (s->pubdir_change){
				add_request(RT_CHANGE,s->jid,NULL,s->req_id,
							NULL,s->pubdir_change,s->s);
				gg_pubdir50_free(s->pubdir_change);
				s->pubdir_change=NULL;
			}
			if (s->get_roster){
				gg_userlist_request(s->ggs, GG_USERLIST_GET, NULL);
			}
			break;
		case GG_EVENT_NOTIFY:
			session_event_notify(s,event);
			break;
		case GG_EVENT_NOTIFY_DESCR:
			session_event_notify_descr(s,event);
			break;
		case GG_EVENT_NOTIFY60:
			session_event_notify60(s,event);
			break;
		case GG_EVENT_STATUS:
			session_event_status(s,
					event->event.status.status,
					event->event.status.uin,
					event->event.status.descr,
					0,0,0,0);
			break;
		case GG_EVENT_STATUS60:
			session_event_status(s,
					event->event.status60.status,
					event->event.status60.uin,
					event->event.status60.descr,
					1,
					event->event.status60.remote_ip,
					event->event.status60.remote_port,
					event->event.status60.version);
			break;
		case GG_EVENT_MSG:
			if (event->event.msg.recipients_count>1){
				debug(L_("Dropped conference message: sender: %i class: %i time: %lu"),
							event->event.msg.sender,
							event->event.msg.msgclass,
							(unsigned long)event->event.msg.time);
				break;
			}
			gg_messages_in++;
			debug(L_("Message: sender: %i class: %i time: %lu"),
							event->event.msg.sender,
							event->event.msg.msgclass,
							(unsigned long)event->event.msg.time);
			
			if (event->event.msg.sender==0){
				if (!user_sys_msg_received(s->user,event->event.msg.msgclass)) break;
				if (ignore_system_messages == ISM_IGNORE_ALL) break;
				if (ignore_system_messages == ISM_IGNORE_HTML
					&& strstr((const char *)event->event.msg.message, "<HTML>")) break;
				timestamp=event->event.msg.time;
				str=g_strdup_printf(_("GG System message #%i"),
							event->event.msg.msgclass);
				message_send_subject(s->s,jid, s->user->jid, str,
						string_from_gg((const char *)event->event.msg.message),
												timestamp);
				g_free(str);
				break;
			}
			else{
				Contact *c=user_get_contact(s->user,
						event->event.msg.sender,0);
				if ((!c && s->user->ignore_unknown) 
				    || (c && c->ignored)) {
					debug(L_("Ignoring the message."));
			       		break;
				}
				jid=jid_build_full(event->event.msg.sender);
				if ((event->event.msg.msgclass&GG_CLASS_CHAT)!=0) chat=1;
				else chat=0;
			}
			if ((event->event.msg.msgclass&GG_CLASS_QUEUED)!=0){
				timestamp=event->event.msg.time;
			}
			else timestamp=0;
			if(event->event.msg.formats_length>0)
				message_send_rich(s->s,jid,s->user->jid,chat,
						(char *)event->event.msg.message,timestamp,
						event->event.msg.formats_length,(void *)event->event.msg.formats);
			else
				message_send(s->s,jid,s->user->jid,chat,
						string_from_gg((const char *)event->event.msg.message),timestamp);
			g_free(jid);
			break;
		case GG_EVENT_PONG:
			s->waiting_for_pong=FALSE;
			if (s->ping_timer){
				g_timer_stop(s->ping_timer);
				debug(L_("Pong! ping time: %fs"),
						g_timer_elapsed(s->ping_timer,NULL));
			}
			if (s->timeout_func) g_source_remove(s->timeout_func);
			s->timeout_func=NULL;
			break;
		case GG_EVENT_PUBDIR50_SEARCH_REPLY:
			request_response_search(event);
			break;
		case GG_EVENT_PUBDIR50_WRITE:
			request_response_write(event);
			break;
		case GG_EVENT_ACK:
			debug("GG_EVENT_ACK");
			break;
		case GG_EVENT_NONE:
			debug("GG_EVENT_NONE");
			break;
		case GG_EVENT_USERLIST:
			if(event->event.userlist.type==GG_USERLIST_GET_REPLY)
				get_roster_done(s,event);
			else
				g_warning(N_("Wrong gg userlist type: %i"),event->event.userlist.type);
			break;
		default:
			g_warning(N_("Unknown GG event: %i"),event->type);
			break;
	}

	session_setup_g_source(s);

	gg_event_free(event);
	debug(L_("io handler done..."));

	return FALSE;
}
Пример #11
0
int delete_static_route(struct request_bib *req)
{
	struct bib_entry *bib;
	struct session_entry *session;
	int error = 0;

	spin_lock_bh(&bib_session_lock);

	switch (req->remove.l3_proto) {
	case L3PROTO_IPV6:
		error = bib_get_by_ipv6(&req->remove.ipv6, req->l4_proto, &bib);
		if (error)
			goto end;
		break;
	case L3PROTO_IPV4:
		error = bib_get_by_ipv4(&req->remove.ipv4, req->l4_proto, &bib);
		if (error)
			goto end;
		break;
	default:
		log_err(ERR_L3PROTO, "Unsupported network protocol: %u.", req->remove.l3_proto);
		error = -EINVAL;
		goto end;
	}

	if (!bib) {
		log_err(ERR_BIB_NOT_FOUND, "Could not find the BIB entry requested by the user.");
		error = -ENOENT;
		goto end;
	}

	/*
	 * I'm tempted to assert that the entry is static here. Would that serve a purpose?
	 * Nah.
	 */

	while (!list_empty(&bib->sessions)) {
		session = container_of(bib->sessions.next, struct session_entry, bib_list_hook);
		error = session_remove(session);
		if (error) {
			log_err(ERR_UNKNOWN_ERROR,
					"Session [%pI6c#%u, %pI6c#%u, %pI4#%u, %pI4#%u] refused to die.",
					&session->ipv6.remote.address, session->ipv6.remote.l4_id,
					&session->ipv6.local.address, session->ipv6.local.l4_id,
					&session->ipv4.local.address, session->ipv4.local.l4_id,
					&session->ipv4.remote.address, session->ipv4.remote.l4_id);
			goto end;
		}
		list_del(&session->bib_list_hook);
		list_del(&session->expire_list_hook);
		session_kfree(session);
	}

	error = bib_remove(bib, req->l4_proto);
	if (error) {
		log_err(ERR_UNKNOWN_ERROR, "Remove bib entry call ended with error code %d, "
				"despite validations.", error);
		goto end;
	}

	pool4_return(req->l4_proto, &bib->ipv4);
	bib_kfree(bib);
	/* Fall through. */

end:
	spin_unlock_bh(&bib_session_lock);
	return error;
}
Пример #12
0
/*
 * plugin_unregister()
 *
 * od³±cza wtyczkê.
 *
 * 0/-1
 */
int plugin_unregister(plugin_t *p)
{
	/* XXX eXtreme HACK warning
	 * (mp) na razie jest tak.  docelowo: wyladowywac pluginy tylko z
	 * glownego programu (queriesami?)
	 * to cos segfaultowalo (wczesniej czy pozniej), jesli bylo wywolane z
	 * ncurses.  niestety, problem pozostaje dla innych pluginow i takiego
	 * np. rc. sie zrobi nast razem */

	/* j/w If any plugin has backtrace here, and we try to remove it from memory.
	 * ekg2 do SEGV.
	 */

	struct timer *t;
	session_t *s;
	query_t **ll;
	variable_t *v;
	command_t *c;
	list_t l;

	if (!p)
		return -1;

/* XXX think about sequence of unloading....: currently: watches, timers, sessions, queries, variables, commands */

	for (l = watches; l; l = l->next) {
		watch_t *w = l->data;

		if (w && w->plugin == p)
			watch_free(w);
	}

	for (t = timers; t; t = t->next) {
		if (t->plugin == p)
			t = timers_removei(t);
	}

	for (s = sessions; s; ) {
		session_t *next = s->next;

		if (s->plugin == p)
			session_remove(s->uid);
		s = next;
	}

	for (ll = queries; ll <= &queries[QUERY_EXTERNAL]; ll++) {
		query_t *q;

		for (q = *ll; q; ) {
			query_t *next = q->next;

			if (q->plugin == p)
				query_free(q);

			q = next;
		}
	}

	for (v = variables; v; v = v->next) {
		if (v->plugin == p) 
			v = variables_removei(v);
	}

	for (c = commands; c; c = c->next) {
		if (c->plugin == p)
			c = commands_removei(c);
	}

	plugins_unlink(p);

	return 0;
}