aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Kadianakis <desnacked@riseup.net>2019-06-03 15:43:54 +0300
committerGeorge Kadianakis <desnacked@riseup.net>2019-11-18 19:18:49 +0200
commit8330b4dc2a18befa0eda8e48abb7f6e151596562 (patch)
treec9310b17d5755ccd34a5120f3d3d26df430fd982 /src
parent46f441502227665c25aa0ad8710bdf8487193904 (diff)
downloadtor-8330b4dc2a18befa0eda8e48abb7f6e151596562.tar.gz
tor-8330b4dc2a18befa0eda8e48abb7f6e151596562.zip
control-port: Implement ONION_CLIENT_AUTH_REMOVE.
Diffstat (limited to 'src')
-rw-r--r--src/feature/control/control_cmd.c1
-rw-r--r--src/feature/control/control_hs.c50
-rw-r--r--src/feature/control/control_hs.h6
-rw-r--r--src/feature/hs/hs_client.c25
-rw-r--r--src/feature/hs/hs_client.h13
5 files changed, 94 insertions, 1 deletions
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c
index 3c16722e15..fcd0d8b292 100644
--- a/src/feature/control/control_cmd.c
+++ b/src/feature/control/control_cmd.c
@@ -2320,6 +2320,7 @@ static const control_cmd_def_t CONTROL_COMMANDS[] =
ONE_LINE(add_onion, CMD_FL_WIPE),
ONE_LINE(del_onion, CMD_FL_WIPE),
ONE_LINE(onion_client_auth_add, CMD_FL_WIPE),
+ ONE_LINE(onion_client_auth_remove, 0),
};
/**
diff --git a/src/feature/control/control_hs.c b/src/feature/control/control_hs.c
index 5db8a0f007..93e66261e0 100644
--- a/src/feature/control/control_hs.c
+++ b/src/feature/control/control_hs.c
@@ -159,3 +159,53 @@ handle_control_onion_client_auth_add(control_connection_t *conn,
smartlist_free(flags);
return retval;
}
+
+/** Syntax details for ONION_CLIENT_AUTH_REMOVE */
+const control_cmd_syntax_t onion_client_auth_remove_syntax = {
+ .max_args = 1,
+ .accept_keywords = true,
+};
+
+/** Called when we get an ONION_CLIENT_AUTH_REMOVE command; parse the body, and
+ * register the new client-side client auth credentials.
+ * "ONION_CLIENT_AUTH_REMOVE" SP HSAddress
+ */
+int
+handle_control_onion_client_auth_remove(control_connection_t *conn,
+ const control_cmd_args_t *args)
+{
+ int retval = -1;
+
+ tor_assert(args);
+
+ int argc = smartlist_len(args->args);
+ if (argc < 1) {
+ control_printf_endreply(conn, 512,
+ "Incomplete ONION_CLIENT_AUTH_REMOVE command");
+ goto err;
+ }
+
+ const char *hsaddress = smartlist_get(args->args, 0);
+ if (!hs_address_is_valid(hsaddress)) {
+ control_printf_endreply(conn, 512, "Invalid v3 address \"%s\"",hsaddress);
+ goto err;
+ }
+
+ hs_client_removal_auth_status_t removal_status;
+ removal_status = hs_client_remove_auth_credentials(hsaddress);
+ if (BUG(removal_status == REMOVAL_BAD_ADDRESS)) {
+ /* It's a bug because the service addr has already been validated above */
+ control_printf_endreply(conn, 512, "Invalid v3 address \"%s\"",hsaddress);
+ } else if (removal_status == REMOVAL_SUCCESS_NOT_FOUND) {
+ control_printf_endreply(conn, 251, "No credentials for \"%s\"",hsaddress);
+ } else if (removal_status == REMOVAL_SUCCESS) {
+ control_printf_endreply(conn, 250, "OK");
+ } else {
+ tor_assert_nonfatal_unreached();
+ }
+
+ retval = 0;
+
+ err:
+ return retval;
+}
diff --git a/src/feature/control/control_hs.h b/src/feature/control/control_hs.h
index 1fcd7de36c..067c7dc47f 100644
--- a/src/feature/control/control_hs.h
+++ b/src/feature/control/control_hs.h
@@ -13,12 +13,16 @@
struct control_cmd_syntax_t;
-extern const char *onion_client_auth_add_keywords[];
extern const struct control_cmd_syntax_t onion_client_auth_add_syntax;
+extern const struct control_cmd_syntax_t onion_client_auth_remove_syntax;
int
handle_control_onion_client_auth_add(control_connection_t *conn,
const control_cmd_args_t *args);
+int
+handle_control_onion_client_auth_remove(control_connection_t *conn,
+ const control_cmd_args_t *args);
+
#endif
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index c854737bef..bbe7b87a60 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -1475,6 +1475,31 @@ hs_client_register_auth_credentials(hs_client_service_authorization_t *creds)
return REGISTER_SUCCESS;
}
+/** Remove client auth credentials for the service <b>hs_address</b>. */
+hs_client_removal_auth_status_t
+hs_client_remove_auth_credentials(const char *hsaddress)
+{
+ ed25519_public_key_t service_identity_pk;
+
+ if (!client_auths) {
+ return REMOVAL_SUCCESS_NOT_FOUND;
+ }
+
+ if (hs_parse_address(hsaddress, &service_identity_pk, NULL, NULL) < 0) {
+ return REMOVAL_BAD_ADDRESS;
+ }
+
+ hs_client_service_authorization_t *cred = NULL;
+ cred = digest256map_remove(client_auths, service_identity_pk.pubkey);
+ /* digestmap_remove() returns the previously stored data if there were any */
+ if (cred) {
+ client_service_authorization_free(cred);
+ return REMOVAL_SUCCESS;
+ }
+
+ return REMOVAL_SUCCESS_NOT_FOUND;
+}
+
/* ========== */
/* Public API */
/* ========== */
diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h
index ea726e2370..459c19db58 100644
--- a/src/feature/hs/hs_client.h
+++ b/src/feature/hs/hs_client.h
@@ -41,6 +41,16 @@ typedef enum {
REGISTER_FAIL_BAD_ADDRESS,
} hs_client_register_auth_status_t;
+/* Status code of client auth credential removal */
+typedef enum {
+ /* We successfuly removed these credentials */
+ REMOVAL_SUCCESS,
+ /* No need to remove those credentials, because they were not there. */
+ REMOVAL_SUCCESS_NOT_FOUND,
+ /* We failed to register these credentials, because of a bad HS address. */
+ REMOVAL_BAD_ADDRESS,
+} hs_client_removal_auth_status_t;
+
/** Flag to set when a client auth is permanent (saved on disk). */
#define CLIENT_AUTH_FLAG_IS_PERMANENT (1<<0)
@@ -63,6 +73,9 @@ typedef struct hs_client_service_authorization_t {
hs_client_register_auth_status_t
hs_client_register_auth_credentials(hs_client_service_authorization_t *creds);
+hs_client_removal_auth_status_t
+hs_client_remove_auth_credentials(const char *hsaddress);
+
#define client_service_authorization_free(auth) \
FREE_AND_NULL(hs_client_service_authorization_t, \
client_service_authorization_free_, (auth))