示例#1
0
static JabberSaslState
jabber_cyrus_handle_challenge(JabberStream *js, xmlnode *packet,
                              xmlnode **reply, char **error)
{
	char *enc_in = xmlnode_get_data(packet);
	unsigned char *dec_in;
	char *enc_out;
	const char *c_out;
	unsigned int clen;
	gsize declen;

	dec_in = purple_base64_decode(enc_in, &declen);

	js->sasl_state = sasl_client_step(js->sasl, (char*)dec_in, declen,
					  NULL, &c_out, &clen);
	g_free(enc_in);
	g_free(dec_in);
	if (js->sasl_state != SASL_CONTINUE && js->sasl_state != SASL_OK) {
		gchar *tmp = g_strdup_printf(_("SASL error: %s"),
				sasl_errdetail(js->sasl));
		purple_debug_error("jabber", "Error is %d : %s\n",
				js->sasl_state, sasl_errdetail(js->sasl));
		*error = tmp;
		return JABBER_SASL_STATE_FAIL;
	} else {
		xmlnode *response = xmlnode_new("response");
		xmlnode_set_namespace(response, NS_XMPP_SASL);
		if (clen > 0) {
			/* Cyrus SASL 2.1.22 appears to contain code to add the charset
			 * to the response for DIGEST-MD5 but there is no possibility
			 * it will be executed.
			 *
			 * My reading of the digestmd5 plugin indicates the username and
			 * realm are always encoded in UTF-8 (they seem to be the values
			 * we pass in), so we need to ensure charset=utf-8 is set.
			 */
			if (!purple_strequal(js->current_mech, "DIGEST-MD5") ||
					strstr(c_out, ",charset="))
				/* If we're not using DIGEST-MD5 or Cyrus SASL is fixed */
				enc_out = purple_base64_encode((unsigned char*)c_out, clen);
			else {
				char *tmp = g_strdup_printf("%s,charset=utf-8", c_out);
				enc_out = purple_base64_encode((unsigned char*)tmp, clen + 14);
				g_free(tmp);
			}

			xmlnode_insert_data(response, enc_out, -1);
			g_free(enc_out);
		}

		*reply = response;
		return JABBER_SASL_STATE_CONTINUE;
	}
}
示例#2
0
文件: httpconn.c 项目: bf4/pidgin-mac
static char *
msn_httpconn_proxy_auth(MsnHttpConn *httpconn)
{
	PurpleAccount *account;
	PurpleProxyInfo *gpi;
	const char *username, *password;
	char *auth = NULL;

	account = httpconn->session->account;

	gpi = purple_proxy_get_setup(account);

	if (gpi == NULL || !(purple_proxy_info_get_type(gpi) == PURPLE_PROXY_HTTP ||
						 purple_proxy_info_get_type(gpi) == PURPLE_PROXY_USE_ENVVAR))
		return NULL;

	username = purple_proxy_info_get_username(gpi);
	password = purple_proxy_info_get_password(gpi);

	if (username != NULL) {
		char *tmp;
		auth = g_strdup_printf("%s:%s", username, password ? password : "");
		tmp = purple_base64_encode((const guchar *)auth, strlen(auth));
		g_free(auth);
		auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp);
		g_free(tmp);
	}

	return auth;
}
示例#3
0
/* TODO find a way to do this without libpurple */
static inline char *
get_auth(PnNode *conn)
{
    const char *username, *password;
    PurpleProxyInfo *gpi;
    char *tmp, *auth;

    gpi = purple_proxy_get_setup(msn_session_get_user_data(conn->session));
    if (!gpi)
        return NULL;

    if (purple_proxy_info_get_type(gpi) != PURPLE_PROXY_HTTP &&
        purple_proxy_info_get_type(gpi) != PURPLE_PROXY_USE_ENVVAR)
        return NULL;

    username = purple_proxy_info_get_username(gpi);
    password = purple_proxy_info_get_password(gpi);
    if (!username && !password)
        return NULL;

    auth = g_strdup_printf("%s:%s", username ? username : "", password ? password : "");
    tmp = purple_base64_encode((const guchar *) auth, strlen(auth));
    g_free(auth);
    auth = g_strdup_printf("Proxy-Authorization: Basic %s\r\n", tmp);
    g_free(tmp);

    return auth;
}
示例#4
0
/*------------------------------------------------------------------------
 * Adds a link to a message
 *
 *  @param mx				The Markup message object
 *	@param replydata		This is the what will be returned when the link gets clicked
 *	@param isStructured		Indicates that the reply is a structured reply
 *	@param displaytext		This is the text for the link which will be displayed in the UI
 */
