Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 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 : /**
10 : * @file lib/exchange_api_get-aml-OFFICER_PUB.c
11 : * @brief Implementation of GET /aml/$OFFICER_PUB
12 : */
13 : #include <microhttpd.h>
14 : #include <gnunet/gnunet_util_lib.h>
15 : #include <gnunet/gnunet_curl_lib.h>
16 : #include "taler/taler_json_lib.h"
17 : #include "taler/exchange/get-aml-OFFICER_PUB.h"
18 : #include "exchange_api_handle.h"
19 : #include "taler/taler_signatures.h"
20 : #include "exchange_api_curl_defaults.h"
21 :
22 :
23 : /**
24 : * Handle for GET /aml/$OFFICER_PUB.
25 : */
26 : struct TALER_EXCHANGE_GetAmlOfficerHandle
27 : {
28 : char *base_url;
29 : char *url;
30 : struct GNUNET_CURL_Job *job;
31 : TALER_EXCHANGE_GetAmlOfficerCallback cb;
32 : TALER_EXCHANGE_GET_AML_OFFICER_RESULT_CLOSURE *cb_cls;
33 : struct GNUNET_CURL_Context *ctx;
34 : struct TALER_AmlOfficerPublicKeyP officer_pub;
35 : struct TALER_AmlOfficerPrivateKeyP officer_priv;
36 : };
37 :
38 :
39 : /**
40 : * Process a completed request.
41 : *
42 : * @param cls operation handle
43 : * @param response_code HTTP status, 0 on transport failure
44 : * @param response parsed JSON response
45 : */
46 : static void
47 3 : handle_get_aml_officer_finished (void *cls,
48 : long response_code,
49 : const void *response)
50 : {
51 3 : struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh = cls;
52 3 : const json_t *j = response;
53 3 : struct TALER_EXCHANGE_GetAmlOfficerResponse result = {
54 : .hr.reply = j,
55 3 : .hr.http_status = (unsigned int) response_code
56 : };
57 :
58 3 : gaoh->job = NULL;
59 3 : switch (response_code)
60 : {
61 0 : case 0:
62 0 : result.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
63 0 : break;
64 2 : case MHD_HTTP_OK:
65 : {
66 : struct GNUNET_JSON_Specification spec[] = {
67 2 : GNUNET_JSON_spec_string (
68 : "officer_name",
69 : &result.details.ok.officer_name),
70 2 : GNUNET_JSON_spec_bool (
71 : "read_only",
72 : &result.details.ok.read_only),
73 2 : GNUNET_JSON_spec_end ()
74 : };
75 :
76 2 : if (GNUNET_OK !=
77 2 : GNUNET_JSON_parse (j,
78 : spec,
79 : NULL,
80 : NULL))
81 : {
82 0 : GNUNET_break_op (0);
83 0 : result.hr.http_status = 0;
84 0 : result.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
85 : }
86 2 : break;
87 : }
88 1 : case MHD_HTTP_BAD_REQUEST:
89 : case MHD_HTTP_FORBIDDEN:
90 : case MHD_HTTP_INTERNAL_SERVER_ERROR:
91 1 : result.hr.ec = TALER_JSON_get_error_code (j);
92 1 : result.hr.hint = TALER_JSON_get_error_hint (j);
93 1 : break;
94 0 : default:
95 0 : GNUNET_break_op (0);
96 0 : result.hr.ec = TALER_JSON_get_error_code (j);
97 0 : result.hr.hint = TALER_JSON_get_error_hint (j);
98 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
99 : "Unexpected response code %u/%d for GET AML officer\n",
100 : (unsigned int) response_code,
101 : (int) result.hr.ec);
102 0 : break;
103 : }
104 3 : gaoh->cb (gaoh->cb_cls,
105 : &result);
106 3 : gaoh->cb = NULL;
107 3 : TALER_EXCHANGE_get_aml_officer_cancel (gaoh);
108 3 : }
109 :
110 :
111 : struct TALER_EXCHANGE_GetAmlOfficerHandle *
112 3 : TALER_EXCHANGE_get_aml_officer_create (
113 : struct GNUNET_CURL_Context *ctx,
114 : const char *url,
115 : const struct TALER_AmlOfficerPrivateKeyP *officer_priv)
116 : {
117 : struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh;
118 :
119 3 : gaoh = GNUNET_new (struct TALER_EXCHANGE_GetAmlOfficerHandle);
120 3 : gaoh->ctx = ctx;
121 3 : gaoh->base_url = GNUNET_strdup (url);
122 3 : gaoh->officer_priv = *officer_priv;
123 3 : GNUNET_CRYPTO_eddsa_key_get_public (&officer_priv->eddsa_priv,
124 : &gaoh->officer_pub.eddsa_pub);
125 3 : return gaoh;
126 : }
127 :
128 :
129 : enum TALER_ErrorCode
130 3 : TALER_EXCHANGE_get_aml_officer_start (
131 : struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh,
132 : TALER_EXCHANGE_GetAmlOfficerCallback cb,
133 : TALER_EXCHANGE_GET_AML_OFFICER_RESULT_CLOSURE *cb_cls)
134 : {
135 : CURL *eh;
136 : struct TALER_AmlOfficerSignatureP officer_sig;
137 : char arg_str[sizeof (struct TALER_AmlOfficerPublicKeyP) * 2 + 16];
138 3 : struct curl_slist *job_headers = NULL;
139 : char pub_str[sizeof (gaoh->officer_pub) * 2];
140 : char sig_str[sizeof (officer_sig) * 2];
141 : char *end;
142 : char *hdr;
143 :
144 3 : gaoh->cb = cb;
145 3 : gaoh->cb_cls = cb_cls;
146 3 : TALER_officer_aml_query_sign (&gaoh->officer_priv,
147 : &officer_sig);
148 3 : end = GNUNET_STRINGS_data_to_string (&gaoh->officer_pub,
149 : sizeof (gaoh->officer_pub),
150 : pub_str,
151 : sizeof (pub_str));
152 3 : *end = '\0';
153 3 : GNUNET_snprintf (arg_str,
154 : sizeof (arg_str),
155 : "aml/%s",
156 : pub_str);
157 3 : gaoh->url = TALER_url_join (gaoh->base_url,
158 : arg_str,
159 : NULL);
160 3 : if (NULL == gaoh->url)
161 0 : return TALER_EC_GENERIC_CONFIGURATION_INVALID;
162 3 : eh = TALER_EXCHANGE_curl_easy_get_ (gaoh->url);
163 3 : if (NULL == eh)
164 : {
165 0 : GNUNET_free (gaoh->url);
166 0 : gaoh->url = NULL;
167 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
168 : }
169 3 : end = GNUNET_STRINGS_data_to_string (&officer_sig,
170 : sizeof (officer_sig),
171 : sig_str,
172 : sizeof (sig_str));
173 3 : *end = '\0';
174 3 : GNUNET_asprintf (&hdr,
175 : "%s: %s",
176 : TALER_AML_OFFICER_SIGNATURE_HEADER,
177 : sig_str);
178 3 : job_headers = curl_slist_append (NULL,
179 : hdr);
180 3 : GNUNET_free (hdr);
181 3 : gaoh->job = GNUNET_CURL_job_add2 (gaoh->ctx,
182 : eh,
183 : job_headers,
184 : &handle_get_aml_officer_finished,
185 : gaoh);
186 3 : curl_slist_free_all (job_headers);
187 3 : if (NULL == gaoh->job)
188 : {
189 0 : GNUNET_free (gaoh->url);
190 0 : gaoh->url = NULL;
191 0 : return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
192 : }
193 3 : return TALER_EC_NONE;
194 : }
195 :
196 :
197 : void
198 3 : TALER_EXCHANGE_get_aml_officer_cancel (
199 : struct TALER_EXCHANGE_GetAmlOfficerHandle *gaoh)
200 : {
201 3 : if (NULL != gaoh->job)
202 : {
203 0 : GNUNET_CURL_job_cancel (gaoh->job);
204 0 : gaoh->job = NULL;
205 : }
206 3 : GNUNET_free (gaoh->url);
207 3 : GNUNET_free (gaoh->base_url);
208 3 : GNUNET_free (gaoh);
209 3 : }
210 :
211 :
212 : /* end of exchange_api_get-aml-OFFICER_PUB.c */
|