void
pecan_cmd_server_free (PecanCmdServer *conn)
{
    pecan_log ("begin");
    g_object_unref (G_OBJECT (conn));
    pecan_log ("end");
}
static void
dispose (GObject *obj)
{
    PecanCmdServer *cmd_conn = CMD_PECAN_NODE (obj);

    pecan_log ("begin");

    if (cmd_conn->cmdproc)
    {
        msn_cmdproc_destroy (cmd_conn->cmdproc);
        cmd_conn->cmdproc = NULL;
    }

    G_OBJECT_CLASS (parent_class)->dispose (obj);

    pecan_log ("end");
}
PecanCmdServer *
pecan_cmd_server_new (const gchar *name,
                      PecanNodeType type)
{
    PecanCmdServer *conn;

    pecan_log ("begin");

    conn = CMD_PECAN_NODE (g_type_create_instance (CMD_PECAN_NODE_TYPE));

    {
        PecanNode *tmp = PECAN_NODE (conn);
        tmp->name = g_strdup (name);
        tmp->type = type;
    }

    pecan_log ("end");

    return conn;
}
Example #4
0
static void
error_cb (PecanNode *node,
          gpointer arg,
          gpointer data)
{
    PecanSession *session;
    PecanSessionPrivate *priv;

    session = PECAN_SESSION (data);
    priv = session->priv;

    pecan_log ("begin");

    {
        PecanSessionClass *class;
        class = g_type_class_peek (PECAN_SESSION_TYPE);
        g_signal_emit (G_OBJECT (session), class->error_sig, 0, arg);
    }

    pecan_log ("end");
}
static void
close_impl (PecanNode *conn)
{
    PecanCmdServer *cmd_conn;

    pecan_log ("begin");

    cmd_conn = CMD_PECAN_NODE (conn);

    g_free (cmd_conn->rx_buf);
    cmd_conn->rx_buf = NULL;
    cmd_conn->rx_len = 0;
    cmd_conn->payload_len = 0;

    if (cmd_conn->cmdproc)
        msn_cmdproc_flush (cmd_conn->cmdproc);

    PECAN_NODE_CLASS (parent_class)->close (conn);

    pecan_log ("end");
}
Example #6
0
static void
open_cb (PecanNode *conn,
         MsnNotification *notification)
{
    MsnSession *session;
    PecanCmdServer *cmd_conn;

    g_return_if_fail (conn != NULL);

    pecan_log ("begin");

    session = conn->session;
    cmd_conn = CMD_PECAN_NODE (conn);

    if (session->login_step == PECAN_LOGIN_STEP_START)
        msn_session_set_login_step (session, PECAN_LOGIN_STEP_HANDSHAKE);
    else
        msn_session_set_login_step (session, PECAN_LOGIN_STEP_HANDSHAKE2);

    msn_cmdproc_send (cmd_conn->cmdproc, "VER", "MSNP12 CVR0");

    pecan_log ("end");
}
/** @todo add extensive tests for this */
static void
parse_impl (PecanNode *base_conn,
            gchar *buf,
            gsize bytes_read)
{
    PecanCmdServer *cmd_conn;
    gchar *cur, *end, *old_rx_buf;
    gint cur_len;

    pecan_log ("begin");

    pecan_debug ("conn=%p,name=%s", base_conn, base_conn->name);

    cmd_conn = CMD_PECAN_NODE (base_conn);

    buf[bytes_read] = '\0';

    cmd_conn->rx_buf = g_realloc (cmd_conn->rx_buf, bytes_read + cmd_conn->rx_len + 1);
    memcpy (cmd_conn->rx_buf + cmd_conn->rx_len, buf, bytes_read + 1);
    cmd_conn->rx_len += bytes_read;

    end = old_rx_buf = cmd_conn->rx_buf;
    cmd_conn->rx_buf = NULL;

    do
    {
        cur = end;

        if (cmd_conn->payload_len)
        {
            if (cmd_conn->payload_len > cmd_conn->rx_len)
                /* The payload is still not complete. */
                break;

            cur_len = cmd_conn->payload_len;
            end += cur_len;
        }
        else
        {
            end = strstr(cur, "\r\n");

            if (end == NULL)
                /* The command is still not complete. */
                break;

            *end = '\0';
            end += 2;
            cur_len = end - cur;
        }

        cmd_conn->rx_len -= cur_len;

        if (cmd_conn->cmdproc)
        {
            if (cmd_conn->payload_len)
            {
                msn_cmdproc_process_payload (cmd_conn->cmdproc, cur, cur_len);
                cmd_conn->payload_len = 0;
            }
            else
            {
                msn_cmdproc_process_cmd_text (cmd_conn->cmdproc, cur);
                cmd_conn->payload_len = cmd_conn->cmdproc->last_cmd->payload_len;
            }
        }
    } while (cmd_conn->rx_len > 0);

    if (cmd_conn->rx_len > 0)
        cmd_conn->rx_buf = g_memdup (cur, cmd_conn->rx_len);
    else
        cmd_conn->rx_buf = NULL;

    g_free (old_rx_buf);

    pecan_log ("end");
}
Example #8
0
void
login_connect_cb(gpointer data, PurpleSslConnection *gsc,
				 PurpleInputCondition cond)
{
	MsnNexus *nexus;
	MsnSession *session;
	char *username, *password;
	char *request_str, *head, *tail;
	char *buffer = NULL;
	guint32 ctint;

	nexus = data;
	g_return_if_fail(nexus != NULL);

	session = nexus->session;
	g_return_if_fail(session != NULL);

	msn_session_set_login_step(session, PECAN_LOGIN_STEP_GET_COOKIE);

	username =
		g_strdup(purple_url_encode(msn_session_get_username(session)));

	password =
		g_strdup(purple_url_encode(msn_session_get_password(session)));

	ctint = strtoul((char *)g_hash_table_lookup(nexus->challenge_data, "ct"), NULL, 10) + 200;

        head = pecan_strdup_printf(
                                   "GET %s HTTP/1.1\r\n"
                                   "Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s",
                                   nexus->login_path,
                                   (char *)g_hash_table_lookup(nexus->challenge_data, "ru"),
                                   username);

        tail = pecan_strdup_printf(
                                   "lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%" G_GUINT32_FORMAT ",kpp=%s,kv=%s,ver=%s,tpf=%s\r\n"
                                   "User-Agent: MSMSGS\r\n"
                                   "Host: %s\r\n"
                                   "Connection: Keep-Alive\r\n"
                                   "Cache-Control: no-cache\r\n",
                                   nexus_challenge_data_lookup(nexus->challenge_data, "lc"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "id"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "tw"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "fs"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "ru"),
                                   ctint,
                                   nexus_challenge_data_lookup(nexus->challenge_data, "kpp"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "kv"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "ver"),
                                   nexus_challenge_data_lookup(nexus->challenge_data, "tpf"),
                                   nexus->login_host);

	buffer = pecan_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail);
	request_str = pecan_strdup_printf("%s,pwd=%s,%s\r\n", head, password, tail);

	pecan_log ("sending: [%s]", buffer);

	g_free(buffer);
	g_free(head);
	g_free(tail);
	g_free(username);
	g_free(password);

	nexus->write_buf = request_str;
	nexus->written_len = 0;

	nexus->read_len = 0;

	nexus->written_cb = nexus_login_written_cb;

	nexus->input_handler = purple_input_add(gsc->fd, PURPLE_INPUT_WRITE,
		nexus_write_cb, nexus);

	nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE);

	return;


}
Example #9
0
static void
nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	MsnNexus *nexus = data;
	MsnSession *session;
	int len;

	session = nexus->session;
	g_return_if_fail(session != NULL);

	if (nexus->input_handler == 0)
		/* TODO: Use purple_ssl_input_add()? */
		nexus->input_handler = purple_input_add(nexus->gsc->fd,
			PURPLE_INPUT_READ, nexus_login_written_cb, nexus);


	len = msn_ssl_read(nexus);

	if (len < 0 && errno == EAGAIN)
		return;
	else if (len < 0) {
		purple_input_remove(nexus->input_handler);
		nexus->input_handler = 0;
		g_free(nexus->read_buf);
		nexus->read_buf = NULL;
		nexus->read_len = 0;
		/* TODO: error handling */
		return;
	}

	if (g_strstr_len(nexus->read_buf, nexus->read_len,
			"\r\n\r\n") == NULL)
		return;

	purple_input_remove(nexus->input_handler);
	nexus->input_handler = 0;

	purple_ssl_close(nexus->gsc);
	nexus->gsc = NULL;

	pecan_log ("ssl buffer: [%s]", nexus->read_buf);

	if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL)
	{
		/* Redirect. */
		char *location, *c;

		location = strstr(nexus->read_buf, "Location: ");
		if (location == NULL)
		{
			g_free(nexus->read_buf);
			nexus->read_buf = NULL;
			nexus->read_len = 0;

			return;
		}
		location = strchr(location, ' ') + 1;

		if ((c = strchr(location, '\r')) != NULL)
			*c = '\0';

		/* Skip the http:// */
		if ((c = strchr(location, '/')) != NULL)
			location = c + 2;

		if ((c = strchr(location, '/')) != NULL)
		{
			g_free(nexus->login_path);
			nexus->login_path = g_strdup(c);

			*c = '\0';
		}

		g_free(nexus->login_host);
		nexus->login_host = g_strdup(location);

		nexus->gsc = purple_ssl_connect(session->account,
				nexus->login_host, PURPLE_SSL_DEFAULT_PORT,
				login_connect_cb, login_error_cb, nexus);
	}
	else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL)
	{
		const char *error;

		if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL)
		{
			if ((error = strstr(error, "cbtxt=")) != NULL)
			{
				const char *c;
				char *temp;

				error += strlen("cbtxt=");

				if ((c = strchr(error, '\n')) == NULL)
					c = error + strlen(error);

				temp = g_strndup(error, c - error);
				error = purple_url_decode(temp);
				g_free(temp);
				if ((temp = strstr(error, " Do one of the following or try again:")) != NULL)
					*temp = '\0';
			}
		}

		msn_session_set_error(session, MSN_ERROR_AUTH, error);
	}
	else if (strstr(nexus->read_buf, "HTTP/1.1 503 Service Unavailable"))
	{
		msn_session_set_error(session, MSN_ERROR_SERV_UNAVAILABLE, NULL);
	}
	else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK"))
	{
		char *base, *c;
		char *login_params;

#if 0
		/* All your base are belong to us. */
		base = buffer;

		/* For great cookie! */
		while ((base = strstr(base, "Set-Cookie: ")) != NULL)
		{
			base += strlen("Set-Cookie: ");

			c = strchr(base, ';');

			session->login_cookies =
				g_list_append(session->login_cookies,
							  g_strndup(base, c - base));
		}
#endif

		base  = strstr(nexus->read_buf, "Authentication-Info: ");

		g_return_if_fail(base != NULL);

		base  = strstr(base, "from-PP='");
		base += strlen("from-PP='");
		c     = strchr(base, '\'');

		login_params = g_strndup(base, c - base);

		msn_got_login_params(session, login_params);

		g_free(login_params);

		msn_nexus_destroy(nexus);
		session->nexus = NULL;
		return;
	}

	g_free(nexus->read_buf);
	nexus->read_buf = NULL;
	nexus->read_len = 0;

}
Example #10
0
static void
got_ok(MsnSlpCall *slpcall,
	   const char *type, const char *content)
{
	g_return_if_fail(slpcall != NULL);
	g_return_if_fail(type    != NULL);

        pecan_log ("type=%s", type);

	if (!strcmp(type, "application/x-msnmsgr-sessionreqbody"))
	{
#ifdef MSN_DIRECTCONN
		if (slpcall->slplink->session->use_directconn &&
                    slpcall->type == MSN_SLPCALL_DC)
		{
			/* First let's try a DirectConnection. */

			MsnSlpLink *slplink;
			MsnSlpMessage *slpmsg;
			char *header;
			gchar *new_content;
			char *branch;

			slplink = slpcall->slplink;

			branch = msn_rand_guid();

                        new_content = pecan_strdup_printf(
                                                          "Bridges: TRUDPv1 TCPv1\r\n"
                                                          "NetID: 0\r\n"
                                                          "Conn-Type: Direct-Connect\r\n"
                                                          "UPnPNat: false\r\n"
                                                          "ICF: false\r\n"
                                                         );

                        header = pecan_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0",
                                                     slplink->remote_user);

			slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, branch,
										"application/x-msnmsgr-transreqbody",
										new_content);

#ifdef PECAN_DEBUG_SLP
			slpmsg->info = "SLP INVITE";
			slpmsg->text_body = TRUE;
#endif
			msn_slplink_send_slpmsg(slplink, slpmsg);

			g_free(header);
			g_free(new_content);

			g_free(branch);
		}
		else
		{
			msn_slp_call_session_init(slpcall);
		}
