diff -r c71e5e8976ba -r cf23e0f1861a libpurple/protocols/gg/oauth/oauth.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/gg/oauth/oauth.c Mon Aug 06 13:16:32 2012 +0200 @@ -0,0 +1,139 @@ +/* + * (C) Copyright 2008 Wojtek Kaniewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License Version + * 2.1 as published by the Free Software Foundation. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// source: http://toxygen.net/libgadu/ + +#include "oauth.h" + +#include "oauth-parameter.h" +#include + +char *gg_oauth_static_nonce; /* dla unit testów */ +char *gg_oauth_static_timestamp; /* dla unit testów */ + +static void gg_oauth_generate_nonce(char *buf, int len) +{ + const char charset[] = "0123456789"; + + if (buf == NULL || len < 1) + return; + + while (len > 1) { + *buf++ = charset[(unsigned) (((float) sizeof(charset) - 1.0) * rand() / (RAND_MAX + 1.0))]; + len--; + } + + *buf = 0; +} + +static gchar *gg_hmac_sha1(const char *key, const char *message) +{ + PurpleCipherContext *context; + guchar digest[20]; + + context = purple_cipher_context_new_by_name("hmac", NULL); + purple_cipher_context_set_option(context, "hash", "sha1"); + 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)); +} + +static char *gg_oauth_generate_signature(const char *method, const char *url, const char *request, const char *consumer_secret, const char *token_secret) +{ + char *text, *key, *res; + gchar *url_e, *request_e, *consumer_secret_e, *token_secret_e; + + url_e = g_uri_escape_string(url, NULL, FALSE); + request_e = g_uri_escape_string(request, NULL, FALSE); + text = g_strdup_printf("%s&%s&%s", method, url_e, request_e); + g_free(url_e); + g_free(request_e); + + consumer_secret_e = g_uri_escape_string(consumer_secret, NULL, FALSE); + token_secret_e = g_uri_escape_string(token_secret, NULL, FALSE); + key = g_strdup_printf("%s&%s", consumer_secret, token_secret ? token_secret : ""); + g_free(consumer_secret_e); + g_free(token_secret_e); + + res = gg_hmac_sha1(key, text); + + free(key); + free(text); + + return res; +} + +char *gg_oauth_generate_header(const char *method, const char *url, const const char *consumer_key, const char *consumer_secret, const char *token, const char *token_secret) +{ + char *request, *signature, *res; + char nonce[80], timestamp[16]; + gg_oauth_parameter_t *params = NULL; + + if (gg_oauth_static_nonce == NULL) + gg_oauth_generate_nonce(nonce, sizeof(nonce)); + else { + strncpy(nonce, gg_oauth_static_nonce, sizeof(nonce) - 1); + nonce[sizeof(nonce) - 1] = 0; + } + + if (gg_oauth_static_timestamp == NULL) + snprintf(timestamp, sizeof(timestamp), "%ld", time(NULL)); + else { + strncpy(timestamp, gg_oauth_static_timestamp, sizeof(timestamp) - 1); + timestamp[sizeof(timestamp) - 1] = 0; + } + + gg_oauth_parameter_set(¶ms, "oauth_consumer_key", consumer_key); + gg_oauth_parameter_set(¶ms, "oauth_nonce", nonce); + gg_oauth_parameter_set(¶ms, "oauth_signature_method", "HMAC-SHA1"); + gg_oauth_parameter_set(¶ms, "oauth_timestamp", timestamp); + gg_oauth_parameter_set(¶ms, "oauth_token", token); + gg_oauth_parameter_set(¶ms, "oauth_version", "1.0"); + + request = gg_oauth_parameter_join(params, 0); + + signature = gg_oauth_generate_signature(method, url, request, consumer_secret, token_secret); + + free(request); + + gg_oauth_parameter_free(params); + params = NULL; + + if (signature == NULL) + return NULL; + + gg_oauth_parameter_set(¶ms, "oauth_version", "1.0"); + gg_oauth_parameter_set(¶ms, "oauth_nonce", nonce); + gg_oauth_parameter_set(¶ms, "oauth_timestamp", timestamp); + gg_oauth_parameter_set(¶ms, "oauth_consumer_key", consumer_key); + gg_oauth_parameter_set(¶ms, "oauth_token", token); + gg_oauth_parameter_set(¶ms, "oauth_signature_method", "HMAC-SHA1"); + gg_oauth_parameter_set(¶ms, "oauth_signature", signature); + + free(signature); + + res = gg_oauth_parameter_join(params, 1); + + gg_oauth_parameter_free(params); + + return res; +} +