Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/EionRobb/skype4pidgin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'skypeweb/skypeweb_util.c')
-rw-r--r--skypeweb/skypeweb_util.c562
1 files changed, 281 insertions, 281 deletions
diff --git a/skypeweb/skypeweb_util.c b/skypeweb/skypeweb_util.c
index ef306c2..a9107f3 100644
--- a/skypeweb/skypeweb_util.c
+++ b/skypeweb/skypeweb_util.c
@@ -1,282 +1,282 @@
-/*
- * SkypeWeb Plugin for libpurple/Pidgin
- * Copyright (c) 2014-2020 Eion Robb
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "skypeweb_util.h"
-
-gchar *
-skypeweb_string_get_chunk(const gchar *haystack, gsize len, const gchar *start, const gchar *end)
-{
- const gchar *chunk_start, *chunk_end;
- g_return_val_if_fail(haystack && start, NULL);
-
- if (len > 0) {
- chunk_start = g_strstr_len(haystack, len, start);
- } else {
- chunk_start = strstr(haystack, start);
- }
- g_return_val_if_fail(chunk_start, NULL);
- chunk_start += strlen(start);
-
- if (end != NULL) {
- if (len > 0) {
- chunk_end = g_strstr_len(chunk_start, len - (chunk_start - haystack), end);
- } else {
- chunk_end = strstr(chunk_start, end);
- }
- g_return_val_if_fail(chunk_end, NULL);
-
- return g_strndup(chunk_start, chunk_end - chunk_start);
- } else {
- return g_strdup(chunk_start);
- }
-}
-
-gchar *
-skypeweb_jsonobj_to_string(JsonObject *jsonobj)
-{
- JsonGenerator *generator;
- JsonNode *root;
- gchar *string;
-
- root = json_node_new(JSON_NODE_OBJECT);
- json_node_set_object(root, jsonobj);
-
- generator = json_generator_new();
- json_generator_set_root(generator, root);
-
- string = json_generator_to_data(generator, NULL);
-
- g_object_unref(generator);
- json_node_free(root);
-
- return string;
-}
-
-/** turn https://bay-client-s.gateway.messenger.live.com/v1/users/ME/contacts/8:eionrobb
- or https://bay-client-s.gateway.messenger.live.com/v1/users/8:eionrobb/presenceDocs/messagingService
- into eionrobb
-*/
-const gchar *
-skypeweb_contact_url_to_name(const gchar *url)
-{
- static gchar *tempname = NULL;
- const gchar *start, *end;
-
- start = g_strrstr(url, "/8:");
- if (!start) start = g_strrstr(url, "/1:");
- if (!start) start = g_strrstr(url, "/4:");
- if (start) start = start + 2;
- if (!start) start = g_strrstr(url, "/2:");
- if (!start) start = g_strrstr(url, "/28:");
- if (start) start = start + 1;
- if (!start) return NULL;
-
- if ((end = strchr(start, '/'))) {
- g_free(tempname);
- tempname = g_strndup(start, end - start);
- return tempname;
- }
-
- g_free(tempname);
- tempname = g_strdup(start);
- return tempname;
-}
-
-/** turn https://bay-client-s.gateway.messenger.live.com/v1/users/ME/conversations/19:blah@thread.skype
- into 19:blah@thread.skype
-*/
-const gchar *
-skypeweb_thread_url_to_name(const gchar *url)
-{
- static gchar *tempname = NULL;
- const gchar *start, *end;
-
- start = g_strrstr(url, "/19:");
- if (!start) return NULL;
- start = start + 1;
-
- if ((end = strchr(start, '/'))) {
- g_free(tempname);
- tempname = g_strndup(start, end - start);
- return tempname;
- }
-
- return start;
-}
-
-/** Blatantly stolen from MSN prpl, with super-secret SHA256 change! */
-#define BUFSIZE 256
-char *
-skypeweb_hmac_sha256(char *input)
-{
- GChecksum *hash;
- const guchar productKey[] = SKYPEWEB_LOCKANDKEY_SECRET;
- const guchar productID[] = SKYPEWEB_LOCKANDKEY_APPID;
- const char hexChars[] = "0123456789abcdef";
- char buf[BUFSIZE];
- unsigned char sha256Hash[32];
- gsize sha256HashLen = sizeof(sha256Hash);
- unsigned char *newHash;
- unsigned int *sha256Parts;
- unsigned int *chlStringParts;
- unsigned int newHashParts[5];
- gchar *output;
-
- long long nHigh = 0, nLow = 0;
-
- int len;
- int i;
-
- hash = g_checksum_new(G_CHECKSUM_SHA256);
- g_checksum_update(hash, (guchar *)input, strlen(input));
- g_checksum_update(hash, productKey, sizeof(productKey) - 1);
- g_checksum_get_digest(hash, (guchar *)sha256Hash, &sha256HashLen);
- g_checksum_free(hash);
-
- /* Split it into four integers */
- sha256Parts = (unsigned int *)sha256Hash;
- for (i = 0; i < 4; i++) {
- /* adjust endianess */
- sha256Parts[i] = GUINT_TO_LE(sha256Parts[i]);
-
- /* & each integer with 0x7FFFFFFF */
- /* and save one unmodified array for later */
- newHashParts[i] = sha256Parts[i];
- sha256Parts[i] &= 0x7FFFFFFF;
- }
-
- /* make a new string and pad with '0' to length that's a multiple of 8 */
- snprintf(buf, BUFSIZE - 5, "%s%s", input, productID);
- len = strlen(buf);
- if ((len % 8) != 0) {
- int fix = 8 - (len % 8);
- memset(&buf[len], '0', fix);
- buf[len + fix] = '\0';
- len += fix;
- }
-
- /* split into integers */
- chlStringParts = (unsigned int *)buf;
-
- /* this is magic */
- for (i = 0; i < (len / 4); i += 2) {
- long long temp;
-
- chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]);
- chlStringParts[i + 1] = GUINT_TO_LE(chlStringParts[i + 1]);
-
- temp = (0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF;
- temp = (sha256Parts[0] * (temp + nLow) + sha256Parts[1]) % 0x7FFFFFFF;
- nHigh += temp;
-
- temp = ((long long)chlStringParts[i + 1] + temp) % 0x7FFFFFFF;
- nLow = (sha256Parts[2] * temp + sha256Parts[3]) % 0x7FFFFFFF;
- nHigh += nLow;
- }
- nLow = (nLow + sha256Parts[1]) % 0x7FFFFFFF;
- nHigh = (nHigh + sha256Parts[3]) % 0x7FFFFFFF;
-
- newHashParts[0] ^= nLow;
- newHashParts[1] ^= nHigh;
- newHashParts[2] ^= nLow;
- newHashParts[3] ^= nHigh;
-
- /* adjust endianness */
- for(i = 0; i < 4; i++)
- newHashParts[i] = GUINT_TO_LE(newHashParts[i]);
-
- /* make a string of the parts */
- newHash = (unsigned char *)newHashParts;
-
- /* convert to hexadecimal */
- output = g_new0(gchar, 33);
- for (i = 0; i < 16; i++)
- {
- output[i * 2] = hexChars[(newHash[i] >> 4) & 0xF];
- output[(i * 2) + 1] = hexChars[newHash[i] & 0xF];
- }
- output[32] = '\0';
-
- return output;
-}
-
-gint64
-skypeweb_get_js_time()
-{
-#if GLIB_CHECK_VERSION(2, 28, 0)
- return (g_get_real_time() / 1000);
-#else
- GTimeVal val;
-
- g_get_current_time (&val);
-
- return (((gint64) val.tv_sec) * 1000) + (val.tv_usec / 1000);
-#endif
-}
-
-/* copied from oscar.c to be libpurple 2.1 compatible */
-PurpleAccount *
-find_acct(const char *prpl, const char *acct_id)
-{
- PurpleAccount *acct = NULL;
-
- /* If we have a specific acct, use it */
- if (acct_id && *acct_id) {
- acct = purple_accounts_find(acct_id, prpl);
- if (acct && !purple_account_is_connected(acct))
- acct = NULL;
- } else { /* Otherwise find an active account for the protocol */
- GList *l = purple_accounts_get_all();
- while (l) {
- if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
- && purple_account_is_connected(l->data)) {
- acct = l->data;
- break;
- }
- l = l->next;
- }
- }
-
- return acct;
-}
-
-const gchar *
-skypeweb_user_url_prefix(const gchar *who)
-{
- if(SKYPEWEB_BUDDY_IS_S4B(who) || SKYPEWEB_BUDDY_IS_BOT(who)) {
- return ""; // already has a prefix
- } else if (SKYPEWEB_BUDDY_IS_MSN(who)) {
- return "1:";
- } else if(SKYPEWEB_BUDDY_IS_PHONE(who)) {
- return "4:";
- } else {
- return "8:";
- }
-}
-
-const gchar *
-skypeweb_strip_user_prefix(const gchar *who)
-{
- if (who[1] == ':') {
- if (who[0] != '2') {
- return who + 2;
- }
- }
-
- return who;
+/*
+ * SkypeWeb Plugin for libpurple/Pidgin
+ * Copyright (c) 2014-2020 Eion Robb
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "skypeweb_util.h"
+
+gchar *
+skypeweb_string_get_chunk(const gchar *haystack, gsize len, const gchar *start, const gchar *end)
+{
+ const gchar *chunk_start, *chunk_end;
+ g_return_val_if_fail(haystack && start, NULL);
+
+ if (len > 0) {
+ chunk_start = g_strstr_len(haystack, len, start);
+ } else {
+ chunk_start = strstr(haystack, start);
+ }
+ g_return_val_if_fail(chunk_start, NULL);
+ chunk_start += strlen(start);
+
+ if (end != NULL) {
+ if (len > 0) {
+ chunk_end = g_strstr_len(chunk_start, len - (chunk_start - haystack), end);
+ } else {
+ chunk_end = strstr(chunk_start, end);
+ }
+ g_return_val_if_fail(chunk_end, NULL);
+
+ return g_strndup(chunk_start, chunk_end - chunk_start);
+ } else {
+ return g_strdup(chunk_start);
+ }
+}
+
+gchar *
+skypeweb_jsonobj_to_string(JsonObject *jsonobj)
+{
+ JsonGenerator *generator;
+ JsonNode *root;
+ gchar *string;
+
+ root = json_node_new(JSON_NODE_OBJECT);
+ json_node_set_object(root, jsonobj);
+
+ generator = json_generator_new();
+ json_generator_set_root(generator, root);
+
+ string = json_generator_to_data(generator, NULL);
+
+ g_object_unref(generator);
+ json_node_free(root);
+
+ return string;
+}
+
+/** turn https://bay-client-s.gateway.messenger.live.com/v1/users/ME/contacts/8:eionrobb
+ or https://bay-client-s.gateway.messenger.live.com/v1/users/8:eionrobb/presenceDocs/messagingService
+ into eionrobb
+*/
+const gchar *
+skypeweb_contact_url_to_name(const gchar *url)
+{
+ static gchar *tempname = NULL;
+ const gchar *start, *end;
+
+ start = g_strrstr(url, "/8:");
+ if (!start) start = g_strrstr(url, "/1:");
+ if (!start) start = g_strrstr(url, "/4:");
+ if (start) start = start + 2;
+ if (!start) start = g_strrstr(url, "/2:");
+ if (!start) start = g_strrstr(url, "/28:");
+ if (start) start = start + 1;
+ if (!start) return NULL;
+
+ if ((end = strchr(start, '/'))) {
+ g_free(tempname);
+ tempname = g_strndup(start, end - start);
+ return tempname;
+ }
+
+ g_free(tempname);
+ tempname = g_strdup(start);
+ return tempname;
+}
+
+/** turn https://bay-client-s.gateway.messenger.live.com/v1/users/ME/conversations/19:blah@thread.skype
+ into 19:blah@thread.skype
+*/
+const gchar *
+skypeweb_thread_url_to_name(const gchar *url)
+{
+ static gchar *tempname = NULL;
+ const gchar *start, *end;
+
+ start = g_strrstr(url, "/19:");
+ if (!start) return NULL;
+ start = start + 1;
+
+ if ((end = strchr(start, '/'))) {
+ g_free(tempname);
+ tempname = g_strndup(start, end - start);
+ return tempname;
+ }
+
+ return start;
+}
+
+/** Blatantly stolen from MSN prpl, with super-secret SHA256 change! */
+#define BUFSIZE 256
+char *
+skypeweb_hmac_sha256(char *input)
+{
+ GChecksum *hash;
+ const guchar productKey[] = SKYPEWEB_LOCKANDKEY_SECRET;
+ const guchar productID[] = SKYPEWEB_LOCKANDKEY_APPID;
+ const char hexChars[] = "0123456789abcdef";
+ char buf[BUFSIZE];
+ unsigned char sha256Hash[32];
+ gsize sha256HashLen = sizeof(sha256Hash);
+ unsigned char *newHash;
+ unsigned int *sha256Parts;
+ unsigned int *chlStringParts;
+ unsigned int newHashParts[5];
+ gchar *output;
+
+ long long nHigh = 0, nLow = 0;
+
+ int len;
+ int i;
+
+ hash = g_checksum_new(G_CHECKSUM_SHA256);
+ g_checksum_update(hash, (guchar *)input, strlen(input));
+ g_checksum_update(hash, productKey, sizeof(productKey) - 1);
+ g_checksum_get_digest(hash, (guchar *)sha256Hash, &sha256HashLen);
+ g_checksum_free(hash);
+
+ /* Split it into four integers */
+ sha256Parts = (unsigned int *)sha256Hash;
+ for (i = 0; i < 4; i++) {
+ /* adjust endianess */
+ sha256Parts[i] = GUINT_TO_LE(sha256Parts[i]);
+
+ /* & each integer with 0x7FFFFFFF */
+ /* and save one unmodified array for later */
+ newHashParts[i] = sha256Parts[i];
+ sha256Parts[i] &= 0x7FFFFFFF;
+ }
+
+ /* make a new string and pad with '0' to length that's a multiple of 8 */
+ snprintf(buf, BUFSIZE - 5, "%s%s", input, productID);
+ len = strlen(buf);
+ if ((len % 8) != 0) {
+ int fix = 8 - (len % 8);
+ memset(&buf[len], '0', fix);
+ buf[len + fix] = '\0';
+ len += fix;
+ }
+
+ /* split into integers */
+ chlStringParts = (unsigned int *)buf;
+
+ /* this is magic */
+ for (i = 0; i < (len / 4); i += 2) {
+ long long temp;
+
+ chlStringParts[i] = GUINT_TO_LE(chlStringParts[i]);
+ chlStringParts[i + 1] = GUINT_TO_LE(chlStringParts[i + 1]);
+
+ temp = (0x0E79A9C1 * (long long)chlStringParts[i]) % 0x7FFFFFFF;
+ temp = (sha256Parts[0] * (temp + nLow) + sha256Parts[1]) % 0x7FFFFFFF;
+ nHigh += temp;
+
+ temp = ((long long)chlStringParts[i + 1] + temp) % 0x7FFFFFFF;
+ nLow = (sha256Parts[2] * temp + sha256Parts[3]) % 0x7FFFFFFF;
+ nHigh += nLow;
+ }
+ nLow = (nLow + sha256Parts[1]) % 0x7FFFFFFF;
+ nHigh = (nHigh + sha256Parts[3]) % 0x7FFFFFFF;
+
+ newHashParts[0] ^= nLow;
+ newHashParts[1] ^= nHigh;
+ newHashParts[2] ^= nLow;
+ newHashParts[3] ^= nHigh;
+
+ /* adjust endianness */
+ for(i = 0; i < 4; i++)
+ newHashParts[i] = GUINT_TO_LE(newHashParts[i]);
+
+ /* make a string of the parts */
+ newHash = (unsigned char *)newHashParts;
+
+ /* convert to hexadecimal */
+ output = g_new0(gchar, 33);
+ for (i = 0; i < 16; i++)
+ {
+ output[i * 2] = hexChars[(newHash[i] >> 4) & 0xF];
+ output[(i * 2) + 1] = hexChars[newHash[i] & 0xF];
+ }
+ output[32] = '\0';
+
+ return output;
+}
+
+gint64
+skypeweb_get_js_time()
+{
+#if GLIB_CHECK_VERSION(2, 28, 0)
+ return (g_get_real_time() / 1000);
+#else
+ GTimeVal val;
+
+ g_get_current_time (&val);
+
+ return (((gint64) val.tv_sec) * 1000) + (val.tv_usec / 1000);
+#endif
+}
+
+/* copied from oscar.c to be libpurple 2.1 compatible */
+PurpleAccount *
+find_acct(const char *prpl, const char *acct_id)
+{
+ PurpleAccount *acct = NULL;
+
+ /* If we have a specific acct, use it */
+ if (acct_id && *acct_id) {
+ acct = purple_accounts_find(acct_id, prpl);
+ if (acct && !purple_account_is_connected(acct))
+ acct = NULL;
+ } else { /* Otherwise find an active account for the protocol */
+ GList *l = purple_accounts_get_all();
+ while (l) {
+ if (!strcmp(prpl, purple_account_get_protocol_id(l->data))
+ && purple_account_is_connected(l->data)) {
+ acct = l->data;
+ break;
+ }
+ l = l->next;
+ }
+ }
+
+ return acct;
+}
+
+const gchar *
+skypeweb_user_url_prefix(const gchar *who)
+{
+ if(SKYPEWEB_BUDDY_IS_S4B(who) || SKYPEWEB_BUDDY_IS_BOT(who)) {
+ return ""; // already has a prefix
+ } else if (SKYPEWEB_BUDDY_IS_MSN(who)) {
+ return "1:";
+ } else if(SKYPEWEB_BUDDY_IS_PHONE(who)) {
+ return "4:";
+ } else {
+ return "8:";
+ }
+}
+
+const gchar *
+skypeweb_strip_user_prefix(const gchar *who)
+{
+ if (who[1] == ':') {
+ if (who[0] != '2') {
+ return who + 2;
+ }
+ }
+
+ return who;
} \ No newline at end of file