void mxit_add_html_link( struct RXMsgData* mx, const char* replydata, gboolean isStructured, const char* displaytext )
{
#ifdef	MXIT_LINK_CLICK
	gchar*	link	= NULL;
	gchar*	link64	= NULL;

	/*
	 * The link content is encoded as follows:
	 *  MXIT_LINK_KEY | ACCOUNT_USER | ACCOUNT_PROTO | REPLY_TO | REPLY_FORMAT | REPLY_DATA
	 */
	link = g_strdup_printf( "%s|%s|%s|%s|%i|%s",
			MXIT_LINK_KEY,
			purple_account_get_username( mx->session->acc ),
			purple_account_get_protocol_id( mx->session->acc ),
			mx->from,
			isStructured ? 1 : 0,
			replydata );
	link64 = purple_base64_encode( (const unsigned char*) link, strlen( link ) );

	g_string_append_printf( mx->msg, "<a href=\"%s%s\">%s</a>", MXIT_LINK_PREFIX, link64, displaytext );

	g_free( link64 );
	g_free( link );
#else
	g_string_append_printf( mx->msg, "<b>%s</b>", replydata );
#endif
}
示例#5
0
static gchar   *twitter_oauth_sign(const gchar * txt, const gchar * key)
{
    PurpleCipher   *cipher;
    PurpleCipherContext *ctx;
    static guchar   output[20];
    size_t          output_size;

    cipher = purple_ciphers_find_cipher("hmac");
    if (!cipher) {
        purple_debug_error(GENERIC_PROTOCOL_ID, "%s: Could not find cipher\n", G_STRFUNC);
        return NULL;
    }
    ctx = purple_cipher_context_new(cipher, NULL);
    if (!ctx) {
        purple_debug_error(GENERIC_PROTOCOL_ID, "%s: Could not create cipher context\n", G_STRFUNC);
        return NULL;
    }
    purple_cipher_context_set_option(ctx, "hash", "sha1");

    purple_cipher_context_set_key(ctx, (guchar *) key);
    purple_cipher_context_append(ctx, (guchar *) txt, strlen(txt));
    if (!purple_cipher_context_digest(ctx, 20, output, &output_size)) {
        purple_debug_error(GENERIC_PROTOCOL_ID, "%s: Could not sign text\n", G_STRFUNC);
        purple_cipher_context_destroy(ctx);
        return NULL;
    }
    purple_cipher_context_destroy(ctx);
    return purple_base64_encode(output, output_size);

}
示例#6
0
/*encode the message to OIM Message Format*/
static gchar *
msn_oim_msg_to_str(MsnOim *oim, const char *body)
{
	GString *oim_body;
	char *oim_base64;
	char *c;
	int len;
	size_t base64_len;

	purple_debug_info("msn", "Encoding OIM Message...\n");
	len = strlen(body);
	c = oim_base64 = purple_base64_encode((const guchar *)body, len);
	base64_len = strlen(oim_base64);
	purple_debug_info("msn", "Encoded base64 body:{%s}\n", oim_base64);

	oim_body = g_string_new(NULL);
	g_string_printf(oim_body, MSN_OIM_MSG_TEMPLATE,
		oim->run_id, oim->send_seq);

#define OIM_LINE_LEN 76
	while (base64_len > OIM_LINE_LEN) {
		g_string_append_len(oim_body, c, OIM_LINE_LEN);
		g_string_append_c(oim_body, '\n');
		c += OIM_LINE_LEN;
		base64_len -= OIM_LINE_LEN;
	}
#undef OIM_LINE_LEN

	g_string_append(oim_body, c);

	g_free(oim_base64);

	return g_string_free(oim_body, FALSE);
}
示例#7
0
static gchar *
gen_context(const char *file_name,
            const char *file_path)
{
    struct stat st;
    gsize size = 0;
    MsnContextHeader header;
    gchar *u8 = NULL;
    guchar *base;
    guchar *n;
    gchar *ret;
    gunichar2 *uni = NULL;
    glong currentChar = 0;
    glong uni_len = 0;
    gsize len;

    if (g_stat(file_path, &st) == 0)
        size = st.st_size;

    if(!file_name) {
        u8 = purple_utf8_try_convert(g_basename(file_path));
        file_name = u8;
    }

    uni = g_utf8_to_utf16(file_name, -1, NULL, &uni_len, NULL);

    if(u8) {
        g_free(u8);
        file_name = NULL;
        u8 = NULL;
    }

    len = sizeof(MsnContextHeader) + MAX_FILE_NAME_LEN + 4;

    header.length = GUINT32_TO_LE(len);
    header.unk1 = GUINT32_TO_LE(2);
    header.file_size = GUINT32_TO_LE(size);
    header.unk2 = GUINT32_TO_LE(0);
    header.unk3 = GUINT32_TO_LE(0);

    base = g_malloc(len + 1);
    n = base;

    memcpy(n, &header, sizeof(MsnContextHeader));
    n += sizeof(MsnContextHeader);

    memset(n, 0x00, MAX_FILE_NAME_LEN);
    for(currentChar = 0; currentChar < uni_len; currentChar++) {
        *((gunichar2 *)n + currentChar) = GUINT16_TO_LE(uni[currentChar]);
    }
    n += MAX_FILE_NAME_LEN;

    memset(n, 0xFF, 4);
    n += 4;

    g_free(uni);
    ret = purple_base64_encode(base, len);
    g_free(base);
    return ret;
}
示例#8
0
void
msn_slplink_request_object(MsnSlpLink *slplink,
						   const char *info,
						   MsnSlpCb cb,
						   MsnSlpEndCb end_cb,
						   const MsnObject *obj)
{
	MsnSlpCall *slpcall;
	char *msnobj_data;
	char *msnobj_base64;

	g_return_if_fail(slplink != NULL);
	g_return_if_fail(obj     != NULL);

	msnobj_data = msn_object_to_string(obj);
	msnobj_base64 = purple_base64_encode((const guchar *)msnobj_data, strlen(msnobj_data));
	g_free(msnobj_data);

	slpcall = msn_slpcall_new(slplink);
	msn_slpcall_init(slpcall, MSN_SLPCALL_ANY);

	slpcall->data_info = g_strdup(info);
	slpcall->cb = cb;
	slpcall->end_cb = end_cb;

	msn_slpcall_invite(slpcall, MSN_OBJ_GUID, 1, msnobj_base64);

	g_free(msnobj_base64);
}
示例#9
0
/*encode the str to RFC2047 style
 * Currently only support the UTF-8 and base64 encode
 */
char *
msn_encode_mime(const char *str)
{
    gchar *base64, *retval;

    g_return_val_if_fail(str != NULL, NULL);

    base64 = purple_base64_encode((guchar *)str, strlen(str));
    retval = g_strdup_printf("=?utf-8?B?%s?=", base64);
    g_free(base64);

    return retval;
}
示例#10
0
/**
 * @return A null-terminated base64 encoded version of the HMAC
 *         calculated using the given key and data.
 */