#else
                msn_slp_call_session_init(slpcall);
#endif /* MSN_DIRECTCONN */
	}
	else if (!strcmp(type, "application/x-msnmsgr-transreqbody"))
	{
		/* Do we get this? */
		pecan_info ("OK with transreqbody");
	}
#ifdef MSN_DIRECTCONN
	else if (!strcmp(type, "application/x-msnmsgr-transrespbody"))
	{
		char *ip_addrs;
		char *temp;
		char *nonce;
		int port;

		{
			char *listening;
			listening = get_token(content, "Listening: ", "\r\n");
			if (strcmp (listening, "false") == 0)
			{
				/** @todo I'm not sure if this is OK. */
				msn_slp_call_session_init(slpcall);
				g_free (listening);
				return;
			}
			g_free (listening);
		}

		nonce = get_token(content, "Nonce: {", "}\r\n");
		ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n");

		temp = get_token(content, "IPv4Internal-Port: ", "\r\n");
		if (temp != NULL)
			port = atoi(temp);
		else
			port = -1;
		g_free(temp);

		if (ip_addrs == NULL)
			return;

		if (port > 0)
			got_transresp(slpcall, nonce, ip_addrs, port);

		g_free(nonce);
		g_free(ip_addrs);
	}
#endif /* MSN_DIRECTCONN */
}
Example #11
0
static void
got_invite(MsnSlpCall *slpcall,
		   const char *branch, const char *type, const char *content)
{
	MsnSlpLink *slplink;

	slplink = slpcall->slplink;

        pecan_log ("type=%s", type);

	if (!strcmp(type, "application/x-msnmsgr-sessionreqbody"))
	{
		char *euf_guid, *context;
		char *temp;

		euf_guid = get_token(content, "EUF-GUID: {", "}\r\n");

		temp = get_token(content, "SessionID: ", "\r\n");
		if (temp != NULL)
			slpcall->session_id = atoi(temp);
		g_free(temp);

		temp = get_token(content, "AppID: ", "\r\n");
		if (temp != NULL)
			slpcall->app_id = atoi(temp);
		g_free(temp);

		context = get_token(content, "Context: ", "\r\n");

		if (context != NULL)
			got_sessionreq(slpcall, branch, euf_guid, context);

		g_free(context);
		g_free(euf_guid);
	}
	else if (!strcmp(type, "application/x-msnmsgr-transreqbody"))
	{
		/* A direct connection? */

		const gchar *listening;
		gchar *new_content, *nonce;

		if (FALSE)
		{
#if 0
			MsnDirectConn *directconn;
			/* const char *ip_addr; */
			char *ip_port;
			int port;

			/* ip_addr = purple_prefs_get_string("/purple/ft/public_ip"); */
			ip_port = "5190";
			listening = "true";
			nonce = msn_rand_guid();

			directconn = msn_directconn_new(slplink);

			/* msn_directconn_parse_nonce(directconn, nonce); */
			directconn->nonce = g_strdup(nonce);

			msn_directconn_listen(directconn);

			port = directconn->port;

                        new_content = pecan_strdup_printf(
                                                          "Bridge: TCPv1\r\n"
                                                          "Listening: %s\r\n"
                                                          "Nonce: {%s}\r\n"
                                                          "Ipv4Internal-Addrs: 192.168.0.82\r\n"
                                                          "Ipv4Internal-Port: %d\r\n"
                                                          "\r\n",
                                                          listening,
                                                          nonce,
                                                          port);
#endif
		}
		else
		{
			listening = "false";
			nonce = g_strdup("00000000-0000-0000-0000-000000000000");

                        new_content = pecan_strdup_printf(
                                                          "Bridge: TCPv1\r\n"
                                                          "Listening: %s\r\n"
                                                          "Nonce: {%s}\r\n"
                                                          "\r\n",
                                                          listening,
                                                          nonce);
		}

		send_ok(slpcall, branch,
				"application/x-msnmsgr-transrespbody", new_content);

		g_free(new_content);
		g_free(nonce);
	}
#ifdef MSN_DIRECTCONN
	else if (!strcmp(type, "application/x-msnmsgr-transrespbody"))
	{
		char *ip_addrs;
		char *temp;
		char *nonce;
		int port;

		nonce = get_token(content, "Nonce: {", "}\r\n");
		ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n");

		temp = get_token(content, "IPv4Internal-Port: ", "\r\n");
		if (temp != NULL)
			port = atoi(temp);
		else
			port = -1;
		g_free(temp);

		if (ip_addrs == NULL)
			return;

		if (port > 0)
			got_transresp(slpcall, nonce, ip_addrs, port);

		g_free(nonce);
		g_free(ip_addrs);
	}
#endif /* MSN_DIRECTCONN */
}