Esempio n. 1
0
gboolean session_timeout(gpointer data){
Session *s;
GgServer *serv;

	g_assert(data!=NULL);
	s=(Session *)data;
	serv=(GgServer*)s->current_server->data;
	user_load_locale(s->user);

	s->timeout_func=0;
	g_warning(N_("Session timeout for %s"),s->jid);

	if(serv->port!=1){
		g_warning(N_("Timeout for server %u - failure count: %d"),
			g_list_position(gg_servers, s->current_server),
			serv->error_count);
	} else {
		g_warning(N_("Timeout for hub %u"),
			g_list_position(gg_servers, s->current_server));
	}

	return session_error(s);
}
Esempio n. 2
0
int jabber_message(struct stream_s *stream,xmlnode tag){
char *type;
char *from;
char *to;
char *subject;
char *body;
int chat;
xmlnode subject_n;
xmlnode body_n;
Session *s;
User *u;

	body_n=xmlnode_get_tag(tag,"body");
	if (body_n!=NULL) body=xmlnode_get_data(body_n);
	else body=NULL;

	subject_n=xmlnode_get_tag(tag,"subject");
	if (subject_n!=NULL) subject=xmlnode_get_data(subject_n);
	else subject=NULL;

	from=xmlnode_get_attrib(tag,"from");
	to=xmlnode_get_attrib(tag,"to");
	type=xmlnode_get_attrib(tag,"type");

	if (!acl_is_allowed(from,tag)){
		if (type && !strcmp(type,"error")){
			debug("Ignoring forbidden message error");
			return -1;
		}
		if (!from) return -1;
		message_send_error(stream,to,from,NULL,405,_("Not allowed"));
		return -1;
	}

	if (from) u=user_get_by_jid(from);
	else u=NULL;
	user_load_locale(u);

	if (!type || !strcmp(type,"normal")) chat=0;
	else if (!strcmp(type,"chat")) chat=1;
	else if (!strcmp(type,"error")){
		g_warning(N_("Error message received: %s"),xmlnode2str(tag));
		return 0;
	}
	else{
		g_warning(N_("Unsupported message type"));
		message_send_error(stream,to,from,body,500,_("Internal Server Error"));
		return -1;
	}

	if (!to || !jid_is_my(to)){
		g_warning(N_("Bad 'to' in: %s"),xmlnode2str(tag));
		message_send_error(stream,to,from,body,400,_("Bad Request"));
		return -1;
	}

	if (!jid_has_uin(to)){
		return message_to_me(stream,from,to,body,tag);
	}

	if (!from){
		g_warning(N_("Anonymous message? %s"),xmlnode2str(tag));
		message_send_error(stream,to,from,body,400,_("Bad Request"));
		return -1;
	}

	s=session_get_by_jid(from,NULL,0);
	if (!s || !s->connected){
		g_warning(N_("%s not logged in. While processing %s"),from,xmlnode2str(tag));
		message_send_error(stream,to,from,body,407,_("Not logged in"));
		return -1;
	}

	if (subject)
		body=g_strdup_printf("Subject: %s\n%s",subject,body);
	session_send_message(s,jid_get_uin(to),chat,string_to_gg(body));
	if (subject)
		g_free(body);

	return 0;
}
Esempio n. 3
0
int jabber_presence(struct stream_s *stream,xmlnode tag){
char *type;
char *from;
char *to;
xmlnode prio_n;
xmlnode show_n;
xmlnode status_n;
char *show,*status;
int priority;
char *tmp;
User *u;

	type=xmlnode_get_attrib(tag,"type");
	from=xmlnode_get_attrib(tag,"from");
	to=xmlnode_get_attrib(tag,"to");

	if (from) u=user_get_by_jid(from);
	else u=NULL;
	user_load_locale(u);

	if (!acl_is_allowed(from,tag)){
		if (type && !strcmp(type,"error")){
			debug("Ignoring forbidden presence error");
			return -1;
		}
		if (!from) return -1;
		presence_send_error(stream,to,from,405,_("Not allowed"));
		return -1;
	}

	show_n=xmlnode_get_tag(tag,"show");
	if (show_n) show=xmlnode_get_data(show_n);
	else show=NULL;

	status_n=xmlnode_get_tag(tag,"status");
	if (status_n) status=xmlnode_get_data(status_n);
	else status=NULL;

	prio_n=xmlnode_get_tag(tag,"priority");
	if (prio_n){
		tmp=xmlnode_get_data(prio_n);
		if (tmp) priority=atoi(tmp);
		else priority=-1;
	}
	else priority=-1;

	if (!type) type="available";

	if (!from || !to){
		if (strcmp(type,"error"))
			presence_send_error(stream,to,from,406,_("Not Acceptable"));
		g_warning(N_("Bad <presence/>: %s"),xmlnode2str(tag));
		return -1;
	}

	if (!jid_is_my(to)){
		if (strcmp(type,"error"))
			presence_send_error(stream,to,from,406,_("Not Acceptable"));
		g_warning(N_("Wrong 'to' in %s"),xmlnode2str(tag));
		return -1;
	}

	if (!strcmp(type,"available")){
		if (jid_has_uin(to))
			return presence_direct_available(stream,from,to);
		else
			return presence(stream,from,to,1,show,status,priority);
	}
	else if (!strcmp(type,"unavailable")){
		if (jid_has_uin(to))
			return presence_direct_unavailable(stream,from,to);
		else
			return presence(stream,from,to,0,show,status,priority);
	}
	if (!strcmp(type,"invisible")){
		if (jid_has_uin(to))
			return presence_direct_unavailable(stream,from,to);
		else
			return presence(stream,from,to,-1,show,status,priority);
	}
	else if (!strcmp(type,"subscribe"))
		return presence_subscribe(stream,from,to);
	else if (!strcmp(type,"unsubscribe"))
		return presence_unsubscribe(stream,from,to);
	else if (!strcmp(type,"subscribed"))
		return presence_subscribed(stream,from,to);
	else if (!strcmp(type,"unsubscribed"))
		return presence_unsubscribed(stream,from,to);
	else if (!strcmp(type,"probe"))
		return presence_probe(stream,from,to);
	else if (!strcmp(type,"error")){
		g_warning(N_("Error presence received: %s"),xmlnode2str(tag));
		return 0;
	}

	g_warning(N_("Unsupported type in %s"),xmlnode2str(tag));
	presence_send_error(stream,to,from,501,_("Not Implemented"));
	return -1;
}
Esempio n. 4
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;
}