Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2015-2026 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_post-auditors-AUDITOR_PUB-H_DENOM_PUB.c
19 : * @brief functions for the auditor to add its signature for denomination at the exchange
20 : * @author Christian Grothoff
21 : */
22 : #include "taler/platform.h"
23 : #include "taler/taler_json_lib.h"
24 : #include <gnunet/gnunet_curl_lib.h>
25 : #include <microhttpd.h>
26 : #include "taler/taler_exchange_service.h"
27 : #include "taler/taler-exchange/post-auditors-AUDITOR_PUB-H_DENOM_PUB.h"
28 : #include "auditor_api_curl_defaults.h"
29 : #include "taler/taler_signatures.h"
30 : #include "taler/taler_curl_lib.h"
31 :
32 :
33 : struct TALER_EXCHANGE_PostAuditorsHandle
34 : {
35 :
36 : /**
37 : * The base URL for this request.
38 : */
39 : char *base_url;
40 :
41 : /**
42 : * The full URL for this request, set during _start.
43 : */
44 : char *url;
45 :
46 : /**
47 : * Minor context that holds body and headers.
48 : */
49 : struct TALER_CURL_PostContext post_ctx;
50 :
51 : /**
52 : * Handle for the request.
53 : */
54 : struct GNUNET_CURL_Job *job;
55 :
56 : /**
57 : * Function to call with the result.
58 : */
59 : TALER_EXCHANGE_PostAuditorsCallback cb;
60 :
61 : /**
62 : * Closure for @a cb.
63 : */
64 : TALER_EXCHANGE_POST_AUDITORS_RESULT_CLOSURE *cb_cls;
65 :
66 : /**
67 : * Reference to the execution context.
68 : */
69 : struct GNUNET_CURL_Context *ctx;
70 :
71 : /**
72 : * Hash of the denomination public key.
73 : */
74 : struct TALER_DenominationHashP h_denom_pub;
75 :
76 : /**
77 : * The auditor's public key.
78 : */
79 : struct TALER_AuditorPublicKeyP auditor_pub;
80 :
81 : /**
82 : * The auditor's signature.
83 : */
84 : struct TALER_AuditorSignatureP auditor_sig;
85 :
86 : };
87 :
88 :
89 : /**
90 : * Function called when we're done processing the
91 : * HTTP POST /auditor/$AUDITOR_PUB/$H_DENOM_PUB request.
92 : *
93 : * @param cls the `struct TALER_EXCHANGE_PostAuditorsHandle *`
94 : * @param response_code HTTP response code, 0 on error
95 : * @param response response body, NULL if not in JSON
96 : */
97 : static void
98 240 : handle_auditor_add_denomination_finished (void *cls,
99 : long response_code,
100 : const void *response)
101 : {
102 240 : struct TALER_EXCHANGE_PostAuditorsHandle *ah = cls;
103 240 : const json_t *json = response;
104 240 : struct TALER_EXCHANGE_PostAuditorsResponse adr = {
105 240 : .hr.http_status = (unsigned int) response_code,
106 : .hr.reply = json
107 : };
108 :
109 240 : ah->job = NULL;
110 240 : switch (response_code)
111 : {
112 240 : case MHD_HTTP_NO_CONTENT:
113 240 : break;
114 0 : case MHD_HTTP_FORBIDDEN:
115 0 : adr.hr.ec = TALER_JSON_get_error_code (json);
116 0 : adr.hr.hint = TALER_JSON_get_error_hint (json);
117 0 : break;
118 0 : case MHD_HTTP_NOT_FOUND:
119 0 : adr.hr.ec = TALER_JSON_get_error_code (json);
120 0 : adr.hr.hint = TALER_JSON_get_error_hint (json);
121 0 : break;
122 0 : case MHD_HTTP_GONE:
123 0 : adr.hr.ec = TALER_JSON_get_error_code (json);
124 0 : adr.hr.hint = TALER_JSON_get_error_hint (json);
125 0 : break;
126 0 : case MHD_HTTP_PRECONDITION_FAILED:
127 0 : adr.hr.ec = TALER_JSON_get_error_code (json);
128 0 : adr.hr.hint = TALER_JSON_get_error_hint (json);
129 0 : break;
130 0 : default:
131 : /* unexpected response code */
132 0 : if (NULL != json)
133 : {
134 0 : adr.hr.ec = TALER_JSON_get_error_code (json);
135 0 : adr.hr.hint = TALER_JSON_get_error_hint (json);
136 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
137 : "Unexpected response code %u/%d for exchange auditor-add-denomination at URL `%s'\n",
138 : (unsigned int) response_code,
139 : (int) adr.hr.ec,
140 : ah->url);
141 : }
142 : else
143 : {
144 0 : adr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
145 0 : adr.hr.hint = NULL;
146 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
147 : "Unexpected HTTP response code %u (no JSON returned) at URL `%s'\n",
148 : (unsigned int) response_code,
149 : ah->url);
150 : }
151 0 : break;
152 : }
153 240 : if (NULL != ah->cb)
154 : {
155 240 : ah->cb (ah->cb_cls,
156 : &adr);
157 240 : ah->cb = NULL;
158 : }
159 240 : TALER_EXCHANGE_post_auditors_cancel (ah);
160 240 : }
161 :
162 :
163 : struct TALER_EXCHANGE_PostAuditorsHandle *
164 240 : TALER_EXCHANGE_post_auditors_create (
165 : struct GNUNET_CURL_Context *ctx,
166 : const char *url,
167 : const struct TALER_DenominationHashP *h_denom_pub,
168 : const struct TALER_AuditorPublicKeyP *auditor_pub,
169 : const struct TALER_AuditorSignatureP *auditor_sig)
170 : {
171 : struct TALER_EXCHANGE_PostAuditorsHandle *ah;
172 :
173 240 : ah = GNUNET_new (struct TALER_EXCHANGE_PostAuditorsHandle);
174 240 : ah->ctx = ctx;
175 240 : ah->base_url = GNUNET_strdup (url);
176 240 : ah->h_denom_pub = *h_denom_pub;
177 240 : ah->auditor_pub = *auditor_pub;
178 240 : ah->auditor_sig = *auditor_sig;
179 240 : return ah;
180 : }
181 :
182 :
183 : enum TALER_ErrorCode
184 240 : TALER_EXCHANGE_post_auditors_start (
185 : struct TALER_EXCHANGE_PostAuditorsHandle *ah,
186 : TALER_EXCHANGE_PostAuditorsCallback cb,
187 : TALER_EXCHANGE_POST_AUDITORS_RESULT_CLOSURE *cb_cls)
188 : {
189 : CURL *eh;
190 : json_t *body;
191 :
192 240 : ah->cb = cb;
193 240 : ah->cb_cls = cb_cls;
194 : {
195 : char apub_str[sizeof (ah->auditor_pub) * 2];
196 : char denom_str[sizeof (ah->h_denom_pub) * 2];
197 : char arg_str[sizeof (apub_str) + sizeof (denom_str) + 32];
198 : char *end;
199 :
200 240 : end = GNUNET_STRINGS_data_to_string (&ah->auditor_pub,
201 : sizeof (ah->auditor_pub),
202 : apub_str,
203 : sizeof (apub_str));
204 240 : *end = '\0';
205 240 : end = GNUNET_STRINGS_data_to_string (&ah->h_denom_pub,
206 : sizeof (ah->h_denom_pub),
207 : denom_str,
208 : sizeof (denom_str));
209 240 : *end = '\0';
210 240 : GNUNET_snprintf (arg_str,
211 : sizeof (arg_str),
212 : "auditors/%s/%s",
213 : apub_str,
214 : denom_str);
215 240 : ah->url = TALER_url_join (ah->base_url,
216 : arg_str,
217 : NULL);
218 : }
219 240 : if (NULL == ah->url)
220 : {
221 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
222 : "Could not construct request URL.\n");
223 0 : return TALER_EC_GENERIC_CONFIGURATION_INVALID;
224 : }
225 240 : body = GNUNET_JSON_PACK (
226 : GNUNET_JSON_pack_data_auto ("auditor_sig",
227 : &ah->auditor_sig));
228 240 : eh = TALER_AUDITOR_curl_easy_get_ (ah->url);
229 480 : if ( (NULL == eh) ||
230 : (GNUNET_OK !=
231 240 : TALER_curl_easy_post (&ah->post_ctx,
232 : eh,
233 : body)) )
234 : {
235 0 : GNUNET_break (0);
236 0 : if (NULL != eh)
237 0 : curl_easy_cleanup (eh);
238 0 : json_decref (body);
239 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
240 : }
241 240 : json_decref (body);
242 240 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
243 : "Requesting URL '%s'\n",
244 : ah->url);
245 480 : ah->job = GNUNET_CURL_job_add2 (ah->ctx,
246 : eh,
247 240 : ah->post_ctx.headers,
248 : &handle_auditor_add_denomination_finished,
249 : ah);
250 240 : if (NULL == ah->job)
251 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
252 240 : return TALER_EC_NONE;
253 : }
254 :
255 :
256 : void
257 240 : TALER_EXCHANGE_post_auditors_cancel (
258 : struct TALER_EXCHANGE_PostAuditorsHandle *ah)
259 : {
260 240 : if (NULL != ah->job)
261 : {
262 0 : GNUNET_CURL_job_cancel (ah->job);
263 0 : ah->job = NULL;
264 : }
265 240 : TALER_curl_easy_post_finished (&ah->post_ctx);
266 240 : GNUNET_free (ah->url);
267 240 : GNUNET_free (ah->base_url);
268 240 : GNUNET_free (ah);
269 240 : }
270 :
271 :
272 : /* end of exchange_api_post-auditors-AUDITOR_PUB-H_DENOM_PUB.c */
|