Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2015-2021 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see
15 : <http://www.gnu.org/licenses/>
16 : */
17 : /**
18 : * @file lib/exchange_api_auditor_add_denomination.c
19 : * @brief functions for the auditor to add its signature for denomination at the exchange
20 : * @author Christian Grothoff
21 : */
22 : #include "platform.h"
23 : #include "taler_json_lib.h"
24 : #include <gnunet/gnunet_curl_lib.h>
25 : #include "taler_exchange_service.h"
26 : #include "auditor_api_curl_defaults.h"
27 : #include "taler_signatures.h"
28 : #include "taler_curl_lib.h"
29 : #include "taler_json_lib.h"
30 :
31 :
32 : struct TALER_EXCHANGE_AuditorAddDenominationHandle
33 : {
34 :
35 : /**
36 : * The url for this request.
37 : */
38 : char *url;
39 :
40 : /**
41 : * Minor context that holds body and headers.
42 : */
43 : struct TALER_CURL_PostContext post_ctx;
44 :
45 : /**
46 : * Handle for the request.
47 : */
48 : struct GNUNET_CURL_Job *job;
49 :
50 : /**
51 : * Function to call with the result.
52 : */
53 : TALER_EXCHANGE_AuditorAddDenominationCallback cb;
54 :
55 : /**
56 : * Closure for @a cb.
57 : */
58 : void *cb_cls;
59 :
60 : /**
61 : * Reference to the execution context.
62 : */
63 : struct GNUNET_CURL_Context *ctx;
64 : };
65 :
66 :
67 : /**
68 : * Function called when we're done processing the
69 : * HTTP POST /auditor/$AUDITOR_PUB/$H_DENOM_PUB request.
70 : *
71 : * @param cls the `struct TALER_EXCHANGE_AuditorAddDenominationHandle *`
72 : * @param response_code HTTP response code, 0 on error
73 : * @param response response body, NULL if not in JSON
74 : */
75 : static void
76 0 : handle_auditor_add_denomination_finished (void *cls,
77 : long response_code,
78 : const void *response)
79 : {
80 0 : struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah = cls;
81 0 : const json_t *json = response;
82 0 : struct TALER_EXCHANGE_HttpResponse hr = {
83 0 : .http_status = (unsigned int) response_code,
84 : .reply = json
85 : };
86 :
87 0 : ah->job = NULL;
88 0 : switch (response_code)
89 : {
90 0 : case MHD_HTTP_NO_CONTENT:
91 0 : break;
92 0 : case MHD_HTTP_FORBIDDEN:
93 0 : hr.ec = TALER_JSON_get_error_code (json);
94 0 : hr.hint = TALER_JSON_get_error_hint (json);
95 0 : break;
96 0 : case MHD_HTTP_NOT_FOUND:
97 0 : hr.ec = TALER_JSON_get_error_code (json);
98 0 : hr.hint = TALER_JSON_get_error_hint (json);
99 0 : break;
100 0 : case MHD_HTTP_GONE:
101 0 : hr.ec = TALER_JSON_get_error_code (json);
102 0 : hr.hint = TALER_JSON_get_error_hint (json);
103 0 : break;
104 0 : case MHD_HTTP_PRECONDITION_FAILED:
105 0 : hr.ec = TALER_JSON_get_error_code (json);
106 0 : hr.hint = TALER_JSON_get_error_hint (json);
107 0 : break;
108 0 : default:
109 : /* unexpected response code */
110 0 : if (NULL != json)
111 : {
112 0 : hr.ec = TALER_JSON_get_error_code (json);
113 0 : hr.hint = TALER_JSON_get_error_hint (json);
114 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
115 : "Unexpected response code %u/%d for exchange auditor-add-denomination at URL `%s'\n",
116 : (unsigned int) response_code,
117 : (int) hr.ec,
118 : ah->url);
119 : }
120 : else
121 : {
122 0 : hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
123 0 : hr.hint = NULL;
124 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
125 : "Unexpected HTTP response code %u (no JSON returned) at URL `%s'\n",
126 : (unsigned int) response_code,
127 : ah->url);
128 : }
129 0 : break;
130 : }
131 0 : if (NULL != ah->cb)
132 : {
133 0 : ah->cb (ah->cb_cls,
134 : &hr);
135 0 : ah->cb = NULL;
136 : }
137 0 : TALER_EXCHANGE_add_auditor_denomination_cancel (ah);
138 0 : }
139 :
140 :
141 : struct TALER_EXCHANGE_AuditorAddDenominationHandle *
142 0 : TALER_EXCHANGE_add_auditor_denomination (
143 : struct GNUNET_CURL_Context *ctx,
144 : const char *url,
145 : const struct TALER_DenominationHashP *h_denom_pub,
146 : const struct TALER_AuditorPublicKeyP *auditor_pub,
147 : const struct TALER_AuditorSignatureP *auditor_sig,
148 : TALER_EXCHANGE_AuditorAddDenominationCallback cb,
149 : void *cb_cls)
150 : {
151 : struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah;
152 : CURL *eh;
153 : json_t *body;
154 :
155 0 : ah = GNUNET_new (struct TALER_EXCHANGE_AuditorAddDenominationHandle);
156 0 : ah->cb = cb;
157 0 : ah->cb_cls = cb_cls;
158 0 : ah->ctx = ctx;
159 : {
160 : char apub_str[sizeof (*auditor_pub) * 2];
161 : char denom_str[sizeof (*h_denom_pub) * 2];
162 : char arg_str[sizeof (apub_str) + sizeof (denom_str) + 32];
163 : char *end;
164 :
165 0 : end = GNUNET_STRINGS_data_to_string (auditor_pub,
166 : sizeof (*auditor_pub),
167 : apub_str,
168 : sizeof (apub_str));
169 0 : *end = '\0';
170 0 : end = GNUNET_STRINGS_data_to_string (h_denom_pub,
171 : sizeof (*h_denom_pub),
172 : denom_str,
173 : sizeof (denom_str));
174 0 : *end = '\0';
175 0 : GNUNET_snprintf (arg_str,
176 : sizeof (arg_str),
177 : "auditors/%s/%s",
178 : apub_str,
179 : denom_str);
180 0 : ah->url = TALER_url_join (url,
181 : arg_str,
182 : NULL);
183 : }
184 0 : if (NULL == ah->url)
185 : {
186 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
187 : "Could not construct request URL.\n");
188 0 : GNUNET_free (ah);
189 0 : return NULL;
190 : }
191 0 : body = GNUNET_JSON_PACK (
192 : GNUNET_JSON_pack_data_auto ("auditor_sig",
193 : auditor_sig));
194 0 : eh = TALER_AUDITOR_curl_easy_get_ (ah->url);
195 0 : if ( (NULL == eh) ||
196 : (GNUNET_OK !=
197 0 : TALER_curl_easy_post (&ah->post_ctx,
198 : eh,
199 : body)) )
200 : {
201 0 : GNUNET_break (0);
202 0 : if (NULL != eh)
203 0 : curl_easy_cleanup (eh);
204 0 : json_decref (body);
205 0 : GNUNET_free (ah->url);
206 0 : return NULL;
207 : }
208 0 : json_decref (body);
209 0 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
210 : "Requesting URL '%s'\n",
211 : ah->url);
212 0 : ah->job = GNUNET_CURL_job_add2 (ctx,
213 : eh,
214 0 : ah->post_ctx.headers,
215 : &handle_auditor_add_denomination_finished,
216 : ah);
217 0 : if (NULL == ah->job)
218 : {
219 0 : TALER_EXCHANGE_add_auditor_denomination_cancel (ah);
220 0 : return NULL;
221 : }
222 0 : return ah;
223 : }
224 :
225 :
226 : void
227 0 : TALER_EXCHANGE_add_auditor_denomination_cancel (
228 : struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah)
229 : {
230 0 : if (NULL != ah->job)
231 : {
232 0 : GNUNET_CURL_job_cancel (ah->job);
233 0 : ah->job = NULL;
234 : }
235 0 : TALER_curl_easy_post_finished (&ah->post_ctx);
236 0 : GNUNET_free (ah->url);
237 0 : GNUNET_free (ah);
238 0 : }
|