static gchar *hmac_sha256(const char *key, const char *message)
{
    PurpleCipherContext *context;
    guchar digest[32];

    context = purple_cipher_context_new_by_name("hmac", NULL);
    purple_cipher_context_set_option(context, "hash", "sha256");
    purple_cipher_context_set_key(context, (guchar *)key);
    purple_cipher_context_append(context, (guchar *)message, strlen(message));
    purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
    purple_cipher_context_destroy(context);

    return purple_base64_encode(digest, sizeof(digest));
}
示例#11
0
void mrim_package_add_base64(MrimPackage *pack, gchar *fmt, ...) {
	gchar *buffer = NULL;
	gsize buffer_size = 0;
	va_list ap;
	va_start(ap, fmt);
	while (*fmt) {
		switch (*fmt) {
			case 'u':
				{
					guint32 value = va_arg(ap, guint32);
					buffer = g_realloc(buffer, buffer_size + sizeof(guint32));
					g_memmove(buffer + buffer_size, &value, sizeof(guint32));
					buffer_size += sizeof(guint32);
				}			
				break;
			case 's': //CP1251
				{
					gchar *string = va_arg(ap, gchar*);
					gsize str_len = g_utf8_strlen(string, -1);
					buffer = g_realloc(buffer, buffer_size + sizeof(guint32) + str_len);
					g_memmove(buffer + buffer_size, &str_len, sizeof(guint32));
					gchar *str = g_convert_with_fallback(string, -1, "CP1251" , "UTF8", NULL, NULL, NULL, NULL);
					g_memmove(buffer + buffer_size + sizeof(guint32), str, str_len);
					g_free(str);
					buffer_size += sizeof(guint32) + str_len;
				}
				break;
			case 'w': //UTF16
				{
					gchar *string = va_arg(ap, gchar*);
					gsize str_len = g_utf8_strlen(string, -1) * sizeof(gunichar2);
					buffer = g_realloc(buffer, buffer_size + sizeof(guint32) + str_len);
					g_memmove(buffer + buffer_size, &str_len, sizeof(guint32));
					gunichar2 *str = g_utf8_to_utf16(string, -1, NULL, NULL, NULL);
					g_memmove(buffer + buffer_size + sizeof(guint32), str, str_len);
					g_free(str);
					buffer_size += sizeof(guint32) + str_len;
				}
				break;
		}
		fmt++;
	}
	va_end(ap);
	gchar *encoded = purple_base64_encode((gchar*)buffer, buffer_size);
	guint32 encoded_len = strlen(encoded);
	mrim_package_add_UL(pack, encoded_len);
	mrim_package_add_raw(pack, encoded, encoded_len);
	g_free(encoded);
	g_free(buffer);
}
示例#12
0
文件: data.c 项目: psunkari/spicebird
xmlnode *
jabber_data_get_xml_definition(const JabberData *data)
{
    xmlnode *tag = xmlnode_new("data");
    char *base64data = purple_base64_encode(data->data, data->size);

    xmlnode_set_namespace(tag, NS_BOB);
    xmlnode_set_attrib(tag, "cid", data->cid);
    xmlnode_set_attrib(tag, "type", data->type);

    xmlnode_insert_data(tag, base64data, -1);

    g_free(base64data);

    return tag;
}
示例#13
0
void twitter_send_request(PurpleAccount *account, gboolean post,
		const char *url, const char *query_string, 
		TwitterSendRequestSuccessFunc success_callback, TwitterSendRequestErrorFunc error_callback,
		gpointer data)
{
	gchar *request;
	const char *pass = purple_connection_get_password(purple_account_get_connection(account));
	const char *sn = purple_account_get_username(account);
	char *auth_text = g_strdup_printf("%s:%s", sn, pass);
	char *auth_text_b64 = purple_base64_encode((guchar *) auth_text, strlen(auth_text));
	gboolean use_https = purple_account_get_bool(account, "use_https", FALSE) && purple_ssl_is_supported();
	char *host = "twitter.com";
	TwitterSendRequestData *request_data = g_new0(TwitterSendRequestData, 1);
	char *full_url = g_strdup_printf("%s://%s%s",
			use_https ? "https" : "http",
			host,
			url);
	request_data->account = account;
	request_data->user_data = data;
	request_data->success_func = success_callback;
	request_data->error_func = error_callback;

	g_free(auth_text);

	request = g_strdup_printf(
			"%s %s%s%s HTTP/1.0\r\n"
			"User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n"
			"Host: %s\r\n"
			"Authorization: Basic %s\r\n"
			"Content-Length: %d\r\n\r\n"
			"%s",
			post ? "POST" : "GET",
			full_url,
			(!post && query_string ? "?" : ""), (!post && query_string ? query_string : ""),
			host,
			auth_text_b64,
			query_string  && post ? strlen(query_string) : 0,
			query_string && post ? query_string : "");

	g_free(auth_text_b64);
	purple_util_fetch_url_request(full_url, TRUE,
			"Mozilla/4.0 (compatible; MSIE 5.5)", TRUE, request, FALSE,
			twitter_send_request_cb, request_data);
	g_free(full_url);
	g_free(request);
}
示例#14
0
void
campfire_http_request(CampfireSslTransaction * xaction, gchar * uri,
		      gchar * method, xmlnode * postxml)
{
	CampfireConn *conn = xaction->campfire;
	const char *api_token =
		purple_account_get_string(conn->account, "api_token", "");
	gchar *xmlstr = NULL, *len = NULL, *encoded = NULL;
	gsize auth_len;

	xaction->http_request = g_string_new(method);
	g_string_append(xaction->http_request, " ");
	g_string_append(xaction->http_request, uri);
	g_string_append(xaction->http_request, " HTTP/1.1\r\n");

	g_string_append(xaction->http_request,
			"Content-Type: application/xml\r\n");

	g_string_append(xaction->http_request, "Authorization: Basic ");
	auth_len = strlen(api_token);
	encoded = purple_base64_encode((const guchar *) api_token, auth_len);
	g_string_append(xaction->http_request, encoded);
	g_string_append(xaction->http_request, "\r\n");
	g_free(encoded);

	g_string_append(xaction->http_request, "Host: ");
	g_string_append(xaction->http_request, conn->hostname);
	g_string_append(xaction->http_request, "\r\n");

	g_string_append(xaction->http_request, "Accept: */*\r\n");

	if (postxml) {
		xmlstr = xmlnode_to_str(postxml, NULL);
		g_string_append(xaction->http_request, "Content-Length: ");
		/* len = g_strdup_printf("%lu", strlen(xmlstr)); */
		len = g_strdup_printf("%" G_GSIZE_FORMAT, strlen(xmlstr));
		g_string_append(xaction->http_request, len);
		g_free(len);
		g_string_append(xaction->http_request, "\r\n\r\n");
		g_string_append(xaction->http_request, xmlstr);
		g_string_append(xaction->http_request, "\r\n");
	}
	g_string_append(xaction->http_request, "\r\n");
	purple_debug_info("campfire", "Formatted request:\n%s\n",
			  xaction->http_request->str);
}
示例#15
0
void
jabber_ibb_session_send_data(JabberIBBSession *sess, gconstpointer data,
                             gsize size)
{
	JabberIBBSessionState state = jabber_ibb_session_get_state(sess);

	purple_debug_info("jabber", "sending data block of %" G_GSIZE_FORMAT " bytes on IBB stream\n",
		size);

	if (state != JABBER_IBB_SESSION_OPENED) {
		purple_debug_error("jabber",
			"trying to send data on a non-open IBB session\n");
	} else if (size > jabber_ibb_session_get_max_data_size(sess)) {
		purple_debug_error("jabber",
			"trying to send a too large packet in the IBB session\n");
	} else {
		JabberIq *set = jabber_iq_new(jabber_ibb_session_get_js(sess),
			JABBER_IQ_SET);
		PurpleXmlNode *data_element = purple_xmlnode_new("data");
		char *base64 = purple_base64_encode(data, size);
		char seq[10];
		g_snprintf(seq, sizeof(seq), "%u", jabber_ibb_session_get_send_seq(sess));

		purple_xmlnode_set_attrib(set->node, "to", jabber_ibb_session_get_who(sess));
		purple_xmlnode_set_namespace(data_element, NS_IBB);
		purple_xmlnode_set_attrib(data_element, "sid", jabber_ibb_session_get_sid(sess));
		purple_xmlnode_set_attrib(data_element, "seq", seq);
		purple_xmlnode_insert_data(data_element, base64, -1);

		purple_xmlnode_insert_child(set->node, data_element);

		purple_debug_info("jabber",
			"IBB: setting send <iq/> callback for session %p %s\n", sess,
			sess->sid);
		jabber_iq_set_callback(set, jabber_ibb_session_send_acknowledge_cb, sess);
		sess->last_iq_id = g_strdup(purple_xmlnode_get_attrib(set->node, "id"));
		purple_debug_info("jabber", "IBB: set sess->last_iq_id: %s\n",
			sess->last_iq_id);
		jabber_iq_send(set);

		g_free(base64);
		(sess->send_seq)++;
	}
}
示例#16
0
static void
ggp_avatar_own_got_token(PurpleConnection *gc, const gchar *token,
                         gpointer _img)
{
    PurpleHttpRequest *req;
    PurpleImage *img = _img;
    ggp_avatar_own_data *own_data = ggp_avatar_get_avdata(gc)->own_data;
    gchar *img_data, *img_data_e, *request_data;
    PurpleAccount *account = purple_connection_get_account(gc);
    uin_t uin = ggp_str_to_uin(purple_account_get_username(account));

    if (img != own_data->img) {
        purple_debug_warning("gg", "ggp_avatar_own_got_token: "
                             "avatar was changed in meantime\n");
        return;
    }
    own_data->img = NULL;

    img_data = purple_base64_encode(purple_image_get_data(img),
                                    purple_image_get_size(img));
    img_data_e = g_uri_escape_string(img_data, NULL, FALSE);
    g_free(img_data);
    request_data = g_strdup_printf("uin=%d&photo=%s", uin, img_data_e);
    g_free(img_data_e);

    purple_debug_misc("gg", "ggp_avatar_own_got_token: "
                      "uploading new avatar...\n");

    req = purple_http_request_new("http://avatars.nowe.gg/upload");
    purple_http_request_set_max_len(req, GGP_AVATAR_RESPONSE_MAX);
    purple_http_request_set_method(req, "POST");
    purple_http_request_header_set(req, "Authorization", token);
    purple_http_request_header_set(req, "From", "avatars to avatars");
    purple_http_request_header_set(req, "Content-Type",
                                   "application/x-www-form-urlencoded");
    purple_http_request_set_contents(req, request_data, -1);
    purple_http_request(gc, req, ggp_avatar_own_sent, NULL);
    purple_http_request_unref(req);

    g_free(request_data);
}
示例#17
0
/*------------------------------------------------------------------------
 * Insert an inline image command.
 *
 *  @param mx				The message text as processed so far.
 *  @oaram id				The imgstore ID of the inline image.
 */
static void inline_image_add( GString* mx, int id )
{
	PurpleStoredImage *image;
	gconstpointer img_data;
	gsize img_size;
	gchar* enc;

	image = purple_imgstore_find_by_id( id );
	if ( image == NULL )
		return;

	img_data = purple_imgstore_get_data( image );
	img_size = purple_imgstore_get_size( image );

	enc = purple_base64_encode( img_data, img_size );

	g_string_append( mx, "::op=img|dat=" );
	g_string_append( mx, enc );
	g_string_append_c( mx, ':' );

	g_free( enc );
}
示例#18
0
/*------------------------------------------------------------------------
 * Encrypt the user's cleartext password using the AES 128-bit (ECB)
 *  encryption algorithm.
 *
 *  @param session	The MXit session object
 *  @return			The encrypted & encoded password.  Must be g_free'd when no longer needed.
 */
