1 /*
2  * SPDX-FileCopyrightText: 2021 Marek Chalupa <mchalupa@redhat.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  */
6 
7 #include "flickr-oauth.h"
8 
9 #include <glib.h>
10 #include <stdlib.h>
11 
12 #include <string.h>
13 #include <oauth.h>
14 
15 /* ----------------- private functions declarations ----------------- */
16 
17 static gchar *
18 get_timestamp (void);
19 
20 static void
21 free_params (gchar **params, gint params_no);
22 
23 /* -------------------------- public API  -------------------------- */
24 
25 gchar *
flickroauth_get_signature(const gchar * consumer_secret,const gchar * token_secret,const gchar * url,gchar ** params,gint params_no)26 flickroauth_get_signature (const gchar *consumer_secret,
27                            const gchar *token_secret,
28                            const gchar *url,
29                            gchar **params,
30                            gint params_no)
31 {
32   gchar *params_string;
33   gchar *base_string;
34   gchar *encryption_key;
35   gchar *signature;
36 
37   qsort (params, params_no, sizeof (gchar *), oauth_cmpstringp);
38 
39   params_string = oauth_serialize_url (params_no, 0, params);
40 
41   base_string = oauth_catenc (3, FLICKR_OAUTH_HTTP_METHOD,
42                                 url, params_string);
43 
44   g_free (params_string);
45 
46   if (token_secret == NULL)
47     encryption_key = g_strdup_printf ("%s&", consumer_secret);
48   else
49     encryption_key = g_strdup_printf ("%s&%s",
50                                       consumer_secret,
51                                       token_secret);
52 
53   signature = oauth_sign_hmac_sha1 (base_string, encryption_key);
54 
55   g_free (encryption_key);
56   g_free (base_string);
57 
58   return signature;
59 }
60 
61 
62 gchar *
flickroauth_create_api_url(const gchar * consumer_key,const gchar * consumer_secret,const gchar * oauth_token,const gchar * oauth_token_secret,gchar ** params,const guint params_no)63 flickroauth_create_api_url (const gchar *consumer_key,
64                             const gchar *consumer_secret,
65                             const gchar *oauth_token,
66                             const gchar *oauth_token_secret,
67                             gchar **params,
68                             const guint params_no)
69 {
70   guint i;
71   gchar *nonce;
72   gchar *timestamp;
73   gchar *signature;
74   gchar *url;
75   gchar *params_string;
76 
77   g_return_val_if_fail (consumer_key, NULL);
78 
79   /* handle Non-authorised call */
80   if (oauth_token == NULL)
81   {
82     params_string = oauth_serialize_url (params_no, 0, params);
83 
84     url = g_strdup_printf ("%s?api_key=%s&%s", FLICKR_API_URL,
85                                                consumer_key,
86                                                params_string);
87 
88     g_free (params_string);
89 
90     return url;
91   }
92 
93   /* there are 7 pre-filled parameters  in authorize call*/
94   guint params_all_no = params_no + 7;
95   gchar **params_all = g_malloc ((params_all_no) * sizeof (gchar *));
96 
97   if (params_all == NULL)
98     return NULL;
99 
100   nonce = oauth_gen_nonce ();
101   timestamp = get_timestamp ();
102 
103   params_all[0] = g_strdup_printf ("oauth_nonce=%s", nonce);
104   params_all[1] = g_strdup_printf ("oauth_timestamp=%s", timestamp);
105   params_all[2] = g_strdup_printf ("oauth_consumer_key=%s",
106                                    consumer_key);
107   params_all[3] = g_strdup_printf ("oauth_signature_method=%s",
108                                    FLICKR_OAUTH_SIGNATURE_METHOD);
109   params_all[4] = g_strdup_printf ("oauth_version=%s",
110                                    FLICKR_OAUTH_VERSION);
111   params_all[5] = g_strdup_printf ("oauth_token=%s", oauth_token);
112 
113   /* copy user parameters to the params_all */
114   for (i = 0; i < params_no; i++)
115     params_all[7 + i - 1] = g_strdup (params[i]);
116 
117   g_free (nonce);
118   g_free (timestamp);
119 
120   signature = flickroauth_get_signature (consumer_secret,
121                                          oauth_token_secret,
122                                          FLICKR_API_URL, params_all,
123                                          params_all_no - 1);
124 
125   params_all[params_all_no - 1] = g_strdup_printf ("oauth_signature=%s",
126                                                    signature);
127   g_free (signature);
128 
129   params_string = oauth_serialize_url (params_all_no, 0, params_all);
130 
131   free_params (params_all, params_all_no);
132   g_free (params_all);
133 
134   url = g_strdup_printf ("%s?%s", FLICKR_API_URL, params_string);
135 
136   return url;
137 }
138 
139 inline gchar *
flickroauth_authorization_url(const gchar * oauth_token,const gchar * perms)140 flickroauth_authorization_url (const gchar *oauth_token,
141                                const gchar *perms)
142 {
143   gchar *url;
144   if (perms == NULL)
145     url = g_strdup_printf ("%s?oauth_token=%s", FLICKR_OAUTH_AUTHPOINT,
146                                               oauth_token);
147   else
148     url = g_strdup_printf ("%s?oauth_token=%s&perms=%s",
149                            FLICKR_OAUTH_AUTHPOINT,
150                            oauth_token, perms);
151 
152   return url;
153 }
154 
155 /* ----------------------- private functions ----------------------- */
156 
157 inline static gchar *
get_timestamp(void)158 get_timestamp (void)
159 {
160   GTimeVal tm;
161   g_get_current_time (&tm);
162 
163   return g_strdup_printf ("%lu", tm.tv_sec);
164 }
165 
166 static void
free_params(gchar ** params,gint params_no)167 free_params (gchar **params, gint params_no)
168 {
169   gint i;
170   for (i = 0; i < params_no; i++)
171     g_free (params[i]);
172 }
173