taler_util.h (33244B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2024 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 <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file include/taler/taler_util.h 18 * @brief Interface for common utility functions 19 * This library is not thread-safe, all APIs must only be used from a single thread. 20 * This library calls abort() if it runs out of memory. Be aware of these limitations. 21 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 22 * @author Christian Grothoff 23 */ 24 #ifndef TALER_UTIL_H 25 #define TALER_UTIL_H 26 27 #include <gnunet/gnunet_common.h> 28 #define __TALER_UTIL_LIB_H_INSIDE__ 29 30 #include <gnunet/gnunet_util_lib.h> 31 #include <taler/taler_amount_lib.h> 32 #include <taler/taler_crypto_lib.h> 33 34 35 /** 36 * Version of the Taler API, in hex. 37 * Thus 0.8.4-1 = 0x00080401. 38 */ 39 #define TALER_API_VERSION 0x000D0000 40 41 /** 42 * Stringify operator. 43 * 44 * @param a some expression to stringify. Must NOT be a macro. 45 * @return same expression as a constant string. 46 */ 47 #define TALER_S(a) #a 48 49 /** 50 * Stringify operator. 51 * 52 * @param a some expression to stringify. Can be a macro. 53 * @return macro-expanded expression as a constant string. 54 */ 55 #define TALER_QUOTE(a) TALER_S (a) 56 57 58 /* Define logging functions */ 59 #define TALER_LOG_DEBUG(...) \ 60 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) 61 62 #define TALER_LOG_INFO(...) \ 63 GNUNET_log (GNUNET_ERROR_TYPE_INFO, __VA_ARGS__) 64 65 #define TALER_LOG_WARNING(...) \ 66 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, __VA_ARGS__) 67 68 #define TALER_LOG_ERROR(...) \ 69 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, __VA_ARGS__) 70 71 72 /** 73 * Tests a given as assertion and if failed prints it as a warning with the 74 * given reason 75 * 76 * @param EXP the expression to test as assertion 77 * @param reason string to print as warning 78 */ 79 #define TALER_assert_as(EXP, reason) \ 80 do { \ 81 if (EXP) break; \ 82 TALER_LOG_ERROR ("%s at %s:%d\n", reason, __FILE__, __LINE__); \ 83 abort (); \ 84 } while (0) 85 86 87 /** 88 * HTTP header with an AML officer signature to approve the inquiry. 89 * Used only in GET Requests. 90 */ 91 #define TALER_AML_OFFICER_SIGNATURE_HEADER "Taler-AML-Officer-Signature" 92 93 /** 94 * Header with signature for reserve history requests. 95 */ 96 #define TALER_RESERVE_HISTORY_SIGNATURE_HEADER "Taler-Reserve-History-Signature" 97 98 /** 99 * Header with signature for coin history requests. 100 */ 101 #define TALER_COIN_HISTORY_SIGNATURE_HEADER "Taler-Coin-History-Signature" 102 103 /** 104 * Log an error message at log-level 'level' that indicates 105 * a failure of the command 'cmd' with the message given 106 * by gcry_strerror(rc). 107 */ 108 #define TALER_LOG_GCRY_ERROR(cmd, rc) do { TALER_LOG_ERROR ( \ 109 "`%s' failed at %s:%d with error: %s\n", \ 110 cmd, __FILE__, __LINE__, \ 111 gcry_strerror (rc)); } while (0) 112 113 114 #define TALER_gcry_ok(cmd) \ 115 do {int rc; rc = cmd; if (! rc) break; \ 116 TALER_LOG_ERROR ("A Gcrypt call failed at %s:%d with error: %s\n", \ 117 __FILE__, \ 118 __LINE__, gcry_strerror (rc)); abort (); } while (0 \ 119 ) 120 121 122 /** 123 * Initialize Gcrypt library. 124 */ 125 void 126 TALER_gcrypt_init (void); 127 128 129 /** 130 * Convert a buffer to an 8-character string 131 * representative of the contents. This is used 132 * for logging binary data when debugging. 133 * 134 * @param buf buffer to log 135 * @param buf_size number of bytes in @a buf 136 * @return text representation of buf, valid until next 137 * call to this function 138 */ 139 const char * 140 TALER_b2s (const void *buf, 141 size_t buf_size); 142 143 144 /** 145 * Compare two NUL-terminated strings @a a and @a b in constant time 146 * with respect to their contents. Used for comparing secret/MAC 147 * material (authorization codes, PKCE challenges) to avoid leaking 148 * information via a timing oracle, as plain strcmp() short-circuits 149 * at the first differing byte. Note that the string lengths may 150 * still leak, which is acceptable here as the token length is not 151 * a secret at all. 152 * 153 * @param a first string 154 * @param b second string 155 * @return 0 if the strings are equal, non-zero otherwise 156 */ 157 int 158 TALER_strcmp_ct (const char *a, 159 const char *b); 160 161 162 /** 163 * Convert a fixed-sized object to a string using 164 * #TALER_b2s(). 165 * 166 * @param obj address of object to convert 167 * @return string representing the binary obj buffer 168 */ 169 #define TALER_B2S(obj) TALER_b2s ((obj), sizeof (*(obj))) 170 171 172 /** 173 * Obtain denomination amount from configuration file. 174 * 175 * @param cfg configuration to extract data from 176 * @param section section of the configuration to access 177 * @param option option of the configuration to access 178 * @param[out] denom set to the amount found in configuration 179 * @return #GNUNET_OK on success, 180 * #GNUNET_NO if not found, 181 * #GNUNET_SYSERR on error 182 */ 183 enum GNUNET_GenericReturnValue 184 TALER_config_get_amount (const struct GNUNET_CONFIGURATION_Handle *cfg, 185 const char *section, 186 const char *option, 187 struct TALER_Amount *denom); 188 189 190 /** 191 * Obtain a price list of the form "EUR:1.1;CHF:1;USD:2" from the 192 * configuration file, for options where the same thing may be 193 * priced in several currencies at once. 194 * 195 * A plain "EUR:1.1" is a valid one-element list, so options that 196 * used to be read with #TALER_config_get_amount() can be moved to 197 * this function without invalidating existing configurations. 198 * 199 * @param cfg configuration to extract data from 200 * @param section section of the configuration to access 201 * @param option option of the configuration to access 202 * @param[out] al set to the price list found in the configuration; 203 * the caller must eventually free it using 204 * #TALER_amount_list_free() 205 * @return #GNUNET_OK on success, 206 * #GNUNET_NO if not found (@a al is set to the empty list), 207 * #GNUNET_SYSERR on error 208 */ 209 enum GNUNET_GenericReturnValue 210 TALER_config_get_amount_list (const struct GNUNET_CONFIGURATION_Handle *cfg, 211 const char *section, 212 const char *option, 213 struct TALER_AmountList *al); 214 215 216 /** 217 * Obtain denomination fee structure of a 218 * denomination from configuration file. All 219 * fee options must start with "fee_" and have 220 * names typical for the respective fees. 221 * 222 * @param cfg configuration to extract data from 223 * @param currency expected currency 224 * @param section section of the configuration to access 225 * @param[out] fees set to the denomination fees 226 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 227 */ 228 enum GNUNET_GenericReturnValue 229 TALER_config_get_denom_fees (const struct GNUNET_CONFIGURATION_Handle *cfg, 230 const char *currency, 231 const char *section, 232 struct TALER_DenomFeeSet *fees); 233 234 235 /** 236 * Check that all denominations in @a fees use 237 * @a currency 238 * 239 * @param currency desired currency 240 * @param fees fee set to check 241 * @return #GNUNET_OK on success 242 */ 243 enum GNUNET_GenericReturnValue 244 TALER_denom_fee_check_currency ( 245 const char *currency, 246 const struct TALER_DenomFeeSet *fees); 247 248 249 /** 250 * Load our currency from the @a cfg in @a section 251 * the option "CURRENCY". 252 * 253 * @param cfg configuration to use 254 * @param section configuration section to inspect 255 * @param[out] currency where to write the result 256 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 257 */ 258 enum GNUNET_GenericReturnValue 259 TALER_config_get_currency (const struct GNUNET_CONFIGURATION_Handle *cfg, 260 const char *section, 261 char **currency); 262 263 264 /** 265 * Details about how to render a currency. 266 */ 267 struct TALER_CurrencySpecification 268 { 269 /** 270 * Currency code of the currency. 271 */ 272 char currency[TALER_CURRENCY_LEN]; 273 274 /** 275 * Human-readable long name of the currency, e.g. 276 * "Japanese Yen". 277 */ 278 char *name; 279 280 /** 281 * how many digits the user may enter at most after the @e decimal_separator 282 */ 283 unsigned int num_fractional_input_digits; 284 285 /** 286 * how many digits we render in normal scale after the @e decimal_separator 287 */ 288 unsigned int num_fractional_normal_digits; 289 290 /** 291 * how many digits we render in after the @e decimal_separator even if all 292 * remaining digits are zero. 293 */ 294 unsigned int num_fractional_trailing_zero_digits; 295 296 /** 297 * Mapping of powers of 10 to alternative currency names or symbols. 298 * Keys are the decimal powers, values the currency symbol to use. 299 * Map MUST contain an entry for "0" to the default currency symbol. 300 */ 301 json_t *map_alt_unit_names; 302 303 /** 304 * Amounts wallet should display as short-cuts (for example, 305 * in the withdraw dialog). 306 */ 307 struct TALER_Amount *common_amounts; 308 309 /** 310 * Length of the @e common_amounts array. 311 */ 312 unsigned int num_common_amounts; 313 314 }; 315 316 317 /** 318 * Parse information about supported currencies from 319 * our configuration. 320 * 321 * @param cfg configuration to parse 322 * @param main_currency main currency of the component 323 * @param[out] num_currencies set to number of enabled currencies, length of @e cspecs 324 * @param[out] cspecs set to currency specification array 325 * @return #GNUNET_OK on success, #GNUNET_NO if zero 326 * currency specifications were enabled, 327 * #GNUNET_SYSERR if the configuration was malformed 328 */ 329 enum GNUNET_GenericReturnValue 330 TALER_CONFIG_parse_currencies (const struct GNUNET_CONFIGURATION_Handle *cfg, 331 const char *main_currency, 332 unsigned int *num_currencies, 333 struct TALER_CurrencySpecification **cspecs); 334 335 336 /** 337 * Free @a cspecs array. 338 * 339 * @param num_currencies length of @a cspecs array 340 * @param[in] cspecs array to free 341 */ 342 void 343 TALER_CONFIG_free_currencies ( 344 unsigned int num_currencies, 345 struct TALER_CurrencySpecification cspecs[static num_currencies]); 346 347 348 /** 349 * Check that @a map contains a valid currency scale 350 * map that maps integers from [-12,24] to currency 351 * symbols given as strings. 352 * 353 * @param map map to check 354 * @return #GNUNET_OK if @a map is valid 355 */ 356 enum GNUNET_GenericReturnValue 357 TALER_check_currency_scale_map (const json_t *map); 358 359 360 /** 361 * Allow user to specify an amount on the command line. 362 * 363 * @param shortName short name of the option 364 * @param name long name of the option 365 * @param argumentHelp help text for the option argument 366 * @param description long help text for the option 367 * @param[out] amount set to the amount specified at the command line 368 */ 369 struct GNUNET_GETOPT_CommandLineOption 370 TALER_getopt_get_amount (char shortName, 371 const char *name, 372 const char *argumentHelp, 373 const char *description, 374 struct TALER_Amount *amount); 375 376 377 /** 378 * Return default project data used by Taler exchange. 379 */ 380 const struct GNUNET_OS_ProjectData * 381 TALER_EXCHANGE_project_data (void); 382 383 384 /** 385 * Return default project data used by Taler auditor. 386 */ 387 const struct GNUNET_OS_ProjectData * 388 TALER_AUDITOR_project_data (void); 389 390 391 /** 392 * Return default project data used by Taler fakebank. 393 */ 394 const struct GNUNET_OS_ProjectData * 395 TALER_FAKEBANK_project_data (void); 396 397 398 /** 399 * Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2). 400 * 401 * @param[in,out] inp pointer to string to re-encode 402 * @return number of bytes in resulting @a inp 403 */ 404 size_t 405 TALER_rfc8785encode (char **inp); 406 407 408 /** 409 * URL-encode a string according to rfc3986. 410 * 411 * @param s string to encode 412 * @returns the urlencoded string, the caller must free it with GNUNET_free() 413 */ 414 char * 415 TALER_urlencode (const char *s); 416 417 418 /** 419 * Test if all characters in @a url are valid for 420 * a URL. 421 * 422 * @param url URL to sanity-check 423 * @return true if @a url only contains valid characters 424 */ 425 bool 426 TALER_url_valid_charset (const char *url); 427 428 429 /** 430 * Compare two full payto URIs for equality. 431 * 432 * @param a a full payto URI, NULL is permitted 433 * @param b a full payto URI, NULL is permitted 434 * @return 0 if both are equal, otherwise -1 or 1 435 */ 436 int 437 TALER_full_payto_cmp (const struct TALER_FullPayto a, 438 const struct TALER_FullPayto b); 439 440 /** 441 * Compare two full payto URIs for equality in their normalized form. 442 * 443 * @param a a full payto URI, NULL is permitted 444 * @param b a full payto URI, NULL is permitted 445 * @return 0 if both are equal, otherwise -1 or 1 446 */ 447 int 448 TALER_full_payto_normalize_and_cmp (const struct TALER_FullPayto a, 449 const struct TALER_FullPayto b); 450 451 452 /** 453 * Compare two normalized payto URIs for equality. 454 * 455 * @param a a full payto URI, NULL is permitted 456 * @param b a full payto URI, NULL is permitted 457 * @return 0 if both are equal, otherwise -1 or 1 458 */ 459 int 460 TALER_normalized_payto_cmp (const struct TALER_NormalizedPayto a, 461 const struct TALER_NormalizedPayto b); 462 463 464 /** 465 * Check if payto URI identifies a Taler wallet. 466 * 467 * @param payto_uri (full or normalized) to check 468 * @return true if the payto URI is for a wallet 469 */ 470 bool 471 TALER_payto_is_wallet (const char *payto_uri); 472 473 474 /** 475 * Test if the URL is a valid "http" (or "https") 476 * URL (includes test for #TALER_url_valid_charset()). 477 * 478 * @param url a string to test if it could be a valid URL 479 * @return true if @a url is well-formed 480 */ 481 bool 482 TALER_is_web_url (const char *url); 483 484 485 /** 486 * Check if a character is reserved and should be urlencoded. 487 * 488 * Unreserved characters: 489 * - ASCII letters: a-z A-Z 490 * - Digits: 0-9 491 * - Hyphen: - 492 * - Underscore: _ 493 * - Period: . 494 * - Tilde: ~ 495 * 496 * @param c character to look at 497 * @return true if @a c needs to be urlencoded, 498 * false otherwise (@a c in [a-zA-Z0-9_~.-]) 499 */ 500 bool 501 TALER_url_is_reserved (char c); 502 503 504 /** 505 * Test if the URL is a valid slug (URL-safe string). 506 * 507 * Allowed characters: 508 * - ASCII letters: a-z A-Z 509 * - Digits: 0-9 510 * - Hyphen: - 511 * - Underscore: _ 512 * - Period: . 513 * - Colon: : 514 * - Tilde: ~ (needed for core banking account usernames) 515 * 516 * Additional restrictions: 517 * - must not be empty 518 * - must not be "." or ".." 519 * - must not contain '/' 520 * - must not contain percent-encoding '%' 521 * 522 * @param slug a string to test if it could be a valid slug 523 * @return true if @a slug is well-formed 524 */ 525 bool 526 TALER_is_slug (const char *slug); 527 528 529 /** 530 * Test if @a session_id is a valid session ID, as used for 531 * session-based payments at a merchant. 532 * 533 * A session ID is deliberately *not* a slug: it may be empty, and it 534 * may contain '=' as session IDs are frequently base64-encoded 535 * identifiers (such as the Paivana IDs) that end in padding. 536 * 537 * Allowed characters: 538 * - ASCII letters: a-z A-Z 539 * - Digits: 0-9 540 * - Hyphen: - 541 * - Underscore: _ 542 * - Period: . 543 * - Colon: : 544 * - Equals: = (needed for base64-encoded identifiers) 545 * - Tilde: ~ 546 * 547 * Additional restrictions: 548 * - must not be "." or ".." 549 * - must not contain '/' 550 * - must not contain percent-encoding '%' 551 * 552 * The empty session ID is valid and means that a payment is not bound 553 * to any session; it is also what the merchant stores in its database 554 * in that case, and what it puts into the "taler://pay/" URI of an 555 * order without a session. Requests where only an actual session 556 * makes sense must thus check for the empty string in addition to 557 * calling this function. 558 * 559 * @param session_id a string to test if it could be a valid session ID 560 * @return true if @a session_id is well-formed 561 */ 562 bool 563 TALER_is_session_id (const char *session_id); 564 565 566 /** 567 * Check if @a lang matches the @a language_pattern, and if so with 568 * which preference. 569 * See also: https://tools.ietf.org/html/rfc7231#section-5.3.1 570 * 571 * @param pattern a preferences string 572 * like "fr-CH, fr;q=0.9, en;q=0.8, *;q=0.1" 573 * @param value the value to match 574 * @return q-weight given for @a value in @a pattern, 1.0 if no weights are given; 575 * 0 if @a value is not in @a pattern 576 */ 577 double 578 TALER_pattern_matches (const char *pattern, 579 const char *value); 580 581 582 /** 583 * Make an absolute URL with query parameters. 584 * 585 * If a 'value' is given as NULL, both the key and the value are skipped. Note 586 * that a NULL value does not terminate the list, only a NULL key signals the 587 * end of the list of arguments. 588 * 589 * @param base_url absolute base URL to use, must either 590 * end with '/' *or* @a path must be the empty string 591 * @param path path of the url to append to the @a base_url 592 * @param ... NULL-terminated key-value pairs (char *) for query parameters, 593 * only the value will be url-encoded 594 * @returns the URL, must be freed with #GNUNET_free 595 */ 596 char * 597 TALER_url_join (const char *base_url, 598 const char *path, 599 ...); 600 601 602 /** 603 * Make an absolute URL for the given parameters. 604 * 605 * If a 'value' is given as NULL, both the key and the value are skipped. Note 606 * that a NULL value does not terminate the list, only a NULL key signals the 607 * end of the list of arguments. 608 * 609 * @param proto protocol for the URL (typically https) 610 * @param host hostname for the URL 611 * @param prefix prefix for the URL 612 * @param path path for the URL 613 * @param ... NULL-terminated key-value pairs (char *) for query parameters, 614 * the value will be url-encoded 615 * @returns the URL, must be freed with #GNUNET_free 616 */ 617 char * 618 TALER_url_absolute_raw (const char *proto, 619 const char *host, 620 const char *prefix, 621 const char *path, 622 ...); 623 624 625 /** 626 * Make an absolute URL for the given parameters. 627 * 628 * If a 'value' is given as NULL, both the key and the value are skipped. Note 629 * that a NULL value does not terminate the list, only a NULL key signals the 630 * end of the list of arguments. 631 * 632 * @param proto protocol for the URL (typically https) 633 * @param host hostname for the URL 634 * @param prefix prefix for the URL 635 * @param path path for the URL 636 * @param args NULL-terminated key-value pairs (char *) for query parameters, 637 * the value will be url-encoded 638 * @returns the URL, must be freed with #GNUNET_free 639 */ 640 char * 641 TALER_url_absolute_raw_va (const char *proto, 642 const char *host, 643 const char *prefix, 644 const char *path, 645 va_list args); 646 647 648 /** 649 * Obtain the payment method from a @a payto_uri 650 * 651 * @param payto_uri the URL to parse 652 * @return NULL on error (malformed @a payto_uri) 653 */ 654 char * 655 TALER_payto_get_method (const char *payto_uri); 656 657 658 /** 659 * Normalize payto://-URI to make "strcmp()" sufficient 660 * to check if two payto-URIs refer to the same bank 661 * account. Removes optional arguments (everything after 662 * "?") and applies method-specific normalizations to 663 * the main part of the URI. 664 * 665 * @param input a payto://-URI 666 * @return normalized URI, or NULL if @a input was not well-formed 667 */ 668 struct TALER_NormalizedPayto 669 TALER_payto_normalize (const struct TALER_FullPayto input); 670 671 672 /** 673 * Normalize the given full payto URI and hash it. 674 * 675 * @param in full payto URI 676 * @param[out] out hash of the normalized payto URI 677 */ 678 void 679 TALER_full_payto_normalize_and_hash ( 680 const struct TALER_FullPayto in, 681 struct TALER_NormalizedPaytoHashP *out); 682 683 684 /** 685 * Obtain the account name from a payto URL. 686 * 687 * @param payto an x-taler-bank payto URL 688 * @return only the account name from the @a payto URL, NULL if not an x-taler-bank 689 * payto URL 690 */ 691 char * 692 TALER_xtalerbank_account_from_payto (const struct TALER_FullPayto payto); 693 694 695 /** 696 * Obtain the receiver name from a payto URL. 697 * 698 * @param fpayto a full payto URL 699 * @return only the receiver name from the @a payto URL, NULL if not a full payto URL 700 */ 701 char * 702 TALER_payto_get_receiver_name (const struct TALER_FullPayto fpayto); 703 704 705 /** 706 * Extract the subject value from the URI parameters. 707 * 708 * @param payto_uri the full URL to parse 709 * @return NULL if the subject parameter is not found. 710 * The caller should free the returned value. 711 */ 712 char * 713 TALER_payto_get_subject (const struct TALER_FullPayto payto_uri); 714 715 716 /** 717 * Check that a full payto:// URI is well-formed. 718 * 719 * @param fpayto_uri the full URL to check 720 * @return NULL on success, otherwise an error 721 * message to be freed by the caller! 722 */ 723 char * 724 TALER_payto_validate (const struct TALER_FullPayto fpayto_uri); 725 726 727 /** 728 * Check that a normalized payto:// URI is well-formed. 729 * 730 * @param npayto_uri the normalized URL to check 731 * @return NULL on success, otherwise an error 732 * message to be freed by the caller! 733 */ 734 char * 735 TALER_normalized_payto_validate (const struct TALER_NormalizedPayto npayto_uri); 736 737 738 /** 739 * Create payto://-URI for a given exchange base URL 740 * and a @a reserve_pub. 741 * 742 * @param exchange_url the base URL of the exchange 743 * @param reserve_pub the public key of the reserve 744 * @return payto://-URI for the reserve (without receiver-name!) 745 */ 746 struct TALER_NormalizedPayto 747 TALER_reserve_make_payto (const char *exchange_url, 748 const struct TALER_ReservePublicKeyP *reserve_pub); 749 750 751 /** 752 * Check that an IBAN number is well-formed. 753 * 754 * Validates given IBAN according to the European Banking Standards. See: 755 * http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf 756 * 757 * @param iban the IBAN to check 758 * @return NULL on success, otherwise an error 759 * message to be freed by the caller! 760 */ 761 char * 762 TALER_iban_validate (const char *iban); 763 764 765 /** 766 * Possible choices for long-polling for the deposit status. 767 */ 768 enum TALER_DepositGetLongPollTarget 769 { 770 /** 771 * No long-polling. 772 */ 773 TALER_DGLPT_NONE = 0, 774 775 /** 776 * Wait for KYC required/ACCEPTED state *or* for 777 * OK state. 778 */ 779 TALER_DGLPT_KYC_REQUIRED_OR_OK = 1, 780 781 /** 782 * Wait for the OK-state only. 783 */ 784 TALER_DGLPT_OK = 2, 785 786 /** 787 * Maximum allowed value. 788 */ 789 TALER_DGLPT_MAX = 2 790 }; 791 792 793 /** 794 * Possible choices for long-polling for the KYC status. 795 */ 796 enum TALER_EXCHANGE_KycLongPollTarget 797 { 798 /** 799 * No long polling. 800 */ 801 TALER_EXCHANGE_KLPT_NONE = 0, 802 803 /** 804 * Wait for KYC auth transfer to be complete. 805 */ 806 TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER = 1, 807 808 /** 809 * Wait for AML investigation to be complete. 810 */ 811 TALER_EXCHANGE_KLPT_INVESTIGATION_DONE = 2, 812 813 /** 814 * Wait for KYC status to be OK. 815 */ 816 TALER_EXCHANGE_KLPT_KYC_OK = 3, 817 818 /** 819 * Maximum legal value in this enumeration. 820 */ 821 TALER_EXCHANGE_KLPT_MAX = 3 822 }; 823 824 825 /** 826 * Enumeration of possible events that may trigger 827 * KYC requirements. 828 */ 829 enum TALER_KYCLOGIC_KycTriggerEvent 830 { 831 832 /** 833 * Reserved value for invalid event types. 834 */ 835 TALER_KYCLOGIC_KYC_TRIGGER_NONE = 0, 836 837 /** 838 * Customer withdraws coins. 839 */ 840 TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW = 1, 841 842 /** 843 * Merchant deposits coins. 844 */ 845 TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT = 2, 846 847 /** 848 * Wallet receives P2P payment. 849 */ 850 TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 3, 851 852 /** 853 * Wallet balance exceeds threshold. The timeframe is 854 * irrelevant for this limit. 855 */ 856 TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 4, 857 858 /** 859 * Reserve is being closed by force. 860 */ 861 TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE = 5, 862 863 /** 864 * Deposits have been aggregated, we are wiring a 865 * certain amount into a (merchant) bank account. 866 */ 867 TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6, 868 869 /** 870 * Limit per transaction. The timeframe is 871 * irrelevant for this limit. 872 */ 873 TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION = 7, 874 875 /** 876 * Limit per refund. The timeframe is 877 * irrelevant for this limit. 878 */ 879 TALER_KYCLOGIC_KYC_TRIGGER_REFUND = 8 880 881 }; 882 883 884 /** 885 * Types of KYC checks. 886 */ 887 enum TALER_KYCLOGIC_CheckType 888 { 889 /** 890 * Wait for staff or contact staff out-of-band. 891 */ 892 TALER_KYCLOGIC_CT_INFO, 893 894 /** 895 * SPA should show an inline form. 896 */ 897 TALER_KYCLOGIC_CT_FORM, 898 899 /** 900 * SPA may start external KYC process. 901 */ 902 TALER_KYCLOGIC_CT_LINK 903 }; 904 905 906 /** 907 * Possible values for a binary filter. 908 */ 909 enum TALER_EXCHANGE_YesNoAll 910 { 911 /** 912 * If condition is yes. 913 */ 914 TALER_EXCHANGE_YNA_YES = 1, 915 916 /** 917 * If condition is no. 918 */ 919 TALER_EXCHANGE_YNA_NO = 2, 920 921 /** 922 * Condition disabled. 923 */ 924 TALER_EXCHANGE_YNA_ALL = 3 925 }; 926 927 928 /** 929 * Convert YNA value to a string. 930 * 931 * @param yna value to convert 932 * @return string representation ("yes"/"no"/"all"). 933 */ 934 const char * 935 TALER_yna_to_string (enum TALER_EXCHANGE_YesNoAll yna); 936 937 938 /** 939 * Escape @a str for encoding in XML. 940 * 941 * @param str string to escape 942 * @return XML-encoded @a str (caller must GNUNET_free()) 943 */ 944 char * 945 TALER_escape_xml (const char *str); 946 947 948 /** 949 * Check if @a src matches ``[a-zA-Z0-9-.:]{1, 40}`` 950 * 951 * @param src string to check 952 * @return true if it is an allowed metadata string. 953 */ 954 bool 955 TALER_is_valid_subject_metadata_string (const char *src); 956 957 958 #ifdef __APPLE__ 959 /** 960 * Returns the first occurrence of `c` in `s`, or returns the null-byte 961 * terminating the string if it does not occur. 962 * 963 * @param s the string to search in 964 * @param c the character to search for 965 * @return char* the first occurrence of `c` in `s` 966 */ 967 char *strchrnul (const char *s, int c); 968 969 #endif 970 971 /** 972 * @brief Parses a date information into days after 1970-01-01 (or 0) 973 * 974 * The input MUST be of the form 975 * 976 * 1) YYYY-MM-DD, representing a valid date 977 * 2) YYYY-MM-00, representing a valid month in a particular year 978 * 3) YYYY-00-00, representing a valid year. 979 * 980 * In the cases 2) and 3) the out parameter is set to the beginning of the 981 * time, f.e. 1950-00-00 == 1950-01-01 and 1888-03-00 == 1888-03-01 982 * 983 * The output will set to the number of days after 1970-01-01 or 0, if the input 984 * represents a date belonging to the largest allowed age group. 985 * 986 * @param in Input string representation of the date 987 * @param mask Age mask 988 * @param[out] out Where to write the result 989 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 990 */ 991 enum GNUNET_GenericReturnValue 992 TALER_parse_coarse_date ( 993 const char *in, 994 const struct TALER_AgeMask *mask, 995 uint32_t *out); 996 997 998 /** 999 * @brief Parses a string as a list of age groups. 1000 * 1001 * The string must consist of a colon-separated list of increasing integers 1002 * between 0 and 31. Each entry represents the beginning of a new age group. 1003 * F.e. the string 1004 * 1005 * "8:10:12:14:16:18:21" 1006 * 1007 * represents the following list of eight age groups: 1008 * 1009 * | Group | Ages | 1010 * | -----:|:------------- | 1011 * | 0 | 0, 1, ..., 7 | 1012 * | 1 | 8, 9 | 1013 * | 2 | 10, 11 | 1014 * | 3 | 12, 13 | 1015 * | 4 | 14, 15 | 1016 * | 5 | 16, 17 | 1017 * | 6 | 18, 19, 20 | 1018 * | 7 | 21, ... | 1019 * 1020 * which is then encoded as a bit mask with the corresponding bits set: 1021 * 1022 * 31 24 16 8 0 1023 * | | | | | 1024 * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1 1025 * 1026 * @param groups String representation of age groups 1027 * @param[out] mask Mask representation for age restriction. 1028 * @return Error, if age groups were invalid, OK otherwise. 1029 */ 1030 enum GNUNET_GenericReturnValue 1031 TALER_parse_age_group_string ( 1032 const char *groups, 1033 struct TALER_AgeMask *mask); 1034 1035 1036 /** 1037 * @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21" 1038 * 1039 * NOTE: This function uses a static buffer. It is not safe to call this 1040 * function concurrently. 1041 * 1042 * @param mask Age mask 1043 * @return String representation of the age mask. 1044 * Can be used as value in the TALER config. 1045 */ 1046 const char * 1047 TALER_age_mask_to_string ( 1048 const struct TALER_AgeMask *mask); 1049 1050 1051 /** 1052 * @brief returns the age group of a given age for a given age mask 1053 * 1054 * @param mask Age mask 1055 * @param age The given age 1056 * @return age group 1057 */ 1058 uint8_t 1059 TALER_get_age_group ( 1060 const struct TALER_AgeMask *mask, 1061 uint8_t age); 1062 1063 1064 /** 1065 * @brief Return the lowest age in the corresponding group for a given age 1066 * according the given age mask. 1067 * 1068 * @param mask age mask 1069 * @param age age to check 1070 * @return lowest age in corresponding age group 1071 */ 1072 uint8_t 1073 TALER_get_lowest_age ( 1074 const struct TALER_AgeMask *mask, 1075 uint8_t age); 1076 1077 1078 /** 1079 * @brief Get the lowest age for the largest age group 1080 * 1081 * @param mask the age mask 1082 * @return lowest age for the largest age group 1083 */ 1084 #define TALER_adult_age(mask) \ 1085 sizeof((mask)->bits) * 8 - __builtin_clz ((mask)->bits) - 1 1086 1087 1088 /** 1089 * Command-line options for various TALER_SECMOD_XXX_run() functions. 1090 */ 1091 struct TALER_SECMOD_Options 1092 { 1093 1094 /** 1095 * Number of workers to launch. Note that connections to 1096 * exchanges are NOT workers. 1097 */ 1098 unsigned int max_workers; 1099 1100 /** 1101 * Time when the key update is executed. 1102 * Either the actual current time, or a pretended time. 1103 */ 1104 struct GNUNET_TIME_Timestamp global_now; 1105 1106 /** 1107 * The time for the key update, as passed by the user 1108 * on the command line. 1109 */ 1110 struct GNUNET_TIME_Timestamp global_now_tmp; 1111 1112 /** 1113 * Configuration section name to use. 1114 */ 1115 const char *section; 1116 1117 /** 1118 * Configuration section prefix to use for denomination settings. 1119 * "coin_" for the exchange, "doco_" for Donau. 1120 */ 1121 const char *cprefix; 1122 1123 /** 1124 * Return value from main(). 1125 */ 1126 int global_ret; 1127 1128 1129 }; 1130 1131 #define TALER_SECMOD_OPTIONS(opt) \ 1132 GNUNET_GETOPT_option_timetravel ('T', \ 1133 "timetravel"), \ 1134 GNUNET_GETOPT_option_timestamp ('t', \ 1135 "time", \ 1136 "TIMESTAMP", \ 1137 "pretend it is a different time for the update", \ 1138 &(opt)->global_now_tmp), \ 1139 GNUNET_GETOPT_option_uint ('w', \ 1140 "workers", \ 1141 "COUNT", \ 1142 "use COUNT workers for parallel processing of batch requests", \ 1143 &(opt)->max_workers) 1144 1145 1146 /** 1147 * Main function of an EDDSA secmod that will be run under the GNUnet scheduler. 1148 * 1149 * @param cls must point to a `struct TALER_SECMOD_Options *` 1150 * @param args remaining command-line arguments 1151 * @param cfgfile name of the configuration file used (for saving, can be NULL!) 1152 * @param cfg configuration 1153 */ 1154 void 1155 TALER_SECMOD_eddsa_run (void *cls, 1156 char *const *args, 1157 const char *cfgfile, 1158 const struct GNUNET_CONFIGURATION_Handle *cfg); 1159 1160 1161 /** 1162 * Main function of a CS secmod that will be run under the GNUnet scheduler. 1163 * 1164 * @param cls must point to a `struct TALER_SECMOD_Options *` 1165 * @param args remaining command-line arguments 1166 * @param cfgfile name of the configuration file used (for saving, can be NULL!) 1167 * @param cfg configuration 1168 */ 1169 void 1170 TALER_SECMOD_cs_run (void *cls, 1171 char *const *args, 1172 const char *cfgfile, 1173 const struct GNUNET_CONFIGURATION_Handle *cfg); 1174 1175 1176 /** 1177 * Main function of an RSA secmod that will be run under the GNUnet scheduler. 1178 * 1179 * @param cls must point to a `struct TALER_SECMOD_Options *` 1180 * @param args remaining command-line arguments 1181 * @param cfgfile name of the configuration file used (for saving, can be NULL!) 1182 * @param cfg configuration 1183 */ 1184 void 1185 TALER_SECMOD_rsa_run (void *cls, 1186 char *const *args, 1187 const char *cfgfile, 1188 const struct GNUNET_CONFIGURATION_Handle *cfg); 1189 1190 1191 /** 1192 * Perform very primitive word splitting of a command. 1193 * Primarily used to split helper commands from the configurations. 1194 * 1195 * @param command command to split 1196 * @param extra_args extra arguments to append after the word 1197 * @returns NULL-terminated array of words, free wiith TALER_words_destroy 1198 */ 1199 char ** 1200 TALER_words_split (const char *command, 1201 const char **extra_args); 1202 1203 1204 /** 1205 * Free arguments allocated with split_words. 1206 * 1207 * @param args NULL-terminated array of strings to free. 1208 */ 1209 void 1210 TALER_words_destroy (char **args); 1211 1212 #undef __TALER_UTIL_LIB_H_INSIDE__ 1213 1214 #endif