char* mxit_encrypt_password( struct MXitSession* session )
{
	char			key[16 + 1];
	char			exkey[512];
	GString*		pass			= NULL;
	GString*		encrypted		= NULL;
	char*			base64;
	unsigned int	i;

	purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" );

	/* build the AES encryption key */
	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
	memcpy( key, session->clientkey, strlen( session->clientkey ) );
	ExpandKey( (unsigned char*) key, (unsigned char*) exkey );

	/* build the secret data to be encrypted: SECRET_HEADER + password */
	pass = g_string_new( SECRET_HEADER );
	g_string_append( pass, purple_connection_get_password( session->con ) );
	padding_add( pass );		/* add ISO10126 padding */

	/* now encrypt the secret. we encrypt each block separately (ECB mode) */
	encrypted = g_string_sized_new( pass->len );
	for ( i = 0; i < pass->len; i += 16 ) {
		char	block[16];

		Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) block );
		g_string_append_len( encrypted, block, 16 );
	}

	/* now base64 encode the encrypted password */
	base64 = purple_base64_encode( (unsigned char*) encrypted->str, encrypted->len );
	g_string_free( encrypted, TRUE );

	g_string_free( pass, TRUE );

	return base64;
}
示例#19
0
/*------------------------------------------------------------------------
 * Encrypt a message using transport-layer encryption.
 *
 *  @param session	The MXit session object
 *	@param message	The message data.
 *  @return			The encrypted message.  Must be g_free'd when no longer needed.
 */
char* mxit_encrypt_message( struct MXitSession* session, char* message )
{
	GString*		raw_message	= NULL;
	char			exkey[512];
	GString*		encoded		= NULL;
	gchar*			base64;
	unsigned int	i;

	purple_debug_info( MXIT_PLUGIN_ID, "encrypt message: '%s'\n", message );

	/* append encryption header to message data */
	raw_message = g_string_new( SECRET_HEADER );
	g_string_append( raw_message, message );
	padding_add( raw_message );		/* add ISO10126 padding */

	/* build the AES key */
	ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );

	/* AES encrypt each block */
	encoded = g_string_sized_new( raw_message->len );
	for ( i = 0; i < raw_message->len; i += 16 ) {
		char	block[16];

		Encrypt( (unsigned char*) raw_message->str + i, (unsigned char*) exkey, (unsigned char*) block );
		g_string_append_len( encoded, block, 16 );
	}
	g_string_free( raw_message, TRUE );

	/* base64 encode the encrypted message */
	base64 = purple_base64_encode( (unsigned char *) encoded->str, encoded->len );
	g_string_free( encoded, TRUE );

	purple_debug_info( MXIT_PLUGIN_ID, "encrypted message: '%s'\n", base64 );

	return base64;
}
示例#20
0
static gchar *
gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
{
	gsize size = 0;
	MsnFileContext *header;
	gchar *u8 = NULL;
	gchar *ret;
	gunichar2 *uni = NULL;
	glong currentChar = 0;
	glong len = 0;
	const char *preview;
	gsize preview_len;

	size = purple_xfer_get_size(xfer);

	purple_xfer_prepare_thumbnail(xfer, "png");

	if (!file_name) {
		gchar *basename = g_path_get_basename(file_path);
		u8 = purple_utf8_try_convert(basename);
		g_free(basename);
		file_name = u8;
	}

	uni = g_utf8_to_utf16(file_name, -1, NULL, &len, NULL);

	if (u8) {
		g_free(u8);
		file_name = NULL;
		u8 = NULL;
	}

	preview = purple_xfer_get_thumbnail(xfer, &preview_len);
	header = g_malloc(sizeof(MsnFileContext) + preview_len);

	header->length = GUINT32_TO_LE(sizeof(MsnFileContext) - 1);
	header->version = GUINT32_TO_LE(2); /* V.3 contains additional unnecessary data */
	header->file_size = GUINT64_TO_LE(size);
	if (preview)
		header->type = GUINT32_TO_LE(0);
	else
		header->type = GUINT32_TO_LE(1);

	len = MIN(len, MAX_FILE_NAME_LEN);
	for (currentChar = 0; currentChar < len; currentChar++) {
		header->file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]);
	}
	memset(&header->file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2);

	memset(&header->unknown1, 0, sizeof(header->unknown1));
	header->unknown2 = GUINT32_TO_LE(0xffffffff);
	if (preview) {
		memcpy(&header->preview, preview, preview_len);
	}
	header->preview[preview_len] = '\0';

	g_free(uni);
	ret = purple_base64_encode((const guchar *)header, sizeof(MsnFileContext) + preview_len);
	g_free(header);
	return ret;
}
示例#21
0
文件: slp.c 项目: Distrotech/pidgin
static gchar *
gen_context(PurpleXfer *xfer, const char *file_name, const char *file_path)
{
	goffset size = 0;
	MsnFileContext context;
	gchar *u8 = NULL;
	gchar *ret;
	gunichar2 *uni = NULL;
	glong currentChar = 0;
	glong len = 0;
	const char *preview;
	gsize preview_len;

	size = purple_xfer_get_size(xfer);

	purple_xfer_prepare_thumbnail(xfer, "png");

	if (!file_name) {
		gchar *basename = g_path_get_basename(file_path);
		u8 = purple_utf8_try_convert(basename);
		g_free(basename);
		file_name = u8;
	}

	uni = g_utf8_to_utf16(file_name, -1, NULL, &len, NULL);

	if (u8) {
		g_free(u8);
		file_name = NULL;
		u8 = NULL;
	}

	preview = purple_xfer_get_thumbnail(xfer, &preview_len);

	context.length = MSN_FILE_CONTEXT_SIZE_V2;
	context.version = 2; /* V.3 contains additional unnecessary data */
	context.file_size = size;
	if (preview)
		context.type = 0;
	else
		context.type = 1;

	len = MIN(len, MAX_FILE_NAME_LEN);
	for (currentChar = 0; currentChar < len; currentChar++) {
		context.file_name[currentChar] = GUINT16_TO_LE(uni[currentChar]);
	}
	memset(&context.file_name[currentChar], 0x00, (MAX_FILE_NAME_LEN - currentChar) * 2);

#if 0
	memset(&context.unknown1, 0, sizeof(context.unknown1));
	context.unknown2 = 0xffffffff;
#endif

	/* Mind the cast, as in, don't free it after! */
	context.preview = (char *)preview;
	context.preview_len = preview_len;

	u8 = msn_file_context_to_wire(&context);
	ret = purple_base64_encode((const guchar *)u8, MSN_FILE_CONTEXT_SIZE_V2 + preview_len);

	g_free(uni);
	g_free(u8);

	return ret;
}
示例#22
0
END_TEST

