libpurple/protocols/gg/oauth/oauth.c

branch
soc.2012.gg
changeset 33329
cf23e0f1861a
child 33343
09f740724036
equal deleted inserted replaced
33328:c71e5e8976ba 33329:cf23e0f1861a
1 /*
2 * (C) Copyright 2008 Wojtek Kaniewski <wojtekka@irc.pl>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License Version
6 * 2.1 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19 // source: http://toxygen.net/libgadu/
20
21 #include "oauth.h"
22
23 #include "oauth-parameter.h"
24 #include <cipher.h>
25
26 char *gg_oauth_static_nonce; /* dla unit testów */
27 char *gg_oauth_static_timestamp; /* dla unit testów */
28
29 static void gg_oauth_generate_nonce(char *buf, int len)
30 {
31 const char charset[] = "0123456789";
32
33 if (buf == NULL || len < 1)
34 return;
35
36 while (len > 1) {
37 *buf++ = charset[(unsigned) (((float) sizeof(charset) - 1.0) * rand() / (RAND_MAX + 1.0))];
38 len--;
39 }
40
41 *buf = 0;
42 }
43
44 static gchar *gg_hmac_sha1(const char *key, const char *message)
45 {
46 PurpleCipherContext *context;
47 guchar digest[20];
48
49 context = purple_cipher_context_new_by_name("hmac", NULL);
50 purple_cipher_context_set_option(context, "hash", "sha1");
51 purple_cipher_context_set_key(context, (guchar *)key);
52 purple_cipher_context_append(context, (guchar *)message, strlen(message));
53 purple_cipher_context_digest(context, sizeof(digest), digest, NULL);
54 purple_cipher_context_destroy(context);
55
56 return purple_base64_encode(digest, sizeof(digest));
57 }
58
59 static char *gg_oauth_generate_signature(const char *method, const char *url, const char *request, const char *consumer_secret, const char *token_secret)
60 {
61 char *text, *key, *res;
62 gchar *url_e, *request_e, *consumer_secret_e, *token_secret_e;
63
64 url_e = g_uri_escape_string(url, NULL, FALSE);
65 request_e = g_uri_escape_string(request, NULL, FALSE);
66 text = g_strdup_printf("%s&%s&%s", method, url_e, request_e);
67 g_free(url_e);
68 g_free(request_e);
69
70 consumer_secret_e = g_uri_escape_string(consumer_secret, NULL, FALSE);
71 token_secret_e = g_uri_escape_string(token_secret, NULL, FALSE);
72 key = g_strdup_printf("%s&%s", consumer_secret, token_secret ? token_secret : "");
73 g_free(consumer_secret_e);
74 g_free(token_secret_e);
75
76 res = gg_hmac_sha1(key, text);
77
78 free(key);
79 free(text);
80
81 return res;
82 }
83
84 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)
85 {
86 char *request, *signature, *res;
87 char nonce[80], timestamp[16];
88 gg_oauth_parameter_t *params = NULL;
89
90 if (gg_oauth_static_nonce == NULL)
91 gg_oauth_generate_nonce(nonce, sizeof(nonce));
92 else {
93 strncpy(nonce, gg_oauth_static_nonce, sizeof(nonce) - 1);
94 nonce[sizeof(nonce) - 1] = 0;
95 }
96
97 if (gg_oauth_static_timestamp == NULL)
98 snprintf(timestamp, sizeof(timestamp), "%ld", time(NULL));
99 else {
100 strncpy(timestamp, gg_oauth_static_timestamp, sizeof(timestamp) - 1);
101 timestamp[sizeof(timestamp) - 1] = 0;
102 }
103
104 gg_oauth_parameter_set(&params, "oauth_consumer_key", consumer_key);
105 gg_oauth_parameter_set(&params, "oauth_nonce", nonce);
106 gg_oauth_parameter_set(&params, "oauth_signature_method", "HMAC-SHA1");
107 gg_oauth_parameter_set(&params, "oauth_timestamp", timestamp);
108 gg_oauth_parameter_set(&params, "oauth_token", token);
109 gg_oauth_parameter_set(&params, "oauth_version", "1.0");
110
111 request = gg_oauth_parameter_join(params, 0);
112
113 signature = gg_oauth_generate_signature(method, url, request, consumer_secret, token_secret);
114
115 free(request);
116
117 gg_oauth_parameter_free(params);
118 params = NULL;
119
120 if (signature == NULL)
121 return NULL;
122
123 gg_oauth_parameter_set(&params, "oauth_version", "1.0");
124 gg_oauth_parameter_set(&params, "oauth_nonce", nonce);
125 gg_oauth_parameter_set(&params, "oauth_timestamp", timestamp);
126 gg_oauth_parameter_set(&params, "oauth_consumer_key", consumer_key);
127 gg_oauth_parameter_set(&params, "oauth_token", token);
128 gg_oauth_parameter_set(&params, "oauth_signature_method", "HMAC-SHA1");
129 gg_oauth_parameter_set(&params, "oauth_signature", signature);
130
131 free(signature);
132
133 res = gg_oauth_parameter_join(params, 1);
134
135 gg_oauth_parameter_free(params);
136
137 return res;
138 }
139

mercurial