anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

anastasis-httpd.h (8996B)


      1 /*
      2   This file is part of Anastasis
      3   Copyright (C) 2019 Anastasis SARL
      4 
      5   Anastasis is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Anastasis 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 Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   Anastasis; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file backend/anastasis-httpd.h
     18  * @brief HTTP serving layer
     19  * @author Christian Grothoff
     20  */
     21 #ifndef ANASTASIS_HTTPD_H
     22 #define ANASTASIS_HTTPD_H
     23 
     24 #include "platform.h"
     25 #include "anastasis_database_lib.h"
     26 #include <microhttpd.h>
     27 #include <taler/taler_mhd_lib.h>
     28 #include <taler/merchant/get-private-orders-ORDER_ID.h>
     29 #include <gnunet/gnunet_mhd_compat.h>
     30 
     31 
     32 /**
     33  * For how many years do we allow users to store truth at most? Also
     34  * how long we store things if the cost is zero.
     35  */
     36 #define ANASTASIS_MAX_YEARS_STORAGE 5
     37 
     38 
     39 /**
     40  * @brief Struct describing an URL and the handler for it.
     41  */
     42 struct AH_RequestHandler
     43 {
     44 
     45   /**
     46    * URL the handler is for.
     47    */
     48   const char *url;
     49 
     50   /**
     51    * Method the handler is for, NULL for "all".
     52    */
     53   const char *method;
     54 
     55   /**
     56    * Mime type to use in reply (hint, can be NULL).
     57    */
     58   const char *mime_type;
     59 
     60   /**
     61    * Raw data for the @e handler
     62    */
     63   const void *data;
     64 
     65   /**
     66    * Number of bytes in @e data, 0 for 0-terminated.
     67    */
     68   size_t data_size;
     69 
     70 
     71   /**
     72    * Function to call to handle the request.
     73    *
     74    * @param rh this struct
     75    * @param connection the MHD connection to handle
     76    * @return MHD result code
     77    */
     78   enum MHD_Result (*handler)(struct AH_RequestHandler *rh,
     79                              struct MHD_Connection *connection);
     80 
     81   /**
     82    * Default response code.
     83    */
     84   unsigned int response_code;
     85 };
     86 
     87 
     88 /**
     89  * Each MHD response handler that sets the "connection_cls" to a
     90  * non-NULL value must use a struct that has this struct as its first
     91  * member.  This struct contains a single callback, which will be
     92  * invoked to clean up the memory when the contection is completed.
     93  */
     94 struct TM_HandlerContext;
     95 
     96 /**
     97  * Signature of a function used to clean up the context
     98  * we keep in the "connection_cls" of MHD when handling
     99  * a request.
    100  *
    101  * @param hc header of the context to clean up.
    102  */
    103 typedef void
    104 (*TM_ContextCleanup)(struct TM_HandlerContext *hc);
    105 
    106 
    107 /**
    108  * Each MHD response handler that sets the "connection_cls" to a
    109  * non-NULL value must use a struct that has this struct as its first
    110  * member.  This struct contains a single callback, which will be
    111  * invoked to clean up the memory when the connection is completed.
    112  */
    113 struct TM_HandlerContext
    114 {
    115 
    116   /**
    117    * Function to execute the handler-specific cleanup of the
    118    * (typically larger) context.
    119    */
    120   TM_ContextCleanup cc;
    121 
    122   /**
    123    * Handler-specific context.
    124    */
    125   void *ctx;
    126 
    127   /**
    128    * Which request handler is handling this request?
    129    */
    130   const struct AH_RequestHandler *rh;
    131 
    132   /**
    133    * URL requested by the client, for logging.
    134    */
    135   const char *url;
    136 
    137   /**
    138    * Asynchronous request context id.
    139    */
    140   struct GNUNET_AsyncScopeId async_scope_id;
    141 };
    142 
    143 /**
    144  * Upload limit to the service, in megabytes.
    145  */
    146 extern unsigned long long AH_upload_limit_mb;
    147 
    148 /**
    149  * Currencies this provider prices its service in, primary currency
    150  * first.  From [anastasis] CURRENCIES.  Every priced option below offers
    151  * exactly these currencies; that is checked at startup.
    152  */
    153 extern char **AH_currencies;
    154 
    155 /**
    156  * Length of the #AH_currencies array.
    157  */
    158 extern unsigned int AH_currencies_len;
    159 
    160 /**
    161  * Annual fee for the backup account, per currency.
    162  */
    163 extern struct TALER_AmountList AH_annual_fees;
    164 
    165 /**
    166  * Fee for a truth upload, per currency.
    167  */
    168 extern struct TALER_AmountList AH_truth_upload_fees;
    169 
    170 /**
    171  * Amount of insurance, per currency.
    172  */
    173 extern struct TALER_AmountList AH_insurance;
    174 
    175 /**
    176  * Cost for secure question truth download, per currency.
    177  */
    178 extern struct TALER_AmountList AH_question_costs;
    179 
    180 
    181 /**
    182  * Check that @a al is a usable price for a configuration option, and
    183  * fail the process if it is not.
    184  *
    185  * A price must be uniformly free or uniformly priced: offering the same
    186  * thing for money in one currency and for nothing in another does not
    187  * price the service, it prices the user's choice of currency, and every
    188  * wallet would simply pick the free one.  A priced option must further
    189  * offer exactly the currencies in #AH_currencies, or a user would find
    190  * out that some step of recovery is unavailable in their currency only
    191  * once the backup exists and the money is spent.
    192  *
    193  * @param al price list to check
    194  * @param section configuration section it came from, for diagnostics
    195  * @param option configuration option it came from, for diagnostics
    196  * @return #GNUNET_OK if @a al is priced in all of #AH_currencies,
    197  *         #GNUNET_NO if @a al is free (empty or all zero),
    198  *         #GNUNET_SYSERR if @a al is unusable; the caller must shut down
    199  */
    200 enum GNUNET_GenericReturnValue
    201 AH_check_price (const struct TALER_AmountList *al,
    202                 const char *section,
    203                 const char *option);
    204 
    205 
    206 /**
    207  * Return the price of @a al in the primary currency, for the scalar
    208  * fields that older clients read.
    209  *
    210  * A free option has no entry for any currency, and reports as zero in
    211  * the primary currency --- which is what a single-currency provider
    212  * running for free already emitted before there were price lists.
    213  *
    214  * @param al price list to look in
    215  * @return price in the primary currency; the pointer is only valid
    216  *         until the next call
    217  */
    218 const struct TALER_Amount *
    219 AH_primary_price (const struct TALER_AmountList *al);
    220 
    221 
    222 /**
    223  * Build the skeleton of a merchant "v1" order that offers every currency
    224  * in @a prices as a payable choice, letting the wallet settle in whichever
    225  * one it holds.
    226  *
    227  * Every entry of @a prices becomes a choice: none is dropped and none can
    228  * be zero, because #AH_check_price() refused to let the provider start on
    229  * a price list that mixes free and non-free currencies.  So the order is
    230  * either complete and payable in every currency the provider advertises,
    231  * or the caller decided the option was free and does not create an order
    232  * at all.
    233  *
    234  * The caller adds whatever else the order needs (products, deadlines, …)
    235  * to the returned object.
    236  *
    237  * @param order_id order ID to use
    238  * @param summary human-readable summary of the order
    239  * @param prices what the order costs, one entry per currency; must not
    240  *        be empty and must not contain a zero
    241  * @return the order object, caller must `json_decref()` it
    242  */
    243 json_t *
    244 AH_make_order (const char *order_id,
    245                const char *summary,
    246                const struct TALER_AmountList *prices);
    247 
    248 
    249 /**
    250  * Extract from a paid order status the amount the wallet actually paid,
    251  * in the currency it chose.
    252  *
    253  * A "v1" order has no top-level amount; the choice that was settled is at
    254  * ``choices[choice_index]``.  A ``choice_index`` of -1 means the contract
    255  * is a legacy "v0" one with a single top-level amount --- which is what
    256  * orders created before this provider was upgraded look like, and they
    257  * still have to settle.
    258  *
    259  * @param osr order status to inspect, must be #TALER_MERCHANT_OSC_PAID
    260  * @param[out] amount set to the amount that was paid
    261  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the contract terms
    262  *         did not contain a usable amount
    263  */
    264 enum GNUNET_GenericReturnValue
    265 AH_paid_amount (const struct TALER_MERCHANT_GetPrivateOrderResponse *osr,
    266                 struct TALER_Amount *amount);
    267 
    268 /**
    269  * Our Taler backend to process payments.
    270  */
    271 extern char *AH_backend_url;
    272 
    273 /**
    274  * Heap for processing timeouts of requests.
    275  */
    276 extern struct GNUNET_CONTAINER_Heap *AH_to_heap;
    277 
    278 /**
    279  * Our configuration.
    280  */
    281 extern const struct GNUNET_CONFIGURATION_Handle *AH_cfg;
    282 
    283 /**
    284  * Number of policy uploads permitted per annual fee payment.
    285  */
    286 extern unsigned long long AH_post_counter;
    287 
    288 /**
    289  * Our fulfillment URL
    290  */
    291 extern char *AH_fulfillment_url;
    292 
    293 /**
    294  * Our business name.
    295  */
    296 extern char *AH_business_name;
    297 
    298 /**
    299  * Our provider salt.
    300  */
    301 extern struct ANASTASIS_CRYPTO_ProviderSaltP AH_provider_salt;
    302 
    303 /**
    304  * Our context for making HTTP requests.
    305  */
    306 extern struct GNUNET_CURL_Context *AH_ctx;
    307 
    308 
    309 /**
    310  * Kick MHD to run now, to be called after MHD_resume_connection().
    311  * Basically, we need to explicitly resume MHD's event loop whenever
    312  * we made progress serving a request.  This function re-schedules
    313  * the task processing MHD's activities to run immediately.
    314  *
    315  * @param cls NULL
    316  */
    317 void
    318 AH_trigger_daemon (void *cls);
    319 
    320 /**
    321  * Kick GNUnet Curl scheduler to begin curl interactions.
    322  */
    323 void
    324 AH_trigger_curl (void);
    325 
    326 #endif