START_TEST(test_util_base64_encode)
{
	assert_string_equal_free("Zm9ydHktdHdvAA==", purple_base64_encode("forty-two", 10));
}
static JabberSaslState
digest_md5_handle_challenge(JabberStream *js, PurpleXmlNode *packet,
                            PurpleXmlNode **response, char **msg)
{
	PurpleXmlNode *reply = NULL;
	char *enc_in = purple_xmlnode_get_data(packet);
	char *dec_in;
	char *enc_out;
	GHashTable *parts;
	JabberSaslState state = JABBER_SASL_STATE_CONTINUE;

	if (!enc_in) {
		*msg = g_strdup(_("Invalid response from server"));
		return JABBER_SASL_STATE_FAIL;
	}

	dec_in = (char *)purple_base64_decode(enc_in, NULL);
	purple_debug_misc("jabber", "decoded challenge (%"
			G_GSIZE_FORMAT "): %s\n",
			strlen(dec_in),
			dec_in);

	parts = jabber_auth_digest_md5_parse(dec_in);

	if (g_hash_table_lookup(parts, "rspauth")) {
		char *rspauth = g_hash_table_lookup(parts, "rspauth");
		char *expected_rspauth = js->auth_mech_data;

		if (rspauth && purple_strequal(rspauth, expected_rspauth)) {
			reply = purple_xmlnode_new("response");
			purple_xmlnode_set_namespace(reply, NS_XMPP_SASL);
		} else {
			*msg = g_strdup(_("Invalid challenge from server"));
			state = JABBER_SASL_STATE_FAIL;
		}
		g_free(js->auth_mech_data);
		js->auth_mech_data = NULL;
	} else {
		/* assemble a response, and send it */
		/* see RFC 2831 */
		char *realm;
		char *nonce;

		/* Make sure the auth string contains everything that should be there.
		   This isn't everything in RFC2831, but it is what we need. */

		nonce = g_hash_table_lookup(parts, "nonce");

		/* we're actually supposed to prompt the user for a realm if
		 * the server doesn't send one, but that really complicates things,
		 * so i'm not gonna worry about it until is poses a problem to
		 * someone, or I get really bored */
		realm = g_hash_table_lookup(parts, "realm");
		if(!realm)
			realm = js->user->domain;

		if (nonce == NULL || realm == NULL) {
			*msg = g_strdup(_("Invalid challenge from server"));
			state = JABBER_SASL_STATE_FAIL;
		} else {
			GString *response = g_string_new("");
			char *a2;
			char *auth_resp;
			char *cnonce;

			cnonce = g_strdup_printf("%x%u%x", g_random_int(), (int)time(NULL),
					g_random_int());

			a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm);
			auth_resp = generate_response_value(js->user,
					purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
			g_free(a2);

			a2 = g_strdup_printf(":xmpp/%s", realm);
			js->auth_mech_data = generate_response_value(js->user,
					purple_connection_get_password(js->gc), nonce, cnonce, a2, realm);
			g_free(a2);

			g_string_append_printf(response, "username=\"%s\"", js->user->node);
			g_string_append_printf(response, ",realm=\"%s\"", realm);
			g_string_append_printf(response, ",nonce=\"%s\"", nonce);
			g_string_append_printf(response, ",cnonce=\"%s\"", cnonce);
			g_string_append_printf(response, ",nc=00000001");
			g_string_append_printf(response, ",qop=auth");
			g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm);
			g_string_append_printf(response, ",response=%s", auth_resp);
			g_string_append_printf(response, ",charset=utf-8");

			g_free(auth_resp);
			g_free(cnonce);

			enc_out = purple_base64_encode((guchar *)response->str, response->len);

			purple_debug_misc("jabber", "decoded response (%"
					G_GSIZE_FORMAT "): %s\n",
					response->len, response->str);

			reply = purple_xmlnode_new("response");
			purple_xmlnode_set_namespace(reply, NS_XMPP_SASL);
			purple_xmlnode_insert_data(reply, enc_out, -1);

			g_free(enc_out);

			g_string_free(response, TRUE);
		}
	}

	g_free(enc_in);
	g_free(dec_in);
	g_hash_table_destroy(parts);

	*response = reply;
	return state;
}
示例#24
0
文件: nexus.c 项目: Lilitana/Pidgin
void
msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data)
{
	MsnSession *session = nexus->session;
	MsnNexusUpdateData *ud;
	MsnNexusUpdateCallback *update;
	PurpleCipherContext *sha1;
	PurpleCipherContext *hmac;

	char *key;

	guchar digest[20];

	struct tm *tm;
	time_t now;
	char *now_str;
	char *timestamp;
	char *timestamp_b64;

	char *domain;
	char *domain_b64;

	char *signedinfo;
	gint32 nonce[6];
	int i;
	char *nonce_b64;
	char *signature_b64;
	guchar signature[20];

	char *request;
	MsnSoapMessage *soap;

	update = g_new0(MsnNexusUpdateCallback, 1);
	update->cb = cb;
	update->data = data;

	if (nexus->tokens[id].updates != NULL) {
		/* Update already in progress. Just add to list and return. */
		purple_debug_info("msn",
		                  "Ticket update for user '%s' on domain '%s' in progress. Adding request to queue.\n",
		                  purple_account_get_username(session->account),
		                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
		nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates,
		                                            update);
		return;
	} else {
		purple_debug_info("msn",
		                  "Updating ticket for user '%s' on domain '%s'\n",
		                  purple_account_get_username(session->account),
		                  ticket_domains[id][SSO_VALID_TICKET_DOMAIN]);
		nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates,
		                                            update);
	}

	ud = g_new0(MsnNexusUpdateData, 1);
	ud->nexus = nexus;
	ud->id = id;

	sha1 = purple_cipher_context_new_by_name("sha1", NULL);

	domain = g_strdup_printf(MSN_SSO_RST_TEMPLATE,
	                         id,
	                         ticket_domains[id][SSO_VALID_TICKET_DOMAIN],
	                         ticket_domains[id][SSO_VALID_TICKET_POLICY] != NULL ?
	                             ticket_domains[id][SSO_VALID_TICKET_POLICY] :
	                             nexus->policy);
	purple_cipher_context_append(sha1, (guchar *)domain, strlen(domain));
	purple_cipher_context_digest(sha1, 20, digest, NULL);
	domain_b64 = purple_base64_encode(digest, 20);

	now = time(NULL);
	tm = gmtime(&now);
	now_str = g_strdup(purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm));
	now += 5*60;
	tm = gmtime(&now);
	timestamp = g_strdup_printf(MSN_SSO_TIMESTAMP_TEMPLATE,
	                            now_str,
	                            purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm));
	purple_cipher_context_reset(sha1, NULL);
	purple_cipher_context_append(sha1, (guchar *)timestamp, strlen(timestamp));
	purple_cipher_context_digest(sha1, 20, digest, NULL);
	timestamp_b64 = purple_base64_encode(digest, 20);
	g_free(now_str);

	purple_cipher_context_destroy(sha1);

	signedinfo = g_strdup_printf(MSN_SSO_SIGNEDINFO_TEMPLATE,
	                             id,
	                             domain_b64,
	                             timestamp_b64);

	for (i = 0; i < 6; i++)
		nonce[i] = rand();
	nonce_b64 = purple_base64_encode((guchar *)&nonce, sizeof(nonce));

	key = rps_create_key(nexus->secret, 24, (char *)nonce, sizeof(nonce));
	hmac = purple_cipher_context_new_by_name("hmac", NULL);
	purple_cipher_context_set_option(hmac, "hash", "sha1");
	purple_cipher_context_set_key_with_len(hmac, (guchar *)key, 24);
	purple_cipher_context_append(hmac, (guchar *)signedinfo, strlen(signedinfo));
	purple_cipher_context_digest(hmac, 20, signature, NULL);
	purple_cipher_context_destroy(hmac);
	signature_b64 = purple_base64_encode(signature, 20);

	request = g_strdup_printf(MSN_SSO_TOKEN_UPDATE_TEMPLATE,
	                          nexus->cipher,
	                          nonce_b64,
	                          timestamp,
	                          signedinfo,
	                          signature_b64,
	                          domain);

	g_free(nonce_b64);
	g_free(domain_b64);
	g_free(timestamp_b64);
	g_free(timestamp);
	g_free(key);
	g_free(signature_b64);
	g_free(signedinfo);
	g_free(domain);

	soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1));
	g_free(request);
	msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE,
	                      nexus_got_update_cb, ud);
}
示例#25
0
文件: nexus.c 项目: Lilitana/Pidgin
static char *
msn_rps_encrypt(MsnNexus *nexus)
{
	char usr_key_base[MSN_USER_KEY_SIZE], *usr_key;
	const char magic1[] = "SESSION KEY HASH";
	const char magic2[] = "SESSION KEY ENCRYPTION";
	PurpleCipherContext *hmac;
	size_t len;
	guchar *hash;
	char *key1, *key2, *key3;
	gsize key1_len;
	const char *iv;
	char *nonce_fixed;
	char *cipher;
	char *response;

	usr_key = &usr_key_base[0];
	/* Header */
	msn_push32le(usr_key, 28);                  /* Header size */
	msn_push32le(usr_key, CRYPT_MODE_CBC);      /* Crypt mode */
	msn_push32le(usr_key, CIPHER_TRIPLE_DES);   /* Cipher type */
	msn_push32le(usr_key, HASH_SHA1);           /* Hash type */
	msn_push32le(usr_key, 8);                   /* IV size */
	msn_push32le(usr_key, 20);                  /* Hash size */
	msn_push32le(usr_key, 72);                  /* Cipher size */
	/* Data */
	iv = usr_key;
	msn_push32le(usr_key, rand());
	msn_push32le(usr_key, rand());
	hash = (guchar *)usr_key;
	usr_key += 20;  /* Remaining is cipher data */

	key1 = (char *)purple_base64_decode((const char *)nexus->tokens[MSN_AUTH_MESSENGER].secret, &key1_len);
	key2 = rps_create_key(key1, key1_len, magic1, sizeof(magic1) - 1);
	key3 = rps_create_key(key1, key1_len, magic2, sizeof(magic2) - 1);

	len = strlen(nexus->nonce);
	hmac = purple_cipher_context_new_by_name("hmac", NULL);
	purple_cipher_context_set_option(hmac, "hash", "sha1");
	purple_cipher_context_set_key_with_len(hmac, (guchar *)key2, 24);
	purple_cipher_context_append(hmac, (guchar *)nexus->nonce, len);
	purple_cipher_context_digest(hmac, 20, hash, NULL);
	purple_cipher_context_destroy(hmac);

	/* We need to pad this to 72 bytes, apparently */
	nonce_fixed = g_malloc(len + 8);
	memcpy(nonce_fixed, nexus->nonce, len);
	memset(nonce_fixed + len, 0x08, 8);
	cipher = des3_cbc(key3, iv, nonce_fixed, len + 8, FALSE);
	g_free(nonce_fixed);

	memcpy(usr_key, cipher, 72);

	g_free(key1);
	g_free(key2);
	g_free(key3);
	g_free(cipher);

	response = purple_base64_encode((guchar *)usr_key_base, MSN_USER_KEY_SIZE);

	return response;
}
示例#26
0
MsnObject *
msn_object_new_from_image (PecanBuffer *image,
                           const char *location,
                           const char *creator,
                           MsnObjectType type)
{
    MsnObject *msnobj;

    PurpleCipherContext *ctx;
    char *buf;
    char *base64;
    unsigned char digest[20];

    msnobj = NULL;

    if (!image)
        return msnobj;

    /* New object */
    msnobj = msn_object_new ();
    msn_object_set_local (msnobj);
    msn_object_set_type (msnobj, type);
    msn_object_set_location (msnobj, location);
    msn_object_set_creator (msnobj, creator);

    msn_object_set_image (msnobj, image);

    /* Compute the SHA1D field. */
    memset (digest, 0, sizeof (digest));

    ctx = purple_cipher_context_new_by_name ("sha1", NULL);
    purple_cipher_context_append (ctx, (const gpointer) image->data, image->len);
    purple_cipher_context_digest (ctx, sizeof (digest), digest, NULL);

    base64 = purple_base64_encode (digest, sizeof (digest));
    msn_object_set_sha1d (msnobj, base64);
    g_free (base64);

    msn_object_set_size (msnobj, image->len);

    /* Compute the SHA1C field. */
    buf = g_strdup_printf ("Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s",
                           msn_object_get_creator (msnobj),
                           msn_object_get_size (msnobj),
                           msn_object_get_type (msnobj),
                           msn_object_get_location (msnobj),
                           msn_object_get_friendly (msnobj),
                           msn_object_get_sha1d (msnobj));

    memset (digest, 0, sizeof (digest));

    purple_cipher_context_reset (ctx, NULL);
    purple_cipher_context_append (ctx, (const guchar *) buf, strlen (buf));
    purple_cipher_context_digest (ctx, sizeof (digest), digest, NULL);
    purple_cipher_context_destroy (ctx);
    g_free (buf);

    base64 = purple_base64_encode (digest, sizeof (digest));
    msn_object_set_sha1c (msnobj, base64);
    g_free (base64);

    return msnobj;
}
示例#27
0
void gfire_chat_proto_invite(gfire_data *p_gfire, guint16 p_packet_len)
{
	if(!p_gfire)
		return;

	guint32 offset = XFIRE_HEADER_LEN;

	guint8 *chat_id = NULL;
	guint32 unknown = 0;
	guint32 userid = 0;
	gchar *name = NULL;
	gchar *nick = NULL;
	gchar *room = NULL;
	GHashTable *components = NULL;

	offset = gfire_proto_read_attr_chatid_bs(p_gfire->buff_in, &chat_id, 0x04, offset);
	if(offset == -1 || !chat_id)
		return;

	offset = gfire_proto_read_attr_int32_bs(p_gfire->buff_in, &unknown, 0xAA, offset);
	if(offset == -1)
	{
		g_free(chat_id);
		return;
	}

	offset = gfire_proto_read_attr_int32_bs(p_gfire->buff_in, &userid, 0x01, offset);
	if(offset == -1)
	{
		g_free(chat_id);
		return;
	}

	offset = gfire_proto_read_attr_string_bs(p_gfire->buff_in, &name, 0x02, offset);
	if(offset == -1 || !name)
	{
		g_free(chat_id);
		return;
	}

	offset = gfire_proto_read_attr_string_bs(p_gfire->buff_in, &nick, 0x0D, offset);
	if(offset == -1 || !nick)
	{
		g_free(chat_id);
		g_free(name);
		return;
	}

	offset = gfire_proto_read_attr_string_bs(p_gfire->buff_in, &room, 0x05, offset);
	if(offset == -1 || !room)
	{
		g_free(chat_id);
		g_free(name);
		g_free(nick);
		return;
	}

	if(strlen(nick) == 0)
	{
		g_free(nick);
		nick = g_strdup(name);
	}

	purple_debug(PURPLE_DEBUG_MISC, "gfire", "(chat invite): %s with alias %s invited us to room '%s'\n",
				NN(name), NN(nick), NN(room));

	// assemble ghashtable
	components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
	g_hash_table_replace(components, g_strdup("room"), room);
	g_hash_table_replace(components, g_strdup("chat_id"), purple_base64_encode(chat_id, XFIRE_CHATID_LEN));

	g_free(chat_id);

	serv_got_chat_invite(gfire_get_connection(p_gfire), room, nick, "", components);
}
示例#28
0
static JabberSaslState
jabber_auth_start_cyrus(JabberStream *js, xmlnode **reply, char **error)
{
	PurpleAccount *account;
	const char *clientout = NULL;
	char *enc_out;
	unsigned coutlen = 0;
	sasl_security_properties_t secprops;
	gboolean again;
	gboolean plaintext = TRUE;

	/* Set up security properties and options */
	secprops.min_ssf = 0;
	secprops.security_flags = SASL_SEC_NOANONYMOUS;

	account = purple_connection_get_account(js->gc);

	if (!jabber_stream_is_ssl(js)) {
		secprops.max_ssf = -1;
		secprops.maxbufsize = 4096;
		plaintext = purple_account_get_bool(account, "auth_plain_in_clear", FALSE);
		if (!plaintext)
			secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
	} else {
		secprops.max_ssf = 0;
		secprops.maxbufsize = 0;
		plaintext = TRUE;
	}
	secprops.property_names = 0;
	secprops.property_values = 0;

	do {
		again = FALSE;

		js->sasl_state = sasl_client_new("xmpp", js->serverFQDN, NULL, NULL, js->sasl_cb, 0, &js->sasl);
		if (js->sasl_state==SASL_OK) {
			sasl_setprop(js->sasl, SASL_SEC_PROPS, &secprops);
			purple_debug_info("sasl", "Mechs found: %s\n", js->sasl_mechs->str);
			js->sasl_state = sasl_client_start(js->sasl, js->sasl_mechs->str, NULL, &clientout, &coutlen, &js->current_mech);
		}
		switch (js->sasl_state) {
			/* Success */
			case SASL_OK:
			case SASL_CONTINUE:
				break;
			case SASL_NOMECH:
				/* No mechanisms have offered to help */

				/* Firstly, if we don't have a password try
				 * to get one
				 */

				if (!purple_account_get_password(account)) {
					purple_account_request_password(account, G_CALLBACK(auth_pass_cb), G_CALLBACK(auth_no_pass_cb), js->gc);
					return JABBER_SASL_STATE_CONTINUE;

				/* If we've got a password, but aren't sending
				 * it in plaintext, see if we can turn on
				 * plaintext auth
				 */
				/* XXX Should we just check for PLAIN/LOGIN being offered mechanisms? */
				} else if (!plaintext) {
					char *msg = g_strdup_printf(_("%s may require plaintext authentication over an unencrypted connection.  Allow this and continue authentication?"),
							purple_account_get_username(account));
					purple_request_yes_no(js->gc, _("Plaintext Authentication"),
							_("Plaintext Authentication"),
							msg,
							1, account, NULL, NULL, account,
							allow_cyrus_plaintext_auth,
							disallow_plaintext_auth);
					g_free(msg);
					return JABBER_SASL_STATE_CONTINUE;

				} else
					js->auth_fail_count++;

				if (js->auth_fail_count == 1 &&
					(js->sasl_mechs->str && g_str_equal(js->sasl_mechs->str, "GSSAPI"))) {
					/* If we tried GSSAPI first, it failed, and it was the only method we had to try, try jabber:iq:auth
					 * for compatibility with iChat 10.5 Server and other jabberd based servers.
					 *
					 * iChat Server 10.5 and certain other corporate servers offer SASL GSSAPI by default, which is often
					 * not configured on the client side, and expects a fallback to jabber:iq:auth when it (predictably) fails.
					 *
					 * Note: xep-0078 points out that using jabber:iq:auth after a sasl failure is wrong. However,
					 * I believe this refers to actual authentication failure, not a simple lack of concordant mechanisms.
					 * Doing otherwise means that simply compiling with SASL support renders the client unable to connect to servers
					 * which would connect without issue otherwise. -evands
					 */
					js->auth_mech = NULL;
					jabber_auth_start_old(js);
					return JABBER_SASL_STATE_CONTINUE;
				}

				break;

				/* Fatal errors. Give up and go home */
			case SASL_BADPARAM:
			case SASL_NOMEM:
				*error = g_strdup(_("SASL authentication failed"));
				break;

				/* For everything else, fail the mechanism and try again */
			default:
				purple_debug_info("sasl", "sasl_state is %d, failing the mech and trying again\n", js->sasl_state);

				js->auth_fail_count++;

				/*
				 * DAA: is this right?
				 * The manpage says that "mech" will contain the chosen mechanism on success.
				 * Presumably, if we get here that isn't the case and we shouldn't try again?
				 * I suspect that this never happens.
				 */
				/*
				 * SXW: Yes, this is right. What this handles is the situation where a
				 * mechanism, say GSSAPI, is tried. If that mechanism fails, it may be
				 * due to mechanism specific issues, so we want to try one of the other
				 * supported mechanisms. This code handles that case
				 */
				if (js->current_mech && *js->current_mech) {
					char *pos;
					if ((pos = strstr(js->sasl_mechs->str, js->current_mech))) {
						g_string_erase(js->sasl_mechs, pos-js->sasl_mechs->str, strlen(js->current_mech));
					}
					/* Remove space which separated this mech from the next */
					if ((js->sasl_mechs->str)[0] == ' ') {
						g_string_erase(js->sasl_mechs, 0, 1);
					}
					again = TRUE;
				}

				sasl_dispose(&js->sasl);
		}
	} while (again);

	if (js->sasl_state == SASL_CONTINUE || js->sasl_state == SASL_OK) {
		xmlnode *auth = xmlnode_new("auth");
		xmlnode_set_namespace(auth, NS_XMPP_SASL);
		xmlnode_set_attrib(auth, "mechanism", js->current_mech);

		xmlnode_set_attrib(auth, "xmlns:ga", "http://www.google.com/talk/protocol/auth");
		xmlnode_set_attrib(auth, "ga:client-uses-full-bind-result", "true");

		if (clientout) {
			if (coutlen == 0) {
				xmlnode_insert_data(auth, "=", -1);
			} else {
				enc_out = purple_base64_encode((unsigned char*)clientout, coutlen);
				xmlnode_insert_data(auth, enc_out, -1);
				g_free(enc_out);
			}
		}

		*reply = auth;
		return JABBER_SASL_STATE_CONTINUE;
	} else {
		return JABBER_SASL_STATE_FAIL;
	}
}
示例#29
0
void om_post_or_get(OmegleAccount *oma, OmegleMethod method,
		const gchar *host, const gchar *url, const gchar *postdata,
		OmegleProxyCallbackFunc callback_func, gpointer user_data,
		gboolean keepalive)
{
	GString *request;
	gchar *cookies;
	OmegleConnection *omconn;
	gchar *real_url;
	gboolean is_proxy = FALSE;
	const gchar *user_agent;
	const gchar* const *languages;
	gchar *language_names;
	PurpleProxyInfo *proxy_info = NULL;
	gchar *proxy_auth;
	gchar *proxy_auth_base64;

	/* TODO: Fix keepalive and use it as much as possible */
	keepalive = FALSE;

	if (host == NULL)
		host = purple_account_get_string(oma->account, "host", "bajor.omegle.com");

	if (oma && oma->account && !(method & OM_METHOD_SSL))
	{
		proxy_info = purple_proxy_get_setup(oma->account);
		if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL)
			proxy_info = purple_global_proxy_get_info();
		if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP)
		{
			is_proxy = TRUE;
		}	
	}
	if (is_proxy == TRUE)
	{
		real_url = g_strdup_printf("http://%s%s", host, url);
	} else {
		real_url = g_strdup(url);
	}

	cookies = om_cookies_to_string(oma);
	user_agent = purple_account_get_string(oma->account, "user-agent", "Opera/9.50 (Windows NT 5.1; U; en-GB)");
	
	if (method & OM_METHOD_POST && !postdata)
		postdata = "";

	/* Build the request */
	request = g_string_new(NULL);
	g_string_append_printf(request, "%s %s HTTP/1.0\r\n",
			(method & OM_METHOD_POST) ? "POST" : "GET",
			real_url);
	if (is_proxy == FALSE)
		g_string_append_printf(request, "Host: %s\r\n", host);
	g_string_append_printf(request, "Connection: %s\r\n",
			(keepalive ? "Keep-Alive" : "close"));
	g_string_append_printf(request, "User-Agent: %s\r\n", user_agent);
	if (method & OM_METHOD_POST) {
		g_string_append_printf(request,
				"Content-Type: application/x-www-form-urlencoded\r\n");
		g_string_append_printf(request,
				"Content-length: %zu\r\n", strlen(postdata));
	}
	g_string_append_printf(request, "Accept: application/json, text/html, */*\r\n");
	g_string_append_printf(request, "Cookie: %s\r\n", cookies);
	g_string_append_printf(request, "Accept-Encoding: gzip\r\n");
	if (is_proxy == TRUE)
	{
		if (purple_proxy_info_get_username(proxy_info) &&
			purple_proxy_info_get_password(proxy_info))
		{
			proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info));
			proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth));
			g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64);
			g_free(proxy_auth_base64);
			g_free(proxy_auth);
		}
	}

	/* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */
	languages = g_get_language_names();
	language_names = g_strjoinv(", ", (gchar **)languages);
	purple_util_chrreplace(language_names, '_', '-');
	g_string_append_printf(request, "Accept-Language: %s\r\n", language_names);
	g_free(language_names);

	purple_debug_info("omegle", "getting url %s\n", url);

	g_string_append_printf(request, "\r\n");
	if (method & OM_METHOD_POST)
		g_string_append_printf(request, "%s", postdata);

	/* If it needs to go over a SSL connection, we probably shouldn't print
	 * it in the debug log.  Without this condition a user's password is
	 * printed in the debug log */
	if (method == OM_METHOD_POST)
		purple_debug_info("omegle", "sending request data:\n%s\n",
			postdata);

	g_free(cookies);

	/*
	 * Do a separate DNS lookup for the given host name and cache it
	 * for next time.
	 *
	 * TODO: It would be better if we did this before we call
	 *       purple_proxy_connect(), so we could re-use the result.
	 *       Or even better: Use persistent HTTP connections for servers
	 *       that we access continually.
	 *
	 * TODO: This cache of the hostname<-->IP address does not respect
	 *       the TTL returned by the DNS server.  We should expire things
	 *       from the cache after some amount of time.
	 */
	if (!is_proxy)
	{
		/* Don't do this for proxy connections, since proxies do the DNS lookup */
		gchar *host_ip;

		host_ip = g_hash_table_lookup(oma->hostname_ip_cache, host);
		if (host_ip != NULL) {
			host = host_ip;
		} else if (oma->account && !oma->account->disconnecting) {
			GSList *host_lookup_list = NULL;
			PurpleDnsQueryData *query;

			host_lookup_list = g_slist_prepend(
					host_lookup_list, g_strdup(host));
			host_lookup_list = g_slist_prepend(
					host_lookup_list, oma);

			query = purple_dnsquery_a(host, 80,
					om_host_lookup_cb, host_lookup_list);
			oma->dns_queries = g_slist_prepend(oma->dns_queries, query);
			host_lookup_list = g_slist_append(host_lookup_list, query);
		}
	}

	omconn = g_new0(OmegleConnection, 1);
	omconn->oma = oma;
	omconn->url = real_url;
	omconn->method = method;
	omconn->hostname = g_strdup(host);
	omconn->request = request;
	omconn->callback = callback_func;
	omconn->user_data = user_data;
	omconn->fd = -1;
	omconn->connection_keepalive = keepalive;
	omconn->request_time = time(NULL);
	oma->conns = g_slist_prepend(oma->conns, omconn);

	om_attempt_connection(omconn);
}
示例#30
0
SevenCupConnection *
sevencup_post_or_get(SevenCupAccount *sa, SteamMethod method,
		const gchar *host, const gchar *url, const gchar *postdata,
		SteamProxyCallbackFunc callback_func, gpointer user_data,
		gboolean keepalive)
{
	GString *request;
	gchar *cookies;
	SevenCupConnection *scon;
	gchar *real_url;
	gboolean is_proxy = FALSE;
	const gchar *user_agent;
	const gchar* const *languages;
	gchar *language_names;
	PurpleProxyInfo *proxy_info = NULL;
	gchar *proxy_auth;
	gchar *proxy_auth_base64;

	if (host == NULL)
		host = "www.7cupsoftea.com";

	if (sa && sa->account)
	{
		if (purple_account_get_bool(sa->account, "use-https", TRUE))
			method |= STEAM_METHOD_SSL;
	}

	if (sa && sa->account && !(method & STEAM_METHOD_SSL))
	{
		proxy_info = purple_proxy_get_setup(sa->account);
		if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_GLOBAL)
			proxy_info = purple_global_proxy_get_info();
		if (purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_HTTP)
		{
			is_proxy = TRUE;
		}	
	}
	if (is_proxy == TRUE)
	{
		real_url = g_strdup_printf("http://%s%s", host, url);
	} else {
		real_url = g_strdup(url);
	}

	cookies = sevencup_cookies_to_string(sa);
	user_agent = purple_account_get_string(sa->account, "user-agent", "Steam 1.2.0 / iPhone");
	
	if (method & STEAM_METHOD_POST && !postdata)
		postdata = "";

	/* Build the request */
	request = g_string_new(NULL);
	g_string_append_printf(request, "%s %s HTTP/1.1\r\n",
			(method & STEAM_METHOD_POST) ? "POST" : "GET",
			real_url);
	if (is_proxy == FALSE)
		g_string_append_printf(request, "Host: %s\r\n", host);
	g_string_append_printf(request, "Connection: %s\r\n",
			(keepalive ? "Keep-Alive" : "close"));
	g_string_append_printf(request, "User-Agent: %s\r\n", user_agent);
	if (method & STEAM_METHOD_POST) {
		g_string_append_printf(request,
				"Content-Type: application/x-www-form-urlencoded\r\n");
		g_string_append_printf(request,
				"Content-length: %zu\r\n", strlen(postdata));
	}
	g_string_append_printf(request, "Accept: */*\r\n");
	g_string_append_printf(request, "Cookie: %s\r\n", cookies);
	g_string_append_printf(request, "Accept-Encoding: gzip\r\n");
	if (is_proxy == TRUE)
	{
		if (purple_proxy_info_get_username(proxy_info) &&
			purple_proxy_info_get_password(proxy_info))
		{
			proxy_auth = g_strdup_printf("%s:%s", purple_proxy_info_get_username(proxy_info), purple_proxy_info_get_password(proxy_info));
			proxy_auth_base64 = purple_base64_encode((guchar *)proxy_auth, strlen(proxy_auth));
			g_string_append_printf(request, "Proxy-Authorization: Basic %s\r\n", proxy_auth_base64);
			g_free(proxy_auth_base64);
			g_free(proxy_auth);
		}
	}

	/* Tell the server what language we accept, so that we get error messages in our language (rather than our IP's) */
	languages = g_get_language_names();
	language_names = g_strjoinv(", ", (gchar **)languages);
	purple_util_chrreplace(language_names, '_', '-');
	g_string_append_printf(request, "Accept-Language: %s\r\n", language_names);
	g_free(language_names);

	purple_debug_info("7cups", "getting url %s\n", url);

	g_string_append_printf(request, "\r\n");
	if (method & STEAM_METHOD_POST)
		g_string_append_printf(request, "%s", postdata);

	/* If it needs to go over a SSL connection, we probably shouldn't print
	 * it in the debug log.  Without this condition a user's password is
	 * printed in the debug log */
	if (method == STEAM_METHOD_POST)
		purple_debug_info("7cups", "sending request data:\n%s\n",
			postdata);

	g_free(cookies);

	scon = g_new0(SevenCupConnection, 1);
	scon->sa = sa;
	scon->url = real_url;
	scon->method = method;
	scon->hostname = g_strdup(host);
	scon->request = request;
	scon->callback = callback_func;
	scon->user_data = user_data;
	scon->fd = -1;
	scon->connection_keepalive = keepalive;
	scon->request_time = time(NULL);
	
	g_queue_push_head(sa->waiting_conns, scon);
	sevencup_next_connection(sa);
	
	return scon;
}