Esempio n. 1
0
static void
close_cb (PecanNode *conn,
          MsnNotification *notification)
{
    char *tmp;

    {
        const char *reason = NULL;

        if (conn->error)
        {
            reason = conn->error->message;

            pecan_error ("connection error: (NS):reason=[%s]", reason);
            tmp = pecan_strdup_printf (_("Error on notification server:\n%s"), reason);

            g_clear_error (&conn->error);
        }
        else
        {
            pecan_error ("connection error: (NS)");
            tmp = pecan_strdup_printf (_("Error on notification server:\nUnknown"));
        }
    }

    pecan_node_close (PECAN_NODE (notification->conn));
    notification->closed = TRUE;
    msn_session_set_error (notification->session, MSN_ERROR_SERVCONN, tmp);

    g_free (tmp);
}
Esempio n. 2
0
static void
xfr_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
    char *host;
    int port;

    if (strcmp(cmd->params[1], "SB") && strcmp(cmd->params[1], "NS"))
    {
        /* Maybe we can have a generic bad command error. */
        pecan_error ("bad XFR command: params=[%s]", cmd->params[1]);
        return;
    }

    msn_parse_socket(cmd->params[2], &host, &port);

    if (!strcmp(cmd->params[1], "SB"))
    {
        pecan_error ("this shouldn't be handled here");
    }
    else if (!strcmp(cmd->params[1], "NS"))
    {
        MsnSession *session;

        session = cmdproc->session;

        msn_session_set_login_step(session, PECAN_LOGIN_STEP_TRANSFER);

        msn_notification_connect(session->notification, host, port);
    }

    g_free(host);
}
Esempio n. 3
0
static void
rea_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
    MsnSession *session;
    const char *who;
    const char *alias;

    session = cmdproc->session;
    who = cmd->params[2];
    alias = purple_url_decode(cmd->params[3]);

    if (strcmp(who, purple_account_get_username (session->account)) == 0)
    {
        /* This is for us. */
        PurpleConnection *gc;
        gc = session->account->gc;
        purple_connection_set_display_name(gc, alias);
    }
    else
    {
        /* This is for a buddy. */
        PecanContact *user;
        user = pecan_contactlist_find_contact(session->contactlist, who);
        if (user)
        {
            pecan_contact_set_store_name(user, alias);
        }
        else
        {
            pecan_error ("unknown user: who=[%s]", who);
            return;
        }
    }
}
Esempio n. 4
0
MsnObject *
msn_object_new_from_string(const gchar *str)
{
    MsnObject *obj;
    gchar *tag, *c;

    g_return_val_if_fail(str != NULL, NULL);

    if (strncmp(str, "<msnobj ", 8))
        return NULL;

    obj = msn_object_new();

    GET_STRING_TAG(creator,  "Creator");
    GET_INT_TAG(size,        "Size");
    GET_INT_TAG(type,        "Type");
    GET_STRING_TAG(location, "Location");
    GET_STRING_TAG(friendly, "Friendly");
    GET_STRING_TAG(sha1d,    "SHA1D");
    GET_STRING_TAG(sha1c,    "SHA1C");

    /* If we are missing any of the required elements then discard the object */
    /* SHA1C is not always sent anymore */
    if (obj->creator == NULL || obj->size == 0 || obj->type == 0
        || obj->location == NULL || obj->friendly == NULL
        || obj->sha1d == NULL /*|| obj->sha1c == NULL*/) {
        pecan_error ("discarding: str=[%s]", str);
        msn_object_destroy(obj);
        obj = NULL;
    }

    return obj;
}
Esempio n. 5
0
static void
error_handler (MsnCmdProc *cmdproc,
               MsnTransaction *trans,
               gint error)
{
    MsnNotification *notification;
    gchar *reason;

    notification = cmdproc->data;
    g_return_if_fail (notification);

    reason = pecan_error_to_string (error);
    pecan_error ("connection error: (NS):reason=[%s]", reason);

    switch (error)
    {
        case 913:
        case 208:
            /* non-fatal */
            break;
        default:
            {
                char *tmp;
                tmp = pecan_strdup_printf (_("Error on notification server:\n%s"), reason);
                msn_session_set_error (notification->session, MSN_ERROR_SERVCONN, tmp);
                g_free (tmp);
            }
    }

    g_free (reason);
}
Esempio n. 6
0
void
msn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
	MsnSession *session;
	MsnSlpLink *slplink;

	session = cmdproc->session;
	slplink = msn_session_get_slplink(session, msg->remote_user);

	if (slplink->swboard == NULL)
	{
		/* We will need this in order to change its flags. */
		slplink->swboard = (MsnSwitchBoard *)cmdproc->data;
		/* If swboard is NULL, something has probably gone wrong earlier on
		 * I didn't want to do this, but MSN 7 is somehow causing us to crash
		 * here, I couldn't reproduce it to debug more, and people are
		 * reporting bugs. Hopefully this doesn't cause more crashes. Stu.
		 */
		if (slplink->swboard != NULL)
			slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink);
		else
			pecan_error ("msn_p2p_msg, swboard is NULL, ouch!");
	}

	msn_slplink_process_msg(slplink, msg);
}
Esempio n. 7
0
static void
email_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
    MsnSession *session;
    PurpleConnection *gc;
    GHashTable *table;
    char *from, *subject, *tmp;

    session = cmdproc->session;
    gc = session->account->gc;

    if (!purple_account_get_check_mail (session->account))
        return;

    if (strcmp(msg->remote_user, "Hotmail"))
    {
        pecan_warning ("unofficial message");
        return;
    }

    if (!session->passport_info.mail_url)
    {
        pecan_error ("no url");
        return;
    }


    table = msn_message_get_hashtable_from_body(msg);

    from = subject = NULL;

    tmp = g_hash_table_lookup(table, "From");
    if (tmp != NULL)
        from = purple_mime_decode_field(tmp);

    tmp = g_hash_table_lookup(table, "Subject");
    if (tmp != NULL)
        subject = purple_mime_decode_field(tmp);

    /** @todo go to the extact email */
    purple_notify_email(gc,
                        (subject != NULL ? subject : ""),
                        (from != NULL ?  from : ""),
                        msn_session_get_username (session),
                        session->passport_info.mail_url, NULL, NULL);

    g_free(from);
    g_free(subject);

    g_hash_table_destroy(table);
}
Esempio n. 8
0
static void
debug_msg_to_file(MsnMessage *msg, gboolean send)
{
	char *tmp;
	char *dir;
	char *pload;
	FILE *tf;
	int c;
	gsize pload_size;

	dir = send ? "send" : "recv";
	c = send ? m_sc++ : m_rc++;
        tmp = pecan_strdup_printf("%s/msntest/%s/%03d", g_get_home_dir(), dir, c);
	tf = g_fopen(tmp, "wb");
	if (tf == NULL)
	{
		pecan_error ("could not open debug file");
		return;
	}
	pload = msn_message_gen_payload(msg, &pload_size);
	fwrite(pload, 1, pload_size, tf);
	fclose(tf);
	g_free(tmp);
}
Esempio n. 9
0
static void
nln_cmd(MsnCmdProc *cmdproc, MsnCommand *cmd)
{
    MsnSession *session;
    PurpleAccount *account;
    PurpleConnection *gc;
    PecanContact *user;
#if defined(PECAN_CVR)
    MsnObject *msnobj;
#endif /* defined(PECAN_CVR) */
    unsigned long clientid;
    const char *state, *passport;
    gchar *friendly;

    session = cmdproc->session;
    account = session->account;
    gc = purple_account_get_connection(account);

    state    = cmd->params[0];
    passport = cmd->params[1];
    friendly = pecan_url_decode(cmd->params[2]);

    user = pecan_contactlist_find_contact(session->contactlist, passport);

    if (!user)
    {
        pecan_error ("unknown user: passport=[%s]", passport);
        return;
    }

    pecan_contact_set_friendly_name(user, friendly);

#if defined(PECAN_CVR)
    if (session->use_userdisplay)
    {
        if (cmd->param_count == 5)
        {
            gchar *tmp;
            tmp = pecan_url_decode(cmd->params[4]);
            msnobj = msn_object_new_from_string(tmp);
            pecan_contact_set_object(user, msnobj);
            g_free (tmp);
        }
        else
        {
            pecan_contact_set_object(user, NULL);
        }
    }
#endif /* defined(PECAN_CVR) */

    clientid = strtoul (cmd->params[3], NULL, 10);
    user->mobile = (clientid & MSN_CLIENT_CAP_MSNMOBILE);

    pecan_contact_set_state(user, state);
    pecan_contact_update(user);

    /* store the friendly name on the server. */
    if (!session->server_alias)
        msn_cmdproc_send (cmdproc, "SBP", "%s %s %s", pecan_contact_get_guid (user), "MFN", cmd->params[2]);

    g_free (friendly);
}
Esempio n. 10
0
void
msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg)
{
	MsnSlpMessage *slpmsg;
	const char *data;
	gsize offset;
	gsize len;

#ifdef PECAN_DEBUG_SLP
	msn_slpmsg_show(msg);
#endif

#ifdef PECAN_DEBUG_SLP_FILES
	debug_msg_to_file(msg, FALSE);
#endif

	if (msg->msnslp_header.total_size < msg->msnslp_header.length)
	{
		pecan_error ("This can't be good");
		g_return_if_reached();
	}

	slpmsg = NULL;
	data = msn_message_get_bin_data(msg, &len);

	/*
		OVERHEAD!
		if (msg->msnslp_header.length < msg->msnslp_header.total_size)
	 */

	offset = msg->msnslp_header.offset;

	if (offset == 0)
	{
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->id = msg->msnslp_header.id;
		slpmsg->session_id = msg->msnslp_header.session_id;
		slpmsg->size = msg->msnslp_header.total_size;
		slpmsg->flags = msg->msnslp_header.flags;

		if (slpmsg->session_id)
		{
			if (slpmsg->slpcall == NULL)
				slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);

			if (slpmsg->slpcall != NULL)
			{
				if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030)
				{
					PurpleXfer *xfer;

					xfer = slpmsg->slpcall->xfer;

					if (xfer != NULL)
					{
						purple_xfer_start(slpmsg->slpcall->xfer,
							0, NULL, 0);
						slpmsg->fp = ((PurpleXfer *)slpmsg->slpcall->xfer)->dest_fp;
						xfer->dest_fp = NULL; /* Disable double fclose() */
					}
				}
			}
		}
		if (!slpmsg->fp && slpmsg->size)
		{
			slpmsg->buffer = g_try_malloc(slpmsg->size);
			if (slpmsg->buffer == NULL)
			{
				pecan_error ("failed to allocate buffer for slpmsg");
				return;
			}
		}
	}
	else
	{
		slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id);
	}

	if (slpmsg == NULL)
	{
		/* Probably the transfer was canceled */
		pecan_error ("couldn't find slpmsg");
		return;
	}

	if (slpmsg->fp)
	{
		/* fseek(slpmsg->fp, offset, SEEK_SET); */
		len = fwrite(data, 1, len, slpmsg->fp);
	}
	else if (slpmsg->size)
	{
		if ((offset + len) > slpmsg->size)
		{
			pecan_error ("oversized slpmsg");
			g_return_if_reached();
		}
		else
			memcpy(slpmsg->buffer + offset, data, len);
	}

	if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) &&
		(slpmsg->slpcall != NULL))
	{
		slpmsg->slpcall->progress = TRUE;

		if (slpmsg->slpcall->progress_cb != NULL)
		{
			slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size,
										 len, offset);
		}
	}

