commit b60c4b335971a871cc879ca52aecd9340d1f4ea7 parent 1dabae961c054c766781a147ef6df57fe2cbf0d4 Author: Christian Grothoff <grothoff@gnunet.org> Date: Wed, 15 Nov 2023 13:49:29 +0100 support more address types Diffstat:
17 files changed, 190 insertions(+), 120 deletions(-)
diff --git a/src/challenger/challenger-httpd_authorize.c b/src/challenger/challenger-httpd_authorize.c @@ -135,7 +135,7 @@ CH_handler_authorize (struct CH_HandlerContext *hc, MHD_GET_ARGUMENT_KIND, "scope"); { - char *last_address; + json_t *last_address; uint32_t address_attempts_left; enum GNUNET_DB_QueryStatus qs; @@ -173,26 +173,30 @@ CH_handler_authorize (struct CH_HandlerContext *hc, { enum GNUNET_GenericReturnValue ret; json_t *args; + char *form; + GNUNET_asprintf (&form, + "enter-%s-form", + CH_address_type); args = GNUNET_JSON_PACK ( GNUNET_JSON_pack_bool ("fix_address", 0 == address_attempts_left), GNUNET_JSON_pack_string ("nonce", hc->path), - GNUNET_JSON_pack_string ("last_address", - (NULL == last_address) - ? "" - : last_address), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_object_steal ("last_address", + last_address)), GNUNET_JSON_pack_uint64 ("changes_left", address_attempts_left) ); ret = TALER_TEMPLATING_reply ( hc->connection, MHD_HTTP_OK, - "enter-address-form", + form, NULL, NULL, args); + GNUNET_free (form); json_decref (args); if (GNUNET_SYSERR == ret) { diff --git a/src/challenger/challenger-httpd_challenge.c b/src/challenger/challenger-httpd_challenge.c @@ -70,9 +70,19 @@ struct ChallengeContext struct MHD_PostProcessor *pp; /** - * 0-terminated address information submitted to us. + * Where we store the collected address data. */ - char *address; + json_t *address; + + /** + * Last key during POST processing. + */ + char *last_key; + + /** + * Uploaded data during POST processing. + */ + char *data; /** * When did we transmit last? @@ -87,7 +97,7 @@ struct ChallengeContext /** * Number of bytes in @a address, excluding 0-terminator. */ - size_t address_len; + size_t data_len; /** * Our tan. @@ -186,7 +196,9 @@ cleanup_ctx (void *cls) GNUNET_OS_process_wait (bc->child)); bc->child = NULL; } - GNUNET_free (bc->address); + json_decref (bc->address); + GNUNET_free (bc->data); + GNUNET_free (bc->last_key); GNUNET_free (bc); } @@ -248,18 +260,25 @@ send_tan (struct ChallengeContext *bc) : GNUNET_SYSERR; return; } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Running auth command `%s' on address `%s'\n", - CH_auth_command, - bc->address); - bc->child = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, - p, - NULL, - NULL, - CH_auth_command, - CH_auth_command, - bc->address, - NULL); + { + char *address; + + address = json_dumps (bc->address, + JSON_COMPACT); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Running auth command `%s' on address `%s'\n", + CH_auth_command, + address); + bc->child = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR, + p, + NULL, + NULL, + CH_auth_command, + CH_auth_command, + address, + NULL); + free (address); + } if (NULL == bc->child) { MHD_RESULT mres; @@ -362,18 +381,31 @@ post_iter (void *cls, (void) content_type; (void) transfer_encoding; (void) off; - if (0 != strcmp (key, - "address")) - return MHD_YES; if (MHD_POSTDATA_KIND != kind) return MHD_YES; - bc->address = GNUNET_realloc (bc->address, - bc->address_len + size + 1); - memcpy (bc->address + bc->address_len, + if ( (NULL != bc->last_key) && + (0 != strcmp (key, + bc->last_key)) ) + { + GNUNET_assert (0 == + json_object_set_new (bc->address, + bc->last_key, + json_string (bc->data))); + GNUNET_free (bc->data); + bc->data_len = 0; + GNUNET_free (bc->last_key); + } + if (NULL == bc->last_key) + { + bc->last_key = GNUNET_strdup (key); + } + bc->data = GNUNET_realloc (bc->data, + bc->data_len + size + 1); + memcpy (bc->data + bc->data_len, data, size); - bc->address_len += size; - bc->address[bc->address_len] = '\0'; + bc->data_len += size; + bc->data[bc->data_len] = '\0'; return MHD_YES; } @@ -394,6 +426,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc, hc->cc = &cleanup_ctx; hc->ctx = bc; bc->pst = GNUNET_OS_PROCESS_UNKNOWN; + bc->address = json_object (); bc->tan = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 100000000); @@ -461,9 +494,26 @@ CH_handler_challenge (struct CH_HandlerContext *hc, return MHD_YES; return MHD_NO; } - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Submitted address is `%s'\n", - bc->address); + if (NULL != bc->last_key) + { + GNUNET_assert (0 == + json_object_set_new (bc->address, + bc->last_key, + json_string (bc->data))); + GNUNET_free (bc->data); + bc->data_len = 0; + GNUNET_free (bc->last_key); + } + { + char *address; + + address = json_dumps (bc->address, + JSON_COMPACT); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Submitted address is `%s'\n", + address); + free (address); + } if (! bc->db_finished) { enum GNUNET_DB_QueryStatus qs; @@ -512,8 +562,7 @@ CH_handler_challenge (struct CH_HandlerContext *hc, if (bc->retransmit) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Transmitting PIN to `%s'\n", - bc->address); + "Transmitting PIN\n"); /* (Re)transmit PIN/TAN */ send_tan (bc); if (GNUNET_YES == bc->suspended) @@ -535,8 +584,8 @@ CH_handler_challenge (struct CH_HandlerContext *hc, bc->pin_attempts_left), GNUNET_JSON_pack_string ("nonce", hc->path), - GNUNET_JSON_pack_string ("address", - bc->address), + GNUNET_JSON_pack_object_incref ("address", + bc->address), GNUNET_JSON_pack_bool ("transmitted", bc->retransmit), GNUNET_JSON_pack_string ("next_tx_time", diff --git a/src/challenger/challenger-httpd_common.c b/src/challenger/challenger-httpd_common.c @@ -59,14 +59,17 @@ char * CH_compute_code (const struct CHALLENGER_ValidationNonceP *nonce, const char *client_secret, const char *client_scope, - const char *address, + const json_t *address, const char *client_redirect_uri) { char *code; char *ns; char *hs; struct GNUNET_ShortHashCode h; + char *astr; + astr = json_dumps (address, + JSON_COMPACT); GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&h, sizeof (h), @@ -74,8 +77,8 @@ CH_compute_code (const struct CHALLENGER_ValidationNonceP *nonce, sizeof (nonce), client_secret, strlen (client_secret), - address, - strlen (address), + astr, + strlen (astr), client_redirect_uri, strlen (client_redirect_uri), client_scope, @@ -84,6 +87,7 @@ CH_compute_code (const struct CHALLENGER_ValidationNonceP *nonce, : 0, NULL, 0)); + free (astr); ns = GNUNET_STRINGS_data_to_string_alloc (nonce, sizeof (*nonce)); hs = GNUNET_STRINGS_data_to_string_alloc (&h, diff --git a/src/challenger/challenger-httpd_common.h b/src/challenger/challenger-httpd_common.h @@ -51,7 +51,7 @@ char * CH_compute_code (const struct CHALLENGER_ValidationNonceP *nonce, const char *client_secret, const char *client_scope, - const char *address, + const json_t *address, const char *client_redirect_uri); diff --git a/src/challenger/challenger-httpd_solve.c b/src/challenger/challenger-httpd_solve.c @@ -234,7 +234,7 @@ CH_handler_solve (struct CH_HandlerContext *hc, { char *client_secret; - char *address; + json_t *address; char *client_scope; char *client_state; char *client_redirect_uri; @@ -286,7 +286,7 @@ CH_handler_solve (struct CH_HandlerContext *hc, GNUNET_free (url_encoded); GNUNET_free (code); } - GNUNET_free (address); + json_decref (address); GNUNET_free (client_scope); GNUNET_free (client_secret); GNUNET_free (client_redirect_uri); diff --git a/src/challenger/challenger-httpd_token.c b/src/challenger/challenger-httpd_token.c @@ -353,7 +353,7 @@ CH_handler_token (struct CH_HandlerContext *hc, /* Check code is valid */ { char *client_secret; - char *address; + json_t *address; char *client_scope; char *client_state; char *client_redirect_uri; @@ -393,7 +393,6 @@ CH_handler_token (struct CH_HandlerContext *hc, if (NULL == address) { GNUNET_break_op (0); - GNUNET_free (address); GNUNET_free (client_scope); GNUNET_free (client_secret); GNUNET_free (client_redirect_uri); @@ -410,7 +409,7 @@ CH_handler_token (struct CH_HandlerContext *hc, client_scope, address, client_redirect_uri); - GNUNET_free (address); + json_decref (address); GNUNET_free (client_scope); GNUNET_free (client_secret); GNUNET_free (client_redirect_uri); diff --git a/src/challenger/challenger-send-email.sh b/src/challenger/challenger-send-email.sh @@ -1,3 +1,4 @@ #!/bin/sh # This file is in the public domain. -exec mail -s "KYC Challenger" -r noreply "$1" +EMAIL=$(echo "$1" | jq -r .email) +exec mail -s "KYC Challenger" -r noreply "$EMAIL" diff --git a/src/challenger/challenger-send-post.sh b/src/challenger/challenger-send-post.sh @@ -11,36 +11,38 @@ set -eu ENDPOINT="https://api.v2.pingen.com" LOGS="$PWD/authorization-post.log" -MESSAGE=`cat -` -DATE=`date +%F` +MESSAGE=$(cat -) +DATE=$(date +%F) ADDR="$1" -NAME=`echo $ADDR | jq -r .full_name` -STREET=`echo $ADDR | jq -r .street` +NAME=$(echo "$ADDR" | jq -r .full_name) +STREET=$(echo "$ADDR" | jq -r .street) -LNUMBER=`echo $STREET | awk '{print $NF}'` -FNUMBER=`echo $STREET | awk '{print $1}'` -case $LNUMBER in +LNUMBER=$(echo $STREET | awk '{print $NF}') +FNUMBER=$(echo $STREET | awk '{print $1}') +case "$LNUMBER" +in ''|*[!0-9]*) - case $FNUMBER in + case "$FNUMBER" + in ''|*[!0-9]*) NUMBER=0 ;; *) - NUMBER=$FNUMBER + NUMBER="$FNUMBER" ;; esac ;; *) - NUMBER=$LNUMBER + NUMBER="$LNUMBER" ;; esac -CITY=`echo $ADDR | jq -r .city` -POSTCODE=`echo $ADDR | jq -r .postcode` -COUNTRY=`echo $ADDR | jq -r .country` +CITY=$(echo "$ADDR" | jq -r .city) +POSTCODE=$(echo "$ADDR" | jq -r .postcode) +COUNTRY=$(echo "$ADDR" | jq -r .country) -MYDIR=`mktemp -d /tmp/authorization-post-XXXXXX` +MYDIR=$(mktemp -d /tmp/authorization-post-XXXXXX) cd "$MYDIR" cat - | sed -e "s/%NAME%/$NAME/g" \ -e "s/%STREET%/$STREET/g" \ @@ -72,23 +74,29 @@ cat - | sed -e "s/%NAME%/$NAME/g" \ EOF pdflatex input.tex > /dev/null 2> /dev/null -REPLY=`curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" \ - --data-urlencode "grant_type=client_credentials" \ - --data-urlencode "client_id=$CLIENT_ID" \ - --data-urlencode "client_secret=$CLIENT_SECRET" \ - --data-urlencode "scope=letter" \ - https://identity.pingen.com/auth/access-tokens` +REPLY=$(curl \ + -s \ + -X POST \ + -H "Content-Type: application/x-www-form-urlencoded" \ + --data-urlencode "grant_type=client_credentials" \ + --data-urlencode "client_id=$CLIENT_ID" \ + --data-urlencode "client_secret=$CLIENT_SECRET" \ + --data-urlencode "scope=letter" \ + https://identity.pingen.com/auth/access-tokens) -ACCESS_TOKEN=`echo $REPLY | jq -r .access_token` +ACCESS_TOKEN=$(echo $REPLY | jq -r .access_token) -REPLY=`curl -s \ +REPLY=$(curl -s \ -X GET "$ENDPOINT/file-upload" \ - -H "Authorization: Bearer $ACCESS_TOKEN"` -ATTRS=`echo $REPLY | jq .data.attributes` -UPLOAD_URL=`echo $ATTRS | jq -r .url` -URL_SIG=`echo $ATTRS | jq -r .url_signature` + -H "Authorization: Bearer $ACCESS_TOKEN") +ATTRS=$(echo "$REPLY" | jq .data.attributes) +UPLOAD_URL=$(echo "$ATTRS" | jq -r .url) +URL_SIG=$(echo "$ATTRS" | jq -r .url_signature) -curl -s -X PUT -T input.pdf $UPLOAD_URL +curl -s \ + -X PUT \ + -T input.pdf \ + "$UPLOAD_URL" RECIPIENT="$(jq -n ' @@ -139,47 +147,48 @@ REQUEST="$(jq -n ' --arg URL_SIG "$URL_SIG" \ )" -STATUS=$(curl -s --request POST \ - --url $ENDPOINT/organisations/${ORG_ID}/letters \ - --header 'Content-Type: application/vnd.api+json' \ +STATUS=$(curl -s \ + --request POST \ + --url "$ENDPOINT/organisations/${ORG_ID}/letters" \ + --header "Content-Type: application/vnd.api+json" \ --header "Authorization: Bearer $ACCESS_TOKEN" \ -d "$REQUEST" \ - -o $MYDIR/final-reply.txt \ + -o "$MYDIR/final-reply.txt" \ -w "%{http_code}" -s) -cat $MYDIR/final-reply.txt >> $LOGS -case $STATUS in +cat "$MYDIR/final-reply.txt" >> "$LOGS" +case "$STATUS" in 201) ;; *) - echo "Failed to add letter: $STATUS" >> $LOGS - echo $REPLY + echo "Failed to add letter: $STATUS" >> "$LOGS" + echo "$REPLY" exit 1; ;; esac -LETTER_ID=`cat $MYDIR/final-reply.txt | jq -r .data.id` -REPLY=$MYDIR/delete-reply.txt +LETTER_ID=$(cat $MYDIR/final-reply.txt | jq -r .data.id) +REPLY="$MYDIR/delete-reply.txt" STATUS=409 sleep 1; -while test $STATUS = 409; +while test "$STATUS" = 409; do STATUS=$(curl -s --request DELETE \ - --url $ENDPOINT/organisations/$ORG_ID/letters/$LETTER_ID \ + --url "$ENDPOINT/organisations/$ORG_ID/letters/$LETTER_ID" \ --header "Authorization: Bearer $ACCESS_TOKEN" \ - -o $REPLY \ + -o "$REPLY" \ -w "%{http_code}" -s) - case $STATUS in + case "$STATUS" in 204) - cat $REPLY >> $LOGS + cat "$REPLY" >> "$LOGS" ;; 409) # Happens, likely still in processing... ;; *) - echo "Failed to delete letter: $STATUS" >> $LOGS + echo "Failed to delete letter: $STATUS" >> "$LOGS" ;; esac done -rm -r $MYDIR +rm -r "$MYDIR" exit 0 diff --git a/src/challenger/challenger-send-sms.sh b/src/challenger/challenger-send-sms.sh @@ -3,21 +3,21 @@ set -eu . telesign-secrets # Set AUTH_TOKEN=... - -MESSAGE=`cat -` -TMPFILE=`mktemp /tmp/sms-loggingXXXXXX` -STATUS=$(curl --request POST \ - --url https://rest-api.telesign.com/v1/messaging \ - --header 'authorization: Basic $AUTH_TOKEN' \ - --header 'content-type: application/x-www-form-urlencoded' \ - --data account_livecycle_event=transact \ +NUMBER=$(echo "$1" | jq -r .phone) +MESSAGE=$(cat -) +TMPFILE=$(mktemp /tmp/sms-loggingXXXXXX) +STATUS=$(curl --request "POST" \ + --url "https://rest-api.telesign.com/v1/messaging" \ + --header "Authorization: Basic $AUTH_TOKEN" \ + --header "Content-type: application/x-www-form-urlencoded" \ + --data "account_livecycle_event=transact" \ --data "message=$MESSAGE" \ - --data message_type=OTP \ - --data "phone_number=$1" \ - -w "%{http_code}" -s -o $TMPFILE) -echo `cat $TMPFILE` >> /var/log/sms.log -rm -f $TMPFILE -case $STATUS in + --data "message_type=OTP" \ + --data "phone_number=$NUMBER" \ + -w "%{http_code}" -s -o "$TMPFILE") +echo $(cat $TMPFILE) >> /var/log/sms.log +rm -f "$TMPFILE" +case "$STATUS" in 200|203|250|290|291|295) exit 0; ;; diff --git a/src/challenger/challenger.conf b/src/challenger/challenger.conf @@ -35,5 +35,9 @@ VALIDATION_EXPIRATION = 365d # AUTH_COMMAND = -# What address type are we validating? (SMS, e-mail, etc.) +# What address type are we validating? (phone, email, address, etc.) +# A template of the form 'enter-$ADDRESS_TYPE-form' must +# exist and the field names must be supported by the +# AUTH_COMMAND. +# # ADDRESS_TYPE = diff --git a/src/challengerdb/pg_authorize_start.c b/src/challengerdb/pg_authorize_start.c @@ -33,7 +33,7 @@ CH_PG_authorize_start (void *cls, const char *client_scope, const char *client_state, const char *client_redirect_uri, - char **last_address, + json_t **last_address, uint32_t *address_attempts_left) { struct PostgresClosure *pg = cls; @@ -51,8 +51,8 @@ CH_PG_authorize_start (void *cls, }; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_allow_null ( - GNUNET_PQ_result_spec_string ("address", - last_address), + TALER_PQ_result_spec_json ("address", + last_address), NULL), GNUNET_PQ_result_spec_uint32 ("address_attempts_left", address_attempts_left), diff --git a/src/challengerdb/pg_authorize_start.h b/src/challengerdb/pg_authorize_start.h @@ -52,7 +52,7 @@ CH_PG_authorize_start (void *cls, const char *client_scope, const char *client_state, const char *client_redirect_uri, - char **last_address, + json_t **last_address, uint32_t *address_attempts_left); diff --git a/src/challengerdb/pg_challenge_set_address_and_pin.c b/src/challengerdb/pg_challenge_set_address_and_pin.c @@ -30,7 +30,7 @@ enum GNUNET_DB_QueryStatus CH_PG_challenge_set_address_and_pin ( void *cls, const struct CHALLENGER_ValidationNonceP *nonce, - const char *address, + const json_t *address, struct GNUNET_TIME_Relative validation_duration, uint32_t *tan, struct GNUNET_TIME_Absolute *last_tx_time, @@ -45,7 +45,7 @@ CH_PG_challenge_set_address_and_pin ( validation_duration); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (nonce), - GNUNET_PQ_query_param_string (address), + TALER_PQ_query_param_json (address), GNUNET_PQ_query_param_absolute_time (&next_tx_time), GNUNET_PQ_query_param_absolute_time (&now), GNUNET_PQ_query_param_uint32 (tan), diff --git a/src/challengerdb/pg_challenge_set_address_and_pin.h b/src/challengerdb/pg_challenge_set_address_and_pin.h @@ -49,7 +49,7 @@ enum GNUNET_DB_QueryStatus CH_PG_challenge_set_address_and_pin ( void *cls, const struct CHALLENGER_ValidationNonceP *nonce, - const char *address, + const json_t *address, struct GNUNET_TIME_Relative validation_duration, uint32_t *tan, struct GNUNET_TIME_Absolute *last_tx_time, diff --git a/src/challengerdb/pg_validation_get.c b/src/challengerdb/pg_validation_get.c @@ -29,7 +29,7 @@ enum GNUNET_DB_QueryStatus CH_PG_validation_get (void *cls, const struct CHALLENGER_ValidationNonceP *nonce, char **client_secret, - char **address, + json_t **address, char **client_scope, char **client_state, char **client_redirect_uri) @@ -43,8 +43,8 @@ CH_PG_validation_get (void *cls, GNUNET_PQ_result_spec_string ("client_secret", client_secret), GNUNET_PQ_result_spec_allow_null ( - GNUNET_PQ_result_spec_string ("address", - address), + TALER_PQ_result_spec_json ("address", + address), NULL), GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_string ("client_scope", diff --git a/src/challengerdb/pg_validation_get.h b/src/challengerdb/pg_validation_get.h @@ -47,7 +47,7 @@ enum GNUNET_DB_QueryStatus CH_PG_validation_get (void *cls, const struct CHALLENGER_ValidationNonceP *nonce, char **client_secret, - char **address, + json_t **address, char **client_scope, char **client_state, char **client_redirect_uri); diff --git a/src/include/challenger_database_plugin.h b/src/include/challenger_database_plugin.h @@ -243,7 +243,7 @@ struct CHALLENGER_DatabasePlugin const char *client_scope, const char *client_state, const char *client_redirect_uri, - char **last_address, + json_t **last_address, uint32_t *address_attempts_left); @@ -270,7 +270,7 @@ struct CHALLENGER_DatabasePlugin (*challenge_set_address_and_pin)( void *cls, const struct CHALLENGER_ValidationNonceP *nonce, - const char *address, + const json_t *address, struct GNUNET_TIME_Relative validation_duration, uint32_t *tan, struct GNUNET_TIME_Absolute *last_tx_time, @@ -318,7 +318,7 @@ struct CHALLENGER_DatabasePlugin (*validation_get)(void *cls, const struct CHALLENGER_ValidationNonceP *nonce, char **client_secret, - char **address, + json_t **address, char **client_scope, char **client_state, char **client_redirect_uri);