summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/taler_crypto_lib.h7
-rw-r--r--src/util/Makefile.am4
-rw-r--r--src/util/amount.c5
-rw-r--r--src/util/config.c57
-rw-r--r--src/util/crypto.c6
-rw-r--r--src/util/crypto_wire.c19
-rw-r--r--src/util/getopt.c87
-rw-r--r--src/util/os_installation.c3
-rw-r--r--src/util/payto.c85
-rw-r--r--src/util/url.c409
-rw-r--r--src/util/util.c548
11 files changed, 662 insertions, 568 deletions
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 3fd72723..206a3db3 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -739,7 +739,7 @@ TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc,
/**
* Compute the hash of the given wire details. The resulting
- * hash is what is put into the contract.
+ * hash is what is signed by the master key.
*
* @param payto_uri bank account
* @param[out] hc set to the hash
@@ -750,7 +750,7 @@ TALER_exchange_wire_signature_hash (const char *payto_uri,
/**
- * Check the signature in @a wire_s.
+ * Check the signature in @a master_sig.
*
* @param payto_uri URL that is signed
* @param master_pub master public key of the exchange
@@ -781,7 +781,8 @@ TALER_exchange_wire_signature_make (const char *payto_uri,
/**
* Compute the hash of the given wire details. The resulting
- * hash is what is put into the contract.
+ * @a hc is what will be put into the contract between customer
+ * and merchant for signing by both parties.
*
* @param payto_uri bank account
* @param salt salt used to eliminate brute-force inversion
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 74e61ccd..95cc233a 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -24,8 +24,12 @@ lib_LTLIBRARIES = \
libtalerutil_la_SOURCES = \
amount.c \
+ config.c \
crypto.c \
crypto_wire.c \
+ getopt.c \
+ payto.c \
+ url.c \
util.c \
os_installation.c
diff --git a/src/util/amount.c b/src/util/amount.c
index a9b41ba7..d5789c1d 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -22,12 +22,7 @@
* @author Christian Grothoff
*/
#include "platform.h"
-#if HAVE_GNUNET_GNUNET_UTIL_LIB_H
#include "taler_util.h"
-#elif HAVE_GNUNET_GNUNET_UTIL_TALER_WALLET_LIB_H
-#include "taler_util_wallet.h"
-#endif
-#include <gcrypt.h>
/**
* Maximum legal 'value' for an amount, based on IEEE double (for JavaScript compatibility).
diff --git a/src/util/config.c b/src/util/config.c
new file mode 100644
index 00000000..e65a144a
--- /dev/null
+++ b/src/util/config.c
@@ -0,0 +1,57 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file config.c
+ * @brief configuration parsing functions for Taler-specific data types
+ * @author Florian Dold
+ * @author Benedikt Mueller
+ */
+#include "platform.h"
+#include "taler_util.h"
+
+
+/**
+ * Obtain denomination amount from configuration file.
+ *
+ * @param cfg configuration to use
+ * @param section section of the configuration to access
+ * @param option option of the configuration to access
+ * @param[out] denom set to the amount found in configuration
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+TALER_config_get_denom (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ const char *option,
+ struct TALER_Amount *denom)
+{
+ char *str;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ section,
+ option,
+ &str))
+ return GNUNET_NO;
+ if (GNUNET_OK != TALER_string_to_amount (str,
+ denom))
+ {
+ GNUNET_free (str);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_free (str);
+ return GNUNET_OK;
+}
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 9fe08984..e847633f 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -22,13 +22,7 @@
* @author Christian Grothoff
*/
#include "platform.h"
-
-#if HAVE_GNUNET_GNUNET_UTIL_TALER_WALLET_LIB_H
-#include "taler_util_wallet.h"
-#endif
-#if HAVE_GNUNET_GNUNET_UTIL_LIB_H
#include "taler_util.h"
-#endif
#include <gcrypt.h>
diff --git a/src/util/crypto_wire.c b/src/util/crypto_wire.c
index a8941e18..d935bec4 100644
--- a/src/util/crypto_wire.c
+++ b/src/util/crypto_wire.c
@@ -24,8 +24,8 @@
/**
- * Compute the hash of the given wire details. The resulting
- * hash is what is put into the contract.
+ * Compute the hash of the given wire details. The resulting
+ * hash is what is signed by the master key.
*
* @param payto_uri bank account
* @param[out] hc set to the hash
@@ -46,7 +46,7 @@ TALER_exchange_wire_signature_hash (const char *payto_uri,
/**
- * Check the signature in @a wire_s.
+ * Check the signature in @a master_sig.
*
* @param payto_uri URL that is signed
* @param master_pub master public key of the exchange
@@ -101,7 +101,8 @@ TALER_exchange_wire_signature_make (const char *payto_uri,
/**
* Compute the hash of the given wire details. The resulting
- * hash is what is put into the contract.
+ * @a hc is what will be put into the contract between customer
+ * and merchant for signing by both parties.
*
* @param payto_uri bank account
* @param salt salt used to eliminate brute-force inversion
@@ -126,7 +127,15 @@ TALER_merchant_wire_signature_hash (const char *payto_uri,
/**
- * Check the signature in @a merch_sig. (Not yet used anywhere.)
+ * Check the signature in @a merch_sig.
+ * (Not yet used anywhere.)
+ *
+ * Expected to be used if/when we get @a merch_pub signed via
+ * X.509 *and* have a way for the WebEx wallet to check that the
+ * @a merch_pub provided matches that of the X.509 certificate
+ * from the Web site. Until then, @a merch_pub cannto be
+ * validated (no PKI), and hence there is no point in checking
+ * these signatures. (See #5129 and #3946).
*
* @param payto_uri URL that is signed
* @param salt the salt used to salt the @a payto_uri when hashing
diff --git a/src/util/getopt.c b/src/util/getopt.c
new file mode 100644
index 00000000..b8948bbb
--- /dev/null
+++ b/src/util/getopt.c
@@ -0,0 +1,87 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file getopt.c
+ * @brief Helper functions for parsing Taler-specific command-line arguments
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "taler_util.h"
+
+
+/**
+ * Set an option with an amount from the command line. A pointer to
+ * this function should be passed as part of the 'struct
+ * GNUNET_GETOPT_CommandLineOption' array to initialize options of
+ * this type.
+ *
+ * @param ctx command line processing context
+ * @param scls additional closure (will point to the `struct TALER_Amount`)
+ * @param option name of the option
+ * @param value actual value of the option as a string.
+ * @return #GNUNET_OK if parsing the value worked
+ */
+static int
+set_amount (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
+ void *scls,
+ const char *option,
+ const char *value)
+{
+ struct TALER_Amount *amount = scls;
+
+ (void) ctx;
+ if (GNUNET_OK !=
+ TALER_string_to_amount (value,
+ amount))
+ {
+ fprintf (stderr,
+ _ ("Failed to parse amount in option `%s'\n"),
+ option);
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
+}
+
+
+/**
+ * Allow user to specify an amount on the command line.
+ *
+ * @param shortName short name of the option
+ * @param name long name of the option
+ * @param argumentHelp help text for the option argument
+ * @param description long help text for the option
+ * @param[out] amount set to the amount specified at the command line
+ */
+struct GNUNET_GETOPT_CommandLineOption
+TALER_getopt_get_amount (char shortName,
+ const char *name,
+ const char *argumentHelp,
+ const char *description,
+ struct TALER_Amount *amount)
+{
+ struct GNUNET_GETOPT_CommandLineOption clo = {
+ .shortName = shortName,
+ .name = name,
+ .argumentHelp = argumentHelp,
+ .description = description,
+ .require_argument = 1,
+ .processor = &set_amount,
+ .scls = (void *) amount
+ };
+
+ return clo;
+}
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
index 1fe5ea07..beea5d70 100644
--- a/src/util/os_installation.c
+++ b/src/util/os_installation.c
@@ -1,6 +1,6 @@
/*
This file is part of GNU Taler.
- Copyright (C) 2016 Inria
+ Copyright (C) 2016 Taler Systems SA
Taler is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -17,7 +17,6 @@
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
-
/**
* @file os_installation.c
* @brief initialize libgnunet OS subsystem for Taler.
diff --git a/src/util/payto.c b/src/util/payto.c
new file mode 100644
index 00000000..484db0bb
--- /dev/null
+++ b/src/util/payto.c
@@ -0,0 +1,85 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2019-2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file payto.c
+ * @brief Common utility functions for dealing with payto://-URIs
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "taler_util.h"
+
+
+/**
+ * Prefix of PAYTO URLs.
+ */
+#define PAYTO "payto://"
+
+
+/**
+ * Obtain the payment method from a @a payto_uri
+ *
+ * @param payto_uri the URL to parse
+ * @return NULL on error (malformed @a payto_uri)
+ */
+char *
+TALER_payto_get_method (const char *payto_uri)
+{
+ const char *start;
+ const char *end;
+
+ if (0 != strncmp (payto_uri,
+ PAYTO,
+ strlen (PAYTO)))
+ return NULL;
+ start = &payto_uri[strlen (PAYTO)];
+ end = strchr (start,
+ (unsigned char) '/');
+ if (NULL == end)
+ return NULL;
+ return GNUNET_strndup (start,
+ end - start);
+}
+
+
+/**
+ * Obtain the account name from a payto URL.
+ *
+ * @param payto an x-taler-bank payto URL
+ * @return only the account name from the @a payto URL, NULL if not an x-taler-bank
+ * payto URL
+ */
+char *
+TALER_xtalerbank_account_from_payto (const char *payto)
+{
+ const char *beg;
+ const char *end;
+
+ if (0 != strncasecmp (payto,
+ "payto://x-taler-bank/",
+ strlen ("payto://x-taler-bank/")))
+ return NULL;
+ beg = strchr (&payto[strlen ("payto://x-taler-bank/")],
+ '/');
+ if (NULL == beg)
+ return NULL;
+ beg++;
+ end = strchr (beg,
+ '?');
+ if (NULL == end)
+ return GNUNET_strdup (beg);
+ return GNUNET_strndup (beg,
+ end - beg);
+}
diff --git a/src/util/url.c b/src/util/url.c
new file mode 100644
index 00000000..be15917b
--- /dev/null
+++ b/src/util/url.c
@@ -0,0 +1,409 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file url.c
+ * @brief URL handling utility functions
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "taler_util.h"
+
+
+/**
+ * Check if a character is reserved and should
+ * be urlencoded.
+ *
+ * @param c character to look at
+ * @return #GNUNET_YES if @a c needs to be urlencoded,
+ * #GNUNET_NO otherwise
+ */
+static bool
+is_reserved (char c)
+{
+ switch (c)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ case '-': case '.': case '_': case '~':
+ return GNUNET_NO;
+ default:
+ break;
+ }
+ return GNUNET_YES;
+}
+
+
+/**
+ * Get the length of a string after it has been
+ * urlencoded.
+ *
+ * @param s the string
+ * @returns the size of the urlencoded @a s
+ */
+static size_t
+urlencode_len (const char *s)
+{
+ size_t len = 0;
+ for (; *s != '\0'; len++, s++)
+ if (GNUNET_YES == is_reserved (*s))
+ len += 2;
+ return len;
+}
+
+
+/**
+ * URL-encode a string according to rfc3986.
+ *
+ * @param buf buffer to write the result to
+ * @param s string to encode
+ */
+static void
+buffer_write_urlencode (struct GNUNET_Buffer *buf,
+ const char *s)
+{
+ GNUNET_buffer_ensure_remaining (buf, urlencode_len (s) + 1);
+
+ for (size_t i = 0; i < strlen (s); i++)
+ {
+ if (GNUNET_YES == is_reserved (s[i]))
+ GNUNET_buffer_write_fstr (buf, "%%%02X", s[i]);
+ else
+ buf->mem[buf->position++] = s[i];
+ }
+}
+
+
+/**
+ * URL-encode a string according to rfc3986.
+ *
+ * @param s string to encode
+ * @returns the urlencoded string, the caller must free it with #GNUNET_free()
+ */
+char *
+TALER_urlencode (const char *s)
+{
+ struct GNUNET_Buffer buf = { 0 };
+
+ buffer_write_urlencode (&buf, s);
+ return GNUNET_buffer_reap_str (&buf);
+}
+
+
+/**
+ * Make an absolute URL with query parameters.
+ *
+ * @param base_url absolute base URL to use
+ * @param path path of the url
+ * @param ... NULL-terminated key-value pairs (char *) for query parameters,
+ * the value will be url-encoded
+ * @returns the URL (must be freed with #GNUNET_free) or
+ * NULL if an error occured.
+ */
+char *
+TALER_url_join (const char *base_url,
+ const char *path,
+ ...)
+{
+ unsigned int iparam = 0;
+ va_list args;
+ struct GNUNET_Buffer buf = { 0 };
+ size_t len;
+
+ GNUNET_assert (NULL != base_url);
+ GNUNET_assert (NULL != path);
+ if (0 == strlen (base_url))
+ {
+ /* base URL can't be empty */
+ GNUNET_break (0);
+ return NULL;
+ }
+ if ('/' != base_url[strlen (base_url) - 1])
+ {
+ /* Must be an actual base URL! */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Base URL `%s' does not end with '/'\n",
+ base_url);
+ return NULL;
+ }
+ if ('/' == path[0])
+ {
+ /* The path must be relative. */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Path `%s' is not relative\n",
+ path);
+ return NULL;
+ }
+
+ /* 1st pass: compute length */
+ len = strlen (base_url) + strlen (path) + 1;
+
+ va_start (args, path);
+ while (1)
+ {
+ char *key;
+ char *value;
+ key = va_arg (args, char *);
+ if (NULL == key)
+ break;
+ value = va_arg (args, char *);
+ if (NULL == value)
+ continue;
+ len += urlencode_len (value) + strlen (key) + 2;
+ }
+ va_end (args);
+
+ GNUNET_buffer_prealloc (&buf, len);
+ GNUNET_buffer_write_str (&buf, base_url);
+ GNUNET_buffer_write_str (&buf, path);
+
+ va_start (args, path);
+ while (1)
+ {
+ char *key;
+ char *value;
+
+ key = va_arg (args, char *);
+ if (NULL == key)
+ break;
+ value = va_arg (args, char *);
+ if (NULL == value)
+ continue;
+ GNUNET_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
+ iparam++;
+ GNUNET_buffer_write_str (&buf, key);
+ GNUNET_buffer_write_str (&buf, "=");
+ buffer_write_urlencode (&buf, value);
+ }
+ va_end (args);
+
+ return GNUNET_buffer_reap_str (&buf);
+}
+
+
+/**
+ * Make an absolute URL for the given parameters.
+ *
+ * @param proto protocol for the URL (typically https)
+ * @param host hostname for the URL
+ * @param prefix prefix for the URL
+ * @param path path for the URL
+ * @param args NULL-terminated key-value pairs (char *) for query parameters,
+ * the value will be url-encoded
+ * @returns the URL, must be freed with #GNUNET_free
+ */
+char *
+TALER_url_absolute_raw_va (const char *proto,
+ const char *host,
+ const char *prefix,
+ const char *path,
+ va_list args)
+{
+ struct GNUNET_Buffer buf = { 0 };
+ unsigned int iparam = 0;
+ size_t len = 0;
+ va_list args2;
+
+ len += strlen (proto) + strlen ("://") + strlen (host);
+ len += strlen (prefix) + strlen (path);
+
+ va_copy (args2, args);
+ while (1)
+ {
+ char *key;
+ char *value;
+ key = va_arg (args2, char *);
+ if (NULL == key)
+ break;
+ value = va_arg (args2, char *);
+ if (NULL == value)
+ continue;
+ len += urlencode_len (value) + strlen (key) + 2;
+ }
+ va_end (args2);
+
+ GNUNET_buffer_prealloc (&buf, len);
+
+ GNUNET_buffer_write_str (&buf, proto);
+ GNUNET_buffer_write_str (&buf, "://");
+ GNUNET_buffer_write_str (&buf, host);
+
+ GNUNET_buffer_write_path (&buf, prefix);
+ GNUNET_buffer_write_path (&buf, path);
+
+ va_copy (args2, args);
+ while (1)
+ {
+ char *key;
+ char *value;
+ key = va_arg (args, char *);
+ if (NULL == key)
+ break;
+ value = va_arg (args, char *);
+ if (NULL == value)
+ continue;
+ GNUNET_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
+ iparam++;
+ GNUNET_buffer_write_str (&buf, key);
+ GNUNET_buffer_write_str (&buf, "=");
+ buffer_write_urlencode (&buf, value);
+ }
+ va_end (args2);
+
+ return GNUNET_buffer_reap_str (&buf);
+}
+
+
+/**
+ * Make an absolute URL for the given parameters.
+ *
+ * @param proto protocol for the URL (typically https)
+ * @param host hostname for the URL
+ * @param prefix prefix for the URL
+ * @param path path for the URL
+ * @param ... NULL-terminated key-value pairs (char *) for query parameters,
+ * the value will be url-encoded
+ * @returns the URL, must be freed with #GNUNET_free
+ */
+char *
+TALER_url_absolute_raw (const char *proto,
+ const char *host,
+ const char *prefix,
+ const char *path,
+ ...)
+{
+ char *result;
+ va_list args;
+
+ va_start (args, path);
+ result = TALER_url_absolute_raw_va (proto, host, prefix, path, args);
+ va_end (args);
+ return result;
+}
+
+
+/**
+ * Find out if an MHD connection is using HTTPS (either
+ * directly or via proxy).
+ *
+ * @param connection MHD connection
+ * @returns GNUNET_YES if the MHD connection is using https,
+ * GNUNET_NO if the MHD connection is using http,
+ * GNUNET_SYSERR if the connection type couldn't be determined
+ */
+int
+TALER_mhd_is_https (struct MHD_Connection *connection)
+{
+ const union MHD_ConnectionInfo *ci;
+ const union MHD_DaemonInfo *di;
+ const char *forwarded_proto = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ "X-Forwarded-Proto");
+
+ if (NULL != forwarded_proto)
+ {
+ if (0 == strcmp (forwarded_proto, "https"))
+ return GNUNET_YES;
+ if (0 == strcmp (forwarded_proto, "http"))
+ return GNUNET_NO;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ /* likely not reverse proxy, figure out if we are
+ http by asking MHD */
+ ci = MHD_get_connection_info (connection,
+ MHD_CONNECTION_INFO_DAEMON);
+ if (NULL == ci)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ di = MHD_get_daemon_info (ci->daemon,
+ MHD_DAEMON_INFO_FLAGS);
+ if (NULL == di)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (0 != (di->flags & MHD_USE_TLS))
+ return GNUNET_YES;
+ return GNUNET_NO;
+}
+
+
+/**
+ * Make an absolute URL for a given MHD connection.
+ *
+ * @param connection the connection to get the URL for
+ * @param path path of the url
+ * @param ... NULL-terminated key-value pairs (char *) for query parameters,
+ * the value will be url-encoded
+ * @returns the URL, must be freed with #GNUNET_free
+ */
+char *
+TALER_url_absolute_mhd (struct MHD_Connection *connection,
+ const char *path,
+ ...)
+{
+ /* By default we assume we're running under HTTPS */
+ const char *proto;
+ const char *host;
+ const char *forwarded_host;
+ const char *prefix;
+ va_list args;
+ char *result;
+
+ if (GNUNET_YES == TALER_mhd_is_https (connection))
+ proto = "https";
+ else
+ proto = "http";
+
+ host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Host");
+ forwarded_host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+ "X-Forwarded-Host");
+
+ prefix = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+ "X-Forwarded-Prefix");
+ if (NULL == prefix)
+ prefix = "";
+
+ if (NULL != forwarded_host)
+ host = forwarded_host;
+
+ if (NULL == host)
+ {
+ /* Should never happen, at last the host header should be defined */
+ GNUNET_break (0);
+ return NULL;
+ }
+
+ va_start (args, path);
+ result = TALER_url_absolute_raw_va (proto, host, prefix, path, args);
+ va_end (args);
+ return result;
+}
+
+
+/* end of url.c */
diff --git a/src/util/util.c b/src/util/util.c
index c9fd5a81..f49bc7c2 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -15,16 +15,13 @@
*/
/**
* @file util.c
- * @brief Common utility functions; we might choose to move those to GNUnet at some point
+ * @brief Common utility functions
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Florian Dold
* @author Benedikt Mueller
*/
-
#include "platform.h"
-#include "gnunet/gnunet_buffer_lib.h"
#include "taler_util.h"
-#include <gcrypt.h>
/**
@@ -59,547 +56,4 @@ TALER_b2s (const void *buf,
}
-/**
- * Obtain denomination amount from configuration file.
- *
- * @param cfg configuration to use
- * @param section section of the configuration to access
- * @param option option of the configuration to access
- * @param[out] denom set to the amount found in configuration
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-int
-TALER_config_get_denom (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *section,
- const char *option,
- struct TALER_Amount *denom)
-{
- char *str;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- section,
- option,
- &str))
- return GNUNET_NO;
- if (GNUNET_OK != TALER_string_to_amount (str,
- denom))
- {
- GNUNET_free (str);
- return GNUNET_SYSERR;
- }
- GNUNET_free (str);
- return GNUNET_OK;
-}
-
-
-/**
- * Set an option with an amount from the command line. A pointer to
- * this function should be passed as part of the 'struct
- * GNUNET_GETOPT_CommandLineOption' array to initialize options of
- * this type.
- *
- * @param ctx command line processing context
- * @param scls additional closure (will point to the `struct TALER_Amount`)
- * @param option name of the option
- * @param value actual value of the option as a string.
- * @return #GNUNET_OK if parsing the value worked
- */
-static int
-set_amount (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
- void *scls,
- const char *option,
- const char *value)
-{
- struct TALER_Amount *amount = scls;
-
- (void) ctx;
- if (GNUNET_OK !=
- TALER_string_to_amount (value,
- amount))
- {
- fprintf (stderr,
- _ ("Failed to parse amount in option `%s'\n"),
- option);
- return GNUNET_SYSERR;
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Allow user to specify an amount on the command line.
- *
- * @param shortName short name of the option
- * @param name long name of the option
- * @param argumentHelp help text for the option argument
- * @param description long help text for the option
- * @param[out] amount set to the amount specified at the command line
- */
-struct GNUNET_GETOPT_CommandLineOption
-TALER_getopt_get_amount (char shortName,
- const char *name,
- const char *argumentHelp,
- const char *description,
- struct TALER_Amount *amount)
-{
- struct GNUNET_GETOPT_CommandLineOption clo = {
- .shortName = shortName,
- .name = name,
- .argumentHelp = argumentHelp,
- .description = description,
- .require_argument = 1,
- .processor = &set_amount,
- .scls = (void *) amount
- };
-
- return clo;
-}
-
-
-/**
- * Check if a character is reserved and should
- * be urlencoded.
- *
- * @param c character to look at
- * @return #GNUNET_YES if @a c needs to be urlencoded,
- * #GNUNET_NO otherwise
- */
-static bool
-is_reserved (char c)
-{
- switch (c)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f': case 'g': case 'h': case 'i': case 'j':
- case 'k': case 'l': case 'm': case 'n': case 'o':
- case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F': case 'G': case 'H': case 'I': case 'J':
- case 'K': case 'L': case 'M': case 'N': case 'O':
- case 'P': case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
- case '-': case '.': case '_': case '~':
- return GNUNET_NO;
- default:
- break;
- }
- return GNUNET_YES;
-}
-
-
-/**
- * Get the length of a string after it has been
- * urlencoded.
- *
- * @param s the string
- * @returns the size of the urlencoded @a s
- */
-static size_t
-urlencode_len (const char *s)
-{
- size_t len = 0;
- for (; *s != '\0'; len++, s++)
- if (GNUNET_YES == is_reserved (*s))
- len += 2;
- return len;
-}
-
-
-/**
- * URL-encode a string according to rfc3986.
- *
- * @param buf buffer to write the result to
- * @param s string to encode
- */
-static void
-buffer_write_urlencode (struct GNUNET_Buffer *buf, const char *s)
-{
- GNUNET_buffer_ensure_remaining (buf, urlencode_len (s) + 1);
-
- for (size_t i = 0; i < strlen (s); i++)
- {
- if (GNUNET_YES == is_reserved (s[i]))
- GNUNET_buffer_write_fstr (buf, "%%%02X", s[i]);
- else
- buf->mem[buf->position++] = s[i];
- }
-}
-
-
-/**
- * URL-encode a string according to rfc3986.
- *
- * @param s string to encode
- * @returns the urlencoded string, the caller must free it with GNUNET_free
- */
-char *
-TALER_urlencode (const char *s)
-{
- struct GNUNET_Buffer buf = { 0 };
-
- buffer_write_urlencode (&buf, s);
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-/**
- * Make an absolute URL with query parameters.
- *
- * @param base_url absolute base URL to use
- * @param path path of the url
- * @param ... NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL (must be freed with #GNUNET_free) or
- * NULL if an error occured.
- */
-char *
-TALER_url_join (const char *base_url,
- const char *path,
- ...)
-{
- unsigned int iparam = 0;
- va_list args;
- struct GNUNET_Buffer buf = { 0 };
- size_t len;
-
- GNUNET_assert (NULL != base_url);
- GNUNET_assert (NULL != path);
- if (0 == strlen (base_url))
- {
- /* base URL can't be empty */
- GNUNET_break (0);
- return NULL;
- }
- if ('/' != base_url[strlen (base_url) - 1])
- {
- /* Must be an actual base URL! */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Base URL `%s' does not end with '/'\n",
- base_url);
- return NULL;
- }
- if ('/' == path[0])
- {
- /* The path must be relative. */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Path `%s' is not relative\n",
- path);
- return NULL;
- }
-
- /* 1st pass: compute length */
- len = strlen (base_url) + strlen (path) + 1;
-
- va_start (args, path);
- while (1)
- {
- char *key;
- char *value;
- key = va_arg (args, char *);
- if (NULL == key)
- break;
- value = va_arg (args, char *);
- if (NULL == value)
- continue;
- len += urlencode_len (value) + strlen (key) + 2;
- }
- va_end (args);
-
- GNUNET_buffer_prealloc (&buf, len);
- GNUNET_buffer_write_str (&buf, base_url);
- GNUNET_buffer_write_str (&buf, path);
-
- va_start (args, path);
- while (1)
- {
- char *key;
- char *value;
-
- key = va_arg (args, char *);
- if (NULL == key)
- break;
- value = va_arg (args, char *);
- if (NULL == value)
- continue;
- GNUNET_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
- iparam++;
- GNUNET_buffer_write_str (&buf, key);
- GNUNET_buffer_write_str (&buf, "=");
- buffer_write_urlencode (&buf, value);
- }
- va_end (args);
-
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-/**
- * Make an absolute URL for the given parameters.
- *
- * @param proto protocol for the URL (typically https)
- * @param host hostname for the URL
- * @param prefix prefix for the URL
- * @param path path for the URL
- * @param args NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL, must be freed with #GNUNET_free
- */
-char *
-TALER_url_absolute_raw_va (const char *proto,
- const char *host,
- const char *prefix,
- const char *path,
- va_list args)
-{
- struct GNUNET_Buffer buf = { 0 };
- unsigned int iparam = 0;
- size_t len = 0;
- va_list args2;
-
- len += strlen (proto) + strlen ("://") + strlen (host);
- len += strlen (prefix) + strlen (path);
-
- va_copy (args2, args);
- while (1)
- {
- char *key;
- char *value;
- key = va_arg (args2, char *);
- if (NULL == key)
- break;
- value = va_arg (args2, char *);
- if (NULL == value)
- continue;
- len += urlencode_len (value) + strlen (key) + 2;
- }
- va_end (args2);
-
- GNUNET_buffer_prealloc (&buf, len);
-
- GNUNET_buffer_write_str (&buf, proto);
- GNUNET_buffer_write_str (&buf, "://");
- GNUNET_buffer_write_str (&buf, host);
-
- GNUNET_buffer_write_path (&buf, prefix);
- GNUNET_buffer_write_path (&buf, path);
-
- va_copy (args2, args);
- while (1)
- {
- char *key;
- char *value;
- key = va_arg (args, char *);
- if (NULL == key)
- break;
- value = va_arg (args, char *);
- if (NULL == value)
- continue;
- GNUNET_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
- iparam++;
- GNUNET_buffer_write_str (&buf, key);
- GNUNET_buffer_write_str (&buf, "=");
- buffer_write_urlencode (&buf, value);
- }
- va_end (args2);
-
- return GNUNET_buffer_reap_str (&buf);
-}
-
-
-/**
- * Make an absolute URL for the given parameters.
- *
- * @param proto protocol for the URL (typically https)
- * @param host hostname for the URL
- * @param prefix prefix for the URL
- * @param path path for the URL
- * @param ... NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL, must be freed with #GNUNET_free
- */
-char *
-TALER_url_absolute_raw (const char *proto,
- const char *host,
- const char *prefix,
- const char *path,
- ...)
-{
- char *result;
- va_list args;
-
- va_start (args, path);
- result = TALER_url_absolute_raw_va (proto, host, prefix, path, args);
- va_end (args);
- return result;
-}
-
-
-/**
- * Find out if an MHD connection is using HTTPS (either
- * directly or via proxy).
- *
- * @param connection MHD connection
- * @returns GNUNET_YES if the MHD connection is using https,
- * GNUNET_NO if the MHD connection is using http,
- * GNUNET_SYSERR if the connection type couldn't be determined
- */
-int
-TALER_mhd_is_https (struct MHD_Connection *connection)
-{
- const union MHD_ConnectionInfo *ci;
- const union MHD_DaemonInfo *di;
- const char *forwarded_proto = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- "X-Forwarded-Proto");
-
- if (NULL != forwarded_proto)
- {
- if (0 == strcmp (forwarded_proto, "https"))
- return GNUNET_YES;
- if (0 == strcmp (forwarded_proto, "http"))
- return GNUNET_NO;
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- /* likely not reverse proxy, figure out if we are
- http by asking MHD */
- ci = MHD_get_connection_info (connection, MHD_CONNECTION_INFO_DAEMON);
- if (NULL == ci)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- di = MHD_get_daemon_info (ci->daemon, MHD_DAEMON_INFO_FLAGS);
- if (NULL == di)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (0 != (di->flags & MHD_USE_TLS))
- return GNUNET_YES;
- return GNUNET_NO;
-}
-
-
-/**
- * Make an absolute URL for a given MHD connection.
- *
- * @param connection the connection to get the URL for
- * @param path path of the url
- * @param ... NULL-terminated key-value pairs (char *) for query parameters,
- * the value will be url-encoded
- * @returns the URL, must be freed with #GNUNET_free
- */
-char *
-TALER_url_absolute_mhd (struct MHD_Connection *connection,
- const char *path,
- ...)
-{
- /* By default we assume we're running under HTTPS */
- const char *proto;
- const char *host;
- const char *forwarded_host;
- const char *prefix;
- va_list args;
- char *result;
-
- if (GNUNET_YES == TALER_mhd_is_https (connection))
- proto = "https";
- else
- proto = "http";
-
- host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "Host");
- forwarded_host = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
- "X-Forwarded-Host");
-
- prefix = MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
- "X-Forwarded-Prefix");
- if (NULL == prefix)
- prefix = "";
-
- if (NULL != forwarded_host)
- host = forwarded_host;
-
- if (NULL == host)
- {
- /* Should never happen, at last the host header should be defined */
- GNUNET_break (0);
- return NULL;
- }
-
- va_start (args, path);
- result = TALER_url_absolute_raw_va (proto, host, prefix, path, args);
- va_end (args);
- return result;
-}
-
-
-/**
- * Prefix of PAYTO URLs.
- */
-#define PAYTO "payto://"
-
-
-/**
- * Obtain the payment method from a @a payto_uri
- *
- * @param payto_uri the URL to parse
- * @return NULL on error (malformed @a payto_uri)
- */
-char *
-TALER_payto_get_method (const char *payto_uri)
-{
- const char *start;
- const char *end;
-
- if (0 != strncmp (payto_uri,
- PAYTO,
- strlen (PAYTO)))
- return NULL;
- start = &payto_uri[strlen (PAYTO)];
- end = strchr (start,
- (unsigned char) '/');
- if (NULL == end)
- return NULL;
- return GNUNET_strndup (start,
- end - start);
-}
-
-
-/**
- * Obtain the account name from a payto URL.
- *
- * @param payto an x-taler-bank payto URL
- * @return only the account name from the @a payto URL, NULL if not an x-taler-bank
- * payto URL
- */
-char *
-TALER_xtalerbank_account_from_payto (const char *payto)
-{
- const char *beg;
- const char *end;
-
- if (0 != strncasecmp (payto,
- "payto://x-taler-bank/",
- strlen ("payto://x-taler-bank/")))
- return NULL;
- beg = strchr (&payto[strlen ("payto://x-taler-bank/")],
- '/');
- if (NULL == beg)
- return NULL;
- beg++;
- end = strchr (beg,
- '?');
- if (NULL == end)
- return GNUNET_strdup (beg);
- return GNUNET_strndup (beg,
- end - beg);
-}
-
-
/* end of util.c */