#if 0
	if (slpmsg->buffer == NULL)
		return;
#endif

	if (msg->msnslp_header.offset + msg->msnslp_header.length
		>= msg->msnslp_header.total_size)
	{
		/* All the pieces of the slpmsg have been received */
		MsnSlpCall *slpcall = NULL;

		slpcall = msn_slp_process_msg(slplink, slpmsg);

#ifdef MSN_DIRECTCONN
		if (slpmsg->flags == 0x100)
		{
			MsnDirectConn *directconn;

			directconn = slplink->directconn;

			directconn->ack_recv = TRUE;

			if (!directconn->ack_sent)
			{
				pecan_warning ("bad ACK");
				msn_directconn_send_handshake(directconn);
			}
		}
		else if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 ||
				 slpmsg->flags == 0x1000030)
		{
			/* Release all the messages and send the ACK */

			msn_slplink_send_ack(slplink, msg);
			msn_slplink_unleash(slplink);
		}
#else
                if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 ||
                    slpmsg->flags == 0x1000030)
                {
                    /* Release all the messages and send the ACK */

                    msn_slplink_send_ack(slplink, msg);
                    msn_slplink_unleash(slplink);
                }
#endif /* MSN_DIRECTCONN */

		msn_slpmsg_destroy(slpmsg);

		if (slpcall != NULL && slpcall->wasted)
			msn_slp_call_destroy(slpcall);
	}
}
Esempio n. 11
0
MsnSlpCall *
msn_slp_sip_recv(MsnSlpLink *slplink, const char *body)
{
	MsnSlpCall *slpcall;

	if (body == NULL)
	{
		pecan_warning ("received bogus message");
		return NULL;
	}

	if (!strncmp(body, "INVITE", strlen("INVITE")))
	{
		char *branch;
		char *content;
		char *content_type;

		slpcall = msn_slp_call_new(slplink);

		/* From: <msnmsgr:[email protected]> */
#if 0
		slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");
#endif

		branch = get_token(body, ";branch={", "}");

		slpcall->id = get_token(body, "Call-ID: {", "}");

#if 0
		long content_len = -1;

		temp = get_token(body, "Content-Length: ", "\r\n");
		if (temp != NULL)
			content_len = atoi(temp);
		g_free(temp);
#endif
		content_type = get_token(body, "Content-Type: ", "\r\n");

		content = get_token(body, "\r\n\r\n", NULL);

		got_invite(slpcall, branch, content_type, content);

		g_free(branch);
		g_free(content_type);
		g_free(content);
	}
	else if (!strncmp(body, "MSNSLP/1.0 ", strlen("MSNSLP/1.0 ")))
	{
		char *content;
		char *content_type;
		/* Make sure this is "OK" */
		const char *status = body + strlen("MSNSLP/1.0 ");
		char *call_id;

		call_id = get_token(body, "Call-ID: {", "}");
		slpcall = msn_slplink_find_slp_call(slplink, call_id);
		g_free(call_id);

		g_return_val_if_fail(slpcall != NULL, NULL);

		if (strncmp(status, "200 OK", 6))
		{
			/* It's not valid. Kill this off. */
			char temp[32];
			const char *c;

			/* Eww */
			if ((c = strchr(status, '\r')) || (c = strchr(status, '\n')) ||
				(c = strchr(status, '\0')))
			{
				size_t offset =  c - status;
				if (offset >= sizeof(temp))
					offset = sizeof(temp) - 1;

				strncpy(temp, status, offset);
				temp[offset] = '\0';
			}

			pecan_error ("received non-OK result: %s", temp);

			slpcall->wasted = TRUE;

			/* msn_slp_call_destroy(slpcall); */
			return slpcall;
		}

		content_type = get_token(body, "Content-Type: ", "\r\n");

		content = get_token(body, "\r\n\r\n", NULL);

		got_ok(slpcall, content_type, content);

		g_free(content_type);
		g_free(content);
	}
	else if (!strncmp(body, "BYE", strlen("BYE")))
	{
		char *call_id;

		call_id = get_token(body, "Call-ID: {", "}");
		slpcall = msn_slplink_find_slp_call(slplink, call_id);
		g_free(call_id);

		if (slpcall != NULL)
			slpcall->wasted = TRUE;

		/* msn_slp_call_destroy(slpcall); */
	}
	else
		slpcall = NULL;

	return slpcall;
}
Esempio n. 12
0
static void
got_sessionreq(MsnSlpCall *slpcall, const char *branch,
			   const char *euf_guid, const char *context)
{
	pecan_debug ("euf_guid=[%s]", euf_guid);

	if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6"))
	{
		/* Emoticon or UserDisplay */
		char *content;
		gsize len;
		MsnSlpSession *slpsession;
		MsnSlpLink *slplink;
		MsnSlpMessage *slpmsg;
		MsnObject *obj;
		char *msnobj_data;
		PecanBuffer *image;
		int type;

		/* Send Ok */
                content = pecan_strdup_printf("SessionID: %lu\r\n\r\n",
                                              slpcall->session_id);

		send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody",
				content);

		g_free(content);

		slplink = slpcall->slplink;

		msnobj_data = (char *)purple_base64_decode(context, &len);
		obj = msn_object_new_from_string(msnobj_data);
		type = msn_object_get_type(obj);
		g_free(msnobj_data);

		if (type == MSN_OBJECT_USERTILE)
		{
			/* image is owned by a local object, not obj */
			image = msn_object_get_image(obj);
		}
#if PURPLE_VERSION_CHECK(2,5,0)
		else if (type == MSN_OBJECT_EMOTICON)
		{
			PurpleStoredImage *img;
			char *path;
			path = g_build_filename(purple_smileys_get_storing_dir(), msn_object_get_location(obj), NULL);
			img = purple_imgstore_new_from_file(path);
			image = pecan_buffer_new_memdup ((const gpointer) purple_imgstore_get_data (img),
							 purple_imgstore_get_size (img));
			purple_imgstore_unref(img);
			g_free(path);
		}
#endif /* PURPLE_VERSION_CHECK(2,5,0) */
		else
		{
			pecan_error ("Wrong object?");
			msn_object_destroy(obj);
			g_return_if_reached();
		}

		if (!image)
		{
                    pecan_error ("Wrong object");
                    msn_object_destroy (obj);
                    g_return_if_reached ();
		}

		msn_object_destroy(obj);

		{
			gchar *tmp;
			tmp = msn_object_to_string (obj);
			pecan_info ("object requested: %s", tmp);
			g_free (tmp);
		}

		slpsession = msn_slplink_find_slp_session(slplink,
												  slpcall->session_id);

		/* DATA PREP */
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->slpcall = slpcall;
		slpmsg->slpsession = slpsession;
		slpmsg->session_id = slpsession->id;
		msn_slpmsg_set_body(slpmsg, NULL, 4);
#ifdef PECAN_DEBUG_SLP
		slpmsg->info = "SLP DATA PREP";
#endif
		msn_slplink_queue_slpmsg(slplink, slpmsg);

		/* DATA */
		slpmsg = msn_slpmsg_new(slplink);
		slpmsg->slpcall = slpcall;
		slpmsg->slpsession = slpsession;
		slpmsg->flags = 0x20;
#ifdef PECAN_DEBUG_SLP
		slpmsg->info = "SLP DATA";
#endif
		msn_slpmsg_set_image (slpmsg, image);
		msn_slplink_queue_slpmsg(slplink, slpmsg);
	}
	else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683"))
	{
		/* File Transfer */
		PurpleAccount *account;
		PurpleXfer *xfer;
		char *bin;
		gsize bin_len;
		guint32 file_size;
		char *file_name;
		gunichar2 *uni_name;

		account = slpcall->slplink->session->account;

		slpcall->cb = msn_xfer_completed_cb;
		slpcall->end_cb = msn_xfer_end_cb;
		slpcall->progress_cb = msn_xfer_progress_cb;
		slpcall->branch = g_strdup(branch);

		slpcall->pending = TRUE;

		xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE,
							   slpcall->slplink->remote_user);
		if (xfer)
		{
			bin = (char *)purple_base64_decode(context, &bin_len);
			file_size = GUINT32_FROM_LE(*(gsize *)(bin + 8));

			uni_name = (gunichar2 *)(bin + 20);
			while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) {
				*uni_name = GUINT16_FROM_LE(*uni_name);
				uni_name++;
			}

			file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1,
										NULL, NULL, NULL);

			g_free(bin);

			purple_xfer_set_filename(xfer, file_name);
			purple_xfer_set_size(xfer, file_size);
			purple_xfer_set_init_fnc(xfer, msn_xfer_init);
			purple_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel);
			purple_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel);

			slpcall->xfer = xfer;
			purple_xfer_ref(slpcall->xfer);

			xfer->data = slpcall;

			purple_xfer_request(xfer);
		}
	}
}