trp/trp_upd.c
trp/trpc.c
trp/trps.c include/tr_name_internal.h mon/mon_req.c mon/mon_req_encode.c mon/mon_req_decode.c
- mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c common/tr_config_filters.c common/tr_config_realms.c common/tr_config_rp_clients.c common/tr_config_orgs.c common/tr_config_comms.c common/tr_list.c include/tr_list.h include/tr_constraint_internal.h include/tr_json_util.h)
+ mon/mon_resp.c mon/mon_common.c mon/mon_resp_encode.c mon/mon_resp_decode.c tr/tr_mon.c mon/mons.c include/tr_socket.h common/tr_gss.c include/tr_gss.h common/tr_config_internal.c mon/mons_handlers.c include/mons_handlers.h tr/tr_tid_mons.c tr/tr_tid_mons.c trp/trp_route.c include/trp_route.h trp/trp_rtable_encoders.c trp/trp_route_encoders.c trp/trp_peer.c include/trp_peer.h trp/trp_peer_encoders.c trp/trp_ptable_encoders.c common/tr_idp_encoders.c common/tr_comm_encoders.c common/tr_rp_client.c include/tr_rp_client.h common/tr_rp_client_encoders.c common/tr_filter_encoders.c common/tr_config_encoders.c common/tr_config_filters.c common/tr_config_realms.c common/tr_config_rp_clients.c common/tr_config_orgs.c common/tr_config_comms.c common/tr_list.c include/tr_list.h include/tr_constraint_internal.h include/tr_json_util.h common/tr_aaa_server.c include/tr_aaa_server.h common/tr_inet_util.c include/tr_inet_util.h)
# Does not actually build!
add_executable(trust_router ${SOURCE_FILES})
common/tr_dh.c \
common/tr_debug.c \
common/tr_util.c \
+ common/tr_inet_util.c \
common/tr_apc.c \
common/tr_comm.c \
common/tr_comm_encoders.c \
common/tr_rp_client.c \
common/tr_rp_client_encoders.c \
common/tr_idp.c \
+ common/tr_aaa_server.c \
common/tr_idp_encoders.c \
common/tr_filter.c \
common/tr_filter_encoders.c \
common/tr_gss_names.c \
common/tr_debug.c \
common/tr_util.c \
+common/tr_inet_util.c \
common/tr_list.c \
trp/trp_route.c \
trp/trp_route_encoders.c \
include/tr.h \
include/tr_msg.h \
include/tr_idp.h \
+ include/tr_aaa_server.h \
include/tr_rp.h include/tr_rp_client.h \
include/tr_comm.h \
include/tr_apc.h \
include/trp_route.h include/trp_rtable.h \
include/tr_list.h \
include/tr_name_internal.h \
- include/tr_util.h include/tr_json_util.h \
+ include/tr_util.h include/tr_json_util.h include/tr_inet_util.h\
include/tr_rand_id.h include/tr_socket.h \
include/tr_constraint_internal.h
static TR_AAA_SERVER *aaa_entry_to_aaa_server(TALLOC_CTX *mem_ctx, struct aaa_entry *ae)
{
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
- TR_AAA_SERVER *aaa=tr_aaa_server_new(tmp_ctx, tr_new_name(ae->hostname));
+ TR_AAA_SERVER *aaa=tr_aaa_server_from_string(tmp_ctx, ae->hostname);
- if ((aaa==NULL) || (aaa->hostname==NULL))
- aaa=NULL;
- else
+ if (aaa)
talloc_steal(mem_ctx, aaa);
talloc_free(tmp_ctx);
--- /dev/null
+/*
+ * Copyright (c) 2012-2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <talloc.h>
+
+#include <tr_name_internal.h>
+#include <tr_aaa_server.h>
+#include <trust_router/tid.h>
+#include <tr_util.h>
+#include <tr_inet_util.h>
+
+static int tr_aaa_server_destructor(void *obj)
+{
+ TR_AAA_SERVER *aaa=talloc_get_type_abort(obj, TR_AAA_SERVER);
+ if (aaa->hostname!=NULL)
+ tr_free_name(aaa->hostname);
+ return 0;
+}
+
+TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx)
+{
+ TR_AAA_SERVER *aaa=talloc(mem_ctx, TR_AAA_SERVER);
+ if (aaa!=NULL) {
+ aaa->next=NULL;
+ aaa->hostname = NULL;
+ tr_aaa_server_set_port(aaa, 0); /* go through setter to guarantee consistent default */
+ talloc_set_destructor((void *)aaa, tr_aaa_server_destructor);
+ }
+ return aaa;
+}
+
+void tr_aaa_server_free(TR_AAA_SERVER *aaa)
+{
+ talloc_free(aaa);
+}
+
+TR_NAME *tr_aaa_server_get_hostname(TR_AAA_SERVER *aaa)
+{
+ return aaa->hostname;
+}
+
+/**
+ * Set the hostname for a AAA server
+ *
+ * Takes ownership of the TR_NAME. Does nothing if aaa is null.
+ *
+ * @param aaa
+ * @param hostname
+ */
+void tr_aaa_server_set_hostname(TR_AAA_SERVER *aaa, TR_NAME *hostname)
+{
+ if (aaa == NULL)
+ return;
+
+ if (aaa->hostname != NULL) {
+ tr_free_name(aaa->hostname);
+ }
+
+ aaa->hostname = hostname;
+}
+
+int tr_aaa_server_get_port(TR_AAA_SERVER *aaa)
+{
+ return aaa->port;
+}
+
+/**
+ * Set the port for a AAA server
+ *
+ * If port is 0, uses the standard TID port (12309). Other invalid values are stored
+ * as-is.
+ *
+ * Does nothing if aaa is null.
+ *
+ * @param aaa
+ * @param port
+ */
+void tr_aaa_server_set_port(TR_AAA_SERVER *aaa, int port)
+{
+ if (aaa == NULL)
+ return;
+
+ if (port == 0)
+ port = TID_PORT;
+
+ aaa->port = port;
+}
+
+/**
+ * Allocate a AAA server record and fill it in by parsing a hostname:port string
+ *
+ * If hostname or port are invalid, hostname will be empty and port will be -1.
+ *
+ * @return newly allocated TR_AAA_SERVER in the mem_ctx context, or NULL on error
+ */
+TR_AAA_SERVER *tr_aaa_server_from_string(TALLOC_CTX *mem_ctx, const char *s)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ TR_AAA_SERVER *aaa = tr_aaa_server_new(tmp_ctx);
+ char *hostname;
+ int port;
+
+ if (aaa == NULL)
+ goto failed;
+
+ hostname = tr_parse_host(tmp_ctx, s, &port);
+ if (NULL == hostname) {
+ hostname = "";
+ port = -1;
+ }
+
+ tr_aaa_server_set_hostname(aaa, tr_new_name(hostname));
+ if (tr_aaa_server_get_hostname(aaa) == NULL)
+ goto failed;
+
+ tr_aaa_server_set_port(aaa, port); /* port = 0 uses default TID port */
+ talloc_steal(mem_ctx, aaa); /*put this in the caller's context */
+ goto succeeded;
+
+failed:
+ aaa = NULL; /* talloc will free the memory if it was allocated */
+
+succeeded:
+ talloc_free(tmp_ctx);
+ return aaa;
+}
+
+TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx)
+{
+ return talloc(mem_ctx, TR_AAA_SERVER_ITER);
+}
+
+void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter)
+{
+ talloc_free(iter);
+}
+
+TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa)
+{
+ iter->this=aaa;
+ return iter->this;
+}
+
+TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter)
+{
+ if (iter->this!=NULL) {
+ iter->this=iter->this->next;
+ }
+ return iter->this;
+}
}
/**
+ * Parse a signed integer
+ *
+ * If the key does not exist in the src object, returns success but does fill in *dest.
+ *
+ * @param src JSON object to pull a value from
+ * @param key key to pull
+ * @param dest (output) pointer to an allocated integer
+ * @return TR_CFG_SUCCESS or an error code
+ */
+static TR_CFG_RC tr_cfg_parse_integer(json_t *src, const char *key, int *dest)
+{
+ json_t *jtmp;
+
+ /* Validate parameters */
+ if ((src == NULL) || (key == NULL) || (dest == NULL))
+ return TR_CFG_BAD_PARAMS;
+
+ /* See if we have a value for this key; do nothing if not */
+ jtmp = json_object_get(src, key);
+ if (jtmp) {
+ if (json_is_number(jtmp)) {
+ *dest = (int) json_integer_value(jtmp);
+ } else {
+ tr_debug("tr_cfg_parse_unsigned: Parsing error, %s is not a number.", key);
+ return TR_CFG_NOPARSE;
+ }
+ }
+
+ return TR_CFG_SUCCESS;
+}
+
+/**
* Parse an unsigned integer
*
* If the key does not exist in the src object, returns success but does fill in *dest.
cfg->max_tree_depth = TR_DEFAULT_MAX_TREE_DEPTH;
cfg->tids_port = TR_DEFAULT_TIDS_PORT;
cfg->trps_port = TR_DEFAULT_TRPS_PORT;
- cfg->monitoring_port = TR_DEFAULT_MONITORING_PORT;
+ cfg->mons_port = TR_DEFAULT_MONITORING_PORT;
cfg->cfg_poll_interval = TR_CFGWATCH_DEFAULT_POLL;
cfg->cfg_settling_time = TR_CFGWATCH_DEFAULT_SETTLE;
cfg->trp_connect_interval = TR_DEFAULT_TRP_CONNECT_INTERVAL;
NOPARSE_UNLESS(tr_cfg_parse_boolean(jmon, "enabled", &enabled));
if (enabled) {
- NOPARSE_UNLESS(tr_cfg_parse_unsigned(jmon, "port", &(trc->internal->monitoring_port)));
+ NOPARSE_UNLESS(tr_cfg_parse_integer(jmon, "port", &(trc->internal->mons_port)));
NOPARSE_UNLESS(tr_cfg_parse_gss_names(trc->internal,
json_object_get(jmon, "authorized_credentials"),
&(trc->internal->monitoring_credentials)));
talloc_steal(trc->internal, trc->internal->hostname);
NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "max_tree_depth", &(trc->internal->max_tree_depth)));
- NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "tids_port", &(trc->internal->tids_port)));
- NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "trps_port", &(trc->internal->trps_port)));
+ NOPARSE_UNLESS(tr_cfg_parse_integer(jint, "tids_port", &(trc->internal->tids_port)));
+ NOPARSE_UNLESS(tr_cfg_parse_integer(jint, "trps_port", &(trc->internal->trps_port)));
NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "cfg_poll_interval", &(trc->internal->cfg_poll_interval)));
NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "cfg_settling_time", &(trc->internal->cfg_settling_time)));
NOPARSE_UNLESS(tr_cfg_parse_unsigned(jint, "trp_connect_interval", &(trc->internal->trp_connect_interval)));
#include <tr_idp.h>
#include <tr.h>
#include <trust_router/trp.h>
+#include <tr_util.h>
+#include <tr_inet_util.h>
#if JANSSON_VERSION_HEX < 0x020500
#include "jansson_iterators.h"
{
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
json_t *jhost=NULL;
- json_t *jport=NULL;
json_t *jgss=NULL;
json_t *jfilt=NULL;
TRP_PEER *new_peer=NULL;
TR_GSS_NAMES *names=NULL;
TR_FILTER_SET *filt_set=NULL;
TR_CFG_RC rc=TR_CFG_ERROR;
+ char *hostname=NULL;
+ int port;
jhost=json_object_get(jporg, "hostname");
- jport=json_object_get(jporg, "port");
jgss=json_object_get(jporg, "gss_names");
jfilt=json_object_get(jporg, "filters");
goto cleanup;
}
- if ((jport!=NULL) && (!json_is_number(jport))) {
- /* note that not specifying the port is allowed, but if set it must be a number */
- tr_err("tr_cfg_parse_one_peer_org: port is not a number.");
- rc=TR_CFG_NOPARSE;
- goto cleanup;
- }
-
if ((jgss==NULL) || (!json_is_array(jgss))) {
tr_err("tr_cfg_parse_one_peer_org: gss_names not specified or not an array.");
rc=TR_CFG_NOPARSE;
goto cleanup;
}
- trp_peer_set_server(new_peer, json_string_value(jhost)); /* string is strdup'ed in _set_server() */
- if (jport==NULL)
- trp_peer_set_port(new_peer, TRP_PORT);
- else
- trp_peer_set_port(new_peer, json_integer_value(jport));
+ /* parse / validate the hostname and port */
+ hostname = tr_parse_host(tmp_ctx, json_string_value(jhost), &port);
+ if (NULL == hostname) {
+ tr_err("tr_cfg_parse_one_peer_org: error parsing hostname (%s)", json_string_value(jhost));
+ rc=TR_CFG_NOPARSE;
+ goto cleanup;
+ }
+
+ if (port < 0) {
+ tr_err("tr_cfg_parse_one_peer_org: invalid port (%s)", json_string_value(jhost));
+ rc=TR_CFG_NOPARSE;
+ goto cleanup;
+ }
+
+ if (port == 0)
+ port = TRP_PORT;
+ trp_peer_set_port(new_peer, port);
+
+ trp_peer_set_server(new_peer, hostname); /* string is strdup'ed in _set_server() */
+ if (trp_peer_get_server(new_peer) == NULL) {
+ tr_err("tr_cfg_parse_one_peer: could not set server hostname for new peer");
+ rc = TR_CFG_NOMEM;
+ goto cleanup;
+ }
rc = tr_cfg_parse_gss_names(tmp_ctx, jgss, &names);
if (rc!=TR_CFG_SUCCESS) {
TR_AAA_SERVER *tr_cfg_parse_one_aaa_server(TALLOC_CTX *mem_ctx, json_t *jaddr, TR_CFG_RC *rc)
{
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
TR_AAA_SERVER *aaa = NULL;
- TR_NAME *name=NULL;
if ((!jaddr) || (!json_is_string(jaddr))) {
tr_debug("tr_cfg_parse_one_aaa_server: Bad parameters.");
*rc = TR_CFG_BAD_PARAMS;
- return NULL;
+ goto cleanup;
}
- name=tr_new_name(json_string_value(jaddr));
- if (name==NULL) {
- tr_debug("tr_cfg_parse_one_aaa_server: Out of memory allocating hostname.");
+ aaa = tr_aaa_server_from_string(mem_ctx, json_string_value(jaddr));
+ if (aaa == NULL) {
+ tr_debug("tr_cfg_parse_one_aaa_server: Out of memory allocating AAA server.");
*rc = TR_CFG_NOMEM;
- return NULL;
+ goto cleanup;
}
- aaa=tr_aaa_server_new(mem_ctx, name);
- if (aaa==NULL) {
- tr_free_name(name);
- tr_debug("tr_cfg_parse_one_aaa_server: Out of memory allocating AAA server.");
- *rc = TR_CFG_NOMEM;
- return NULL;
+ if (tr_aaa_server_get_hostname(aaa)->len == 0) {
+ tr_debug("tr_cfg_parse_one_aaa_server: Invalid hostname for AAA server (%s)",
+ json_string_value(jaddr));
+ *rc = TR_CFG_NOPARSE;
+ goto cleanup;
+ }
+
+ if ((tr_aaa_server_get_port(aaa) <= 0)
+ || (tr_aaa_server_get_port(aaa) > 65535)) {
+ tr_debug("tr_cfg_parse_one_aaa_server: Invalid AAA server port (%s)",
+ json_string_value(jaddr));
+ *rc = TR_CFG_NOPARSE;
+ goto cleanup;
}
+ /* success ! */
+ *rc = TR_CFG_SUCCESS;
+ talloc_steal(mem_ctx, aaa);
+
+cleanup:
+ if (*rc != TR_CFG_SUCCESS)
+ aaa = NULL;
+ talloc_free(tmp_ctx);
return aaa;
}
#include <tr_filter.h>
#include <trp_internal.h>
#include <tid_internal.h>
+#include <tr_inet_util.h>
#include <tr_debug.h>
/* Function types for handling filter fields generally. All target values
return tr_dup_name(trp_inforec_get_owner_realm(target->trp_inforec));
}
+/** Generic handlers for host:port fields*/
+static TR_NAME *tr_ff_get_hostname_and_port(TR_NAME *hn, int port)
+{
+ return tr_hostname_and_port_to_name(hn, port);
+}
+
+static int tr_ff_cmp_hostname_and_port(TR_NAME *hn, int port, int default_port, TR_NAME *val)
+{
+ int cmp = -1;
+ TR_NAME *n = NULL;
+
+ /* allow a match without :port if the default port is in use */
+ if ((port == default_port) && (tr_name_cmp(hn, val) == 0))
+ return 0;
+
+ /* need to match with the :port */
+ n = tr_ff_get_hostname_and_port(hn, port);
+
+ if (n) {
+ cmp = tr_name_cmp(n, val);
+ tr_free_name(n);
+ }
+ return cmp;
+}
+
/** Handlers for TRP trust_router field */
static int tr_ff_cmp_trp_trust_router(TR_FILTER_TARGET *target, TR_NAME *val)
{
- return tr_name_cmp(trp_inforec_get_trust_router(target->trp_inforec), val);
+ return tr_ff_cmp_hostname_and_port(trp_inforec_get_trust_router(target->trp_inforec),
+ trp_inforec_get_trust_router_port(target->trp_inforec),
+ TRP_PORT,
+ val);
}
static TR_NAME *tr_ff_get_trp_trust_router(TR_FILTER_TARGET *target)
{
- return tr_dup_name(trp_inforec_get_trust_router(target->trp_inforec));
+ return tr_ff_get_hostname_and_port(trp_inforec_get_trust_router(target->trp_inforec),
+ trp_inforec_get_trust_router_port(target->trp_inforec));
+}
+
+/** Handlers for TRP next_hop field */
+static int tr_ff_cmp_trp_next_hop(TR_FILTER_TARGET *target, TR_NAME *val)
+{
+ return tr_ff_cmp_hostname_and_port(trp_inforec_get_next_hop(target->trp_inforec),
+ trp_inforec_get_next_hop_port(target->trp_inforec),
+ TID_PORT,
+ val);
+}
+
+static TR_NAME *tr_ff_get_trp_next_hop(TR_FILTER_TARGET *target)
+{
+ return tr_ff_get_hostname_and_port(trp_inforec_get_next_hop(target->trp_inforec),
+ trp_inforec_get_next_hop_port(target->trp_inforec));
}
/** Handlers for TRP owner_contact field */
{TR_FILTER_TYPE_TRP_INBOUND, "trust_router", tr_ff_cmp_trp_trust_router, tr_ff_get_trp_trust_router},
{TR_FILTER_TYPE_TRP_OUTBOUND, "trust_router", tr_ff_cmp_trp_trust_router, tr_ff_get_trp_trust_router},
+ /* next_hop */
+ {TR_FILTER_TYPE_TRP_INBOUND, "next_hop", tr_ff_cmp_trp_next_hop, tr_ff_get_trp_next_hop},
+ {TR_FILTER_TYPE_TRP_OUTBOUND, "next_hop", tr_ff_cmp_trp_next_hop, tr_ff_get_trp_next_hop},
+
/* owner_realm */
{TR_FILTER_TYPE_TRP_INBOUND, "owner_realm", tr_ff_cmp_trp_owner_realm, tr_ff_get_trp_owner_realm},
{TR_FILTER_TYPE_TRP_OUTBOUND, "owner_realm", tr_ff_cmp_trp_owner_realm, tr_ff_get_trp_owner_realm},
* @param port TCP port to connect
* @return 0 on success, -1 on failure
*/
-int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, unsigned int port)
+int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, int port)
{
+ if ((port <= 0) || (port > 65535)) {
+ tr_err("tr_gssc_open_connection: invalid port requested (%d)", port);
+ return -1;
+ }
+
tr_debug("tr_gssc_open_connection: opening connection to %s:%d", server, port);
- if (0 != gsscon_connect(server, port, gssc->service_name, &(gssc->conn), gssc->gss_ctx))
+ if (0 != gsscon_connect(server, (unsigned int) port, gssc->service_name, &(gssc->conn), gssc->gss_ctx))
return -1;
return 0; /* success */
#include <talloc.h>
#include <time.h>
+#include <tr_aaa_server.h>
#include <tr_name_internal.h>
#include <tr_idp.h>
#include <tr_config.h>
#include <tr_debug.h>
-static int tr_aaa_server_destructor(void *obj)
-{
- TR_AAA_SERVER *aaa=talloc_get_type_abort(obj, TR_AAA_SERVER);
- if (aaa->hostname!=NULL)
- tr_free_name(aaa->hostname);
- return 0;
-}
-
-TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx, TR_NAME *hostname)
-{
- TR_AAA_SERVER *aaa=talloc(mem_ctx, TR_AAA_SERVER);
- if (aaa!=NULL) {
- aaa->next=NULL;
- aaa->hostname=hostname;
- talloc_set_destructor((void *)aaa, tr_aaa_server_destructor);
- }
- return aaa;
-}
-
-void tr_aaa_server_free(TR_AAA_SERVER *aaa)
-{
- talloc_free(aaa);
-}
-
-TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx)
-{
- return talloc(mem_ctx, TR_AAA_SERVER_ITER);
-}
-
-void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter)
-{
- talloc_free(iter);
-}
-
-TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa)
-{
- iter->this=aaa;
- return iter->this;
-}
-
-TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter)
-{
- if (iter->this!=NULL) {
- iter->this=iter->this->next;
- }
- return iter->this;
-}
-
-
/* fills in shared if pointer not null */
TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_IDP_REALM *idp_realms, TR_NAME *idp_realm_name, TR_NAME *comm, int *shared_out)
{
static char *tr_aaa_server_to_str(TALLOC_CTX *mem_ctx, TR_AAA_SERVER *aaa)
{
- return talloc_strndup(mem_ctx, aaa->hostname->buf, aaa->hostname->len);
+ char *aaa_hostname = tr_name_strdup( tr_aaa_server_get_hostname(aaa) );
+ char *result = NULL;
+
+ if (aaa_hostname == NULL)
+ return NULL;
+
+ result = talloc_asprintf(mem_ctx,
+ "%s:%d",
+ aaa_hostname,
+ tr_aaa_server_get_port(aaa));
+ free(aaa_hostname);
+ return result;
}
static json_t *tr_aaa_server_to_json(TR_AAA_SERVER *aaa)
{
- char *hostname = tr_name_strdup(aaa->hostname);
- char *s = NULL;
+ char *s = tr_aaa_server_to_str(NULL, aaa);
json_t *jstr = NULL;
- if (hostname == NULL)
- return NULL;
-
- s = talloc_asprintf(NULL, "%s:%d", hostname, TID_PORT);
if (s) {
jstr = json_string(s);
talloc_free(s);
--- /dev/null
+/*
+ * Copyright (c) 2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <tr_name_internal.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <talloc.h>
+
+#include <tr_inet_util.h>
+
+/**
+ * Determine whether a string is a valid address of a given family
+ *
+ * @param s string to check
+ * @param af address family (probably AF_INET or AF_INET6)
+ * @return 1 if string is a valid address in the given family, 0 if not, -1 on error (errno set)
+ */
+static int is_valid_address(int af, const char *s)
+{
+ unsigned char buf[sizeof(struct in6_addr)];
+
+ if (s == NULL)
+ return 0;
+ return inet_pton(af, s, buf);
+}
+
+/**
+ * Determine whether a string is a valid IPv6 address reference
+ *
+ * I.e., an IPv6 address in brackets
+ *
+ * @param s string to validate
+ * @return 1 if a valid reference, 0 otherwise
+ */
+static int tr_valid_ipv6_reference(const char *s)
+{
+ char *cpy;
+ size_t len;
+ int valid_ipv6;
+
+ /* check that it starts with an open bracket */
+ if (*s != '[')
+ return 0;
+
+ /* check that it ends with a close bracket */
+ len = strlen(s);
+ if (*(s+len-1) != ']')
+ return 0;
+
+ /* make a null-terminated copy of the string omitting the brackets */
+ cpy = talloc_strndup(NULL, s+1, len-2);
+ if (cpy == NULL)
+ return 0; /* an error occurred - fail safe */
+
+ valid_ipv6 = is_valid_address(AF_INET6, cpy);
+ talloc_free(cpy);
+
+ return valid_ipv6;
+}
+
+/**
+ * Validate a host string
+ *
+ * The intention is to reject strings that may appear to contain a ':port' spec.
+ * Takes a permissive view of valid: a hostname is valid if either it is a
+ * bracketed IPv6 address reference ([address]) or has no brackets or colons.
+ * This accepts all valid DNS names and IPv4 addresses, as well as many invalid
+ * hostnames. This is ok for accepting a hostname that will later be resolved
+ * because invalid names will fail to resolve. It should *not* be used to ensure
+ * a hostname is compliant with RFC!
+ *
+ * Ignores a trailing colon followed by decimal digits.
+ *
+ * @param s string to validate
+ * @return 1 if a valid host specification, 0 otherwise
+ */
+static int tr_valid_host(const char *s)
+{
+ if (strchr(s, '[') || strchr(s, ']') || strchr(s, ':'))
+ return tr_valid_ipv6_reference(s);
+
+ return 1;
+}
+
+/**
+ * Check that all characters are decimal digits
+ *
+ * @param s
+ * @return 1 if all digits, 0 otherwise
+ */
+static int tr_str_all_digits(const char *s)
+{
+ if (s == NULL)
+ return 0;
+
+ for( ; *s; s++) {
+ if ( (*s < '0') || (*s > '9'))
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Validate and parse a hostname or hostname/port
+ *
+ * If port_out is not null, accepts a port as well. This is
+ * stored in *port_out. If no port is given, a 0 is stored.
+ * If an invalid port is given, -1 is stored.
+ *
+ * If the hostname is invalid, null is returned and no value
+ * is written to *port_out.
+ *
+ * If port_out is null, null will be returned if the string
+ * contains a port.
+ *
+ * The return value must be freed with talloc_free unless
+ * it is null.
+ *
+ * @param mem_ctx talloc context for hostname result
+ * @param s string to parse
+ * @param port_out pointer to an allocated integer, or NULL
+ * @return pointer to the hostname or null on error
+ */
+char *tr_parse_host(TALLOC_CTX *mem_ctx, const char *s, int *port_out)
+{
+ const char *colon;
+ char *hostname;
+ long int port;
+
+ if (s == NULL)
+ return NULL;
+
+ /* If we are accepting a port, find the last colon. */
+ if (port_out == NULL)
+ colon = NULL;
+ else
+ colon = strrchr(s, ':');
+
+ /* Get a copy of the hostname portion, which may be the entire string. */
+ if (colon == NULL)
+ hostname = talloc_strdup(NULL, s);
+ else
+ hostname = talloc_strndup(NULL, s, colon-s);
+
+ if (hostname == NULL)
+ return NULL; /* failed to dup the hostname */
+
+ /* Check that the hostname is valid; if not, return null and ignore the port. */
+ if (! tr_valid_host(hostname)) {
+ talloc_free(hostname);
+ return NULL;
+ }
+
+ /* If we are accepting a port, parse and validate it. */
+ if (port_out != NULL) {
+ if (colon == NULL) {
+ *port_out = 0;
+ } else {
+ port = strtol(colon+1, NULL, 10);
+ if (tr_str_all_digits(colon+1) && (port > 0) && (port <= 65535))
+ *port_out = (int) port;
+ else
+ *port_out = -1;
+ }
+ }
+
+ return hostname;
+}
+
+TR_NAME *tr_hostname_and_port_to_name(TR_NAME *hn, int port)
+{
+ TR_NAME *retval = NULL;
+ char *s = NULL;
+ char *hn_s = tr_name_strdup(hn);
+
+ if (!hn_s)
+ return NULL;
+
+ s = talloc_asprintf(NULL, "%s:%d", hn_s, port);
+ free(hn_s);
+
+ if (s) {
+ retval = tr_new_name(s);
+ talloc_free(s);
+ }
+
+ return retval;
+}
\ No newline at end of file
#include <trp_internal.h>
#include <mon_internal.h>
#include <tr_msg.h>
+#include <tr_util.h>
#include <tr_name_internal.h>
#include <trust_router/tr_constraint.h>
#include <trust_router/tr_dh.h>
#include <tr_debug.h>
+#include <tr_inet_util.h>
/* JSON helpers */
-/* Read attribute attr from msg as an integer. Returns nonzero on error. */
-static int tr_msg_get_json_integer(json_t *jmsg, const char *attr, int *dest)
+/* Read attribute attr from msg as an integer. */
+static TRP_RC tr_msg_get_json_integer(json_t *jmsg, const char *attr, int *dest)
{
json_t *obj;
obj=json_object_get(jmsg, attr);
if (obj == NULL) {
- return -1;
+ return TRP_MISSING;
}
/* check type */
if (!json_is_integer(obj)) {
- return -1;
+ return TRP_BADTYPE;
}
(*dest)=json_integer_value(obj);
- return 0;
+ return TRP_SUCCESS;
}
/* Read attribute attr from msg as a string. Copies string into mem_ctx context so jmsg can
obj=json_object_get(jmsg, attr);
if (obj == NULL)
- return TRP_ERROR;
+ return TRP_MISSING;
/* check type */
if (!json_is_string(obj))
- return TRP_ERROR;
+ return TRP_BADTYPE;
*dest=talloc_strdup(mem_ctx, json_string_value(obj));
if (*dest==NULL)
- return TRP_ERROR;
+ return TRP_NOMEM;
return TRP_SUCCESS;
}
return tresp;
}
+static json_t *hostname_and_port_to_json(TR_NAME *hostname, int port)
+{
+ char *s_hostname = tr_name_strdup(hostname);
+ char *s;
+ json_t *j;
+
+ if (s_hostname == NULL)
+ return NULL;
+
+ s = talloc_asprintf(NULL, "%s:%d", s_hostname, port);
+ free(s_hostname);
+
+ if (s == NULL)
+ return NULL;
+
+ j = json_string(s);
+ talloc_free(s);
+
+ return j;
+}
-/* Information records for TRP update msg
+/* Information records for TRP update msg
* requires that jrec already be allocated */
static TRP_RC tr_msg_encode_inforec_route(json_t *jrec, TRP_INFOREC *rec)
{
json_t *jstr=NULL;
json_t *jint=NULL;
- char *s=NULL;
if (rec==NULL)
return TRP_BADTYPE;
if (trp_inforec_get_trust_router(rec)==NULL)
return TRP_ERROR;
- s=tr_name_strdup(trp_inforec_get_trust_router(rec));
- if (s==NULL)
- return TRP_NOMEM;
- jstr=json_string(s);
- free(s);s=NULL;
+ jstr=hostname_and_port_to_json(trp_inforec_get_trust_router(rec),
+ trp_inforec_get_trust_router_port(rec));
if(jstr==NULL)
- return TRP_ERROR;
+ return TRP_NOMEM;
json_object_set_new(jrec, "trust_router", jstr);
+ jstr=hostname_and_port_to_json(trp_inforec_get_next_hop(rec),
+ trp_inforec_get_next_hop_port(rec));
+ if(jstr==NULL)
+ return TRP_NOMEM;
+ json_object_set_new(jrec, "next_hop", jstr);
+
jint=json_integer(trp_inforec_get_metric(rec));
if(jint==NULL)
return TRP_ERROR;
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
TRP_RC rc=TRP_ERROR;
char *s=NULL;
+ TR_NAME *name;
+ char *hostname;
+ int port;
int num=0;
+ /* get the trust router */
rc=tr_msg_get_json_string(jrecord, "trust_router", &s, tmp_ctx);
if (rc != TRP_SUCCESS)
goto cleanup;
- if (TRP_SUCCESS!=trp_inforec_set_trust_router(rec, tr_new_name(s))) {
+
+ hostname = tr_parse_host(tmp_ctx, s, &port);
+ if ((NULL == hostname)
+ || (NULL == (name = tr_new_name(hostname)))
+ || (port < 0)) {
+ rc = TRP_ERROR;
+ goto cleanup;
+ }
+ talloc_free(s); s=NULL;
+ talloc_free(hostname);
+
+ if (port == 0)
+ port = TRP_PORT;
+
+ if (TRP_SUCCESS!= trp_inforec_set_trust_router(rec, name, port)) {
rc=TRP_ERROR;
goto cleanup;
}
+
+ /* Now do the next hop. If it's not present, use the trust_router for backward
+ * compatibility */
+ switch(tr_msg_get_json_string(jrecord, "next_hop", &s, tmp_ctx)) {
+ case TRP_SUCCESS:
+ /* we got a next_hop field */
+ hostname = tr_parse_host(tmp_ctx, s, &port);
+ if ((hostname == NULL)
+ || (NULL == (name = tr_new_name(hostname)))
+ || (port < 0)) {
+ rc = TRP_ERROR;
+ goto cleanup;
+ }
+ break;
+
+ case TRP_MISSING:
+ /* no next_hop field; use the trust router */
+ name = tr_dup_name(trp_inforec_get_trust_router(rec));
+ if (name == NULL) {
+ rc = TRP_ERROR;
+ goto cleanup;
+ }
+ break;
+
+ default:
+ /* something went wrong */
+ rc = TRP_ERROR;
+ goto cleanup;
+ }
talloc_free(s); s=NULL;
- trp_inforec_set_next_hop(rec, NULL); /* make sure this is null (filled in later) */
+ if (port == 0)
+ port = TID_PORT;
+
+ if (TRP_SUCCESS!= trp_inforec_set_next_hop(rec, name, port)) {
+ rc=TRP_ERROR;
+ goto cleanup;
+ }
rc=tr_msg_get_json_integer(jrecord, "metric", &num);
if ((rc != TRP_SUCCESS) || (TRP_SUCCESS!=trp_inforec_set_metric(rec,num)))
* @param max_fd maximum number of file descriptors to write
* @return number of file descriptors written into the output array
*/
-nfds_t tr_sock_listen_all(unsigned int port, int *fd_out, nfds_t max_fd)
+nfds_t tr_sock_listen_all(int port, int *fd_out, nfds_t max_fd)
{
int rc = 0;
int conn = -1;
return NULL;
}
return dst;
-}
\ No newline at end of file
+}
/* Monitoring server instance */
struct mons_instance {
const char *hostname;
- unsigned int port;
+ int mon_port;
TR_GSS_NAMES *authorized_gss_names;
TIDS_INSTANCE *tids;
TRPS_INSTANCE *trps;
/* mons.c */
MONS_INSTANCE *mons_new(TALLOC_CTX *mem_ctx);
-int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH_FUNC *auth_handler, const char *hostname,
- unsigned int port, void *cookie, int *fd_out, size_t max_fd);
+int mons_get_listener(MONS_INSTANCE *mons,
+ MONS_REQ_FUNC *req_handler,
+ MONS_AUTH_FUNC *auth_handler,
+ const char *hostname,
+ int port,
+ void *cookie,
+ int *fd_out,
+ size_t max_fd);
int mons_accept(MONS_INSTANCE *mons, int listen);
/* monc.c */
MONC_INSTANCE *monc_new(TALLOC_CTX *mem_ctx);
void monc_free(MONC_INSTANCE *monc);
-int monc_open_connection(MONC_INSTANCE *monc, const char *server, unsigned int port);
+int monc_open_connection(MONC_INSTANCE *monc, const char *server, int port);
MON_RESP *monc_send_request(TALLOC_CTX *mem_ctx, MONC_INSTANCE *monc, MON_REQ *req);
#endif //TRUST_ROUTER_MON_REQ_H
TIDS_REQ_FUNC *req_handler;
tids_auth_func *auth_handler;
void *cookie;
- unsigned int tids_port;
+ int tids_port;
TR_NAME *gss_name; /* GSS name client used for authentication */
GArray *pids; /* PIDs of active tids processes */
};
reference they already hold to the TID_REQ.*/
void tid_req_cleanup_json(TID_REQ *, json_t *json);
-int tid_req_add_path(TID_REQ *, const char *this_system, unsigned port);
+int tid_req_add_path(TID_REQ *req, const char *this_system, int port);
TID_SRVR_BLK *tid_srvr_blk_new(TALLOC_CTX *mem_ctx);
void tid_srvr_blk_free(TID_SRVR_BLK *srvr);
--- /dev/null
+/*
+ * Copyright (c) 2012-2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TRUST_ROUTER_TR_AAA_SERVER_H
+#define TRUST_ROUTER_TR_AAA_SERVER_H
+
+#include <talloc.h>
+
+#include <tr_name_internal.h>
+
+typedef struct tr_aaa_server {
+ struct tr_aaa_server *next;
+ TR_NAME *hostname;
+ int port;
+} TR_AAA_SERVER;
+
+typedef struct tr_aaa_server_iter {
+ TR_AAA_SERVER *this;
+} TR_AAA_SERVER_ITER;
+
+TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx);
+void tr_aaa_server_free(TR_AAA_SERVER *aaa);
+
+TR_NAME *tr_aaa_server_get_hostname(TR_AAA_SERVER *aaa);
+void tr_aaa_server_set_hostname(TR_AAA_SERVER *aaa, TR_NAME *hostname);
+int tr_aaa_server_get_port(TR_AAA_SERVER *aaa);
+void tr_aaa_server_set_port(TR_AAA_SERVER *aaa, int port);
+TR_AAA_SERVER *tr_aaa_server_from_string(TALLOC_CTX *mem_ctx, const char *s);
+
+TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx);
+void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter);
+TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa);
+TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter);
+
+#endif //TRUST_ROUTER_TR_AAA_SERVER_H
typedef struct tr_cfg_internal {
unsigned int max_tree_depth;
- unsigned int tids_port;
- unsigned int trps_port;
- unsigned int monitoring_port;
+ int tids_port;
+ int trps_port;
+ int mons_port;
const char *hostname;
int log_threshold;
int console_threshold;
/* tr_gss_client.c */
TR_GSSC_INSTANCE *tr_gssc_instance_new(TALLOC_CTX *mem_ctx);
void tr_gssc_instance_free(TR_GSSC_INSTANCE *tr_gssc);
-int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, unsigned int port);
+int tr_gssc_open_connection(TR_GSSC_INSTANCE *gssc, const char *server, int port);
TR_MSG *tr_gssc_exchange_msgs(TALLOC_CTX *mem_ctx, TR_GSSC_INSTANCE *gssc, TR_MSG *req_msg);
#endif //TRUST_ROUTER_TR_GSS_CLIENT_H
#include <time.h>
#include <tr_name_internal.h>
+#include <tr_aaa_server.h>
#include <tr_apc.h>
-typedef struct tr_aaa_server {
- struct tr_aaa_server *next;
- TR_NAME *hostname;
-} TR_AAA_SERVER;
-
-typedef struct tr_aaa_server_iter {
- TR_AAA_SERVER *this;
-} TR_AAA_SERVER_ITER;
-
/* may also want to use in tr_rp.h */
typedef enum tr_realm_origin {
TR_REALM_LOCAL=0, /* realm we were configured to contact */
int tr_idp_realm_aaa_server_count(TR_IDP_REALM *idp);
int tr_idp_realm_apc_count(TR_IDP_REALM *idp);
void tr_idp_realm_incref(TR_IDP_REALM *realm);
-void tr_idp_realm_decref(TR_IDP_REALM *realm);
-
-TR_AAA_SERVER *tr_aaa_server_new(TALLOC_CTX *mem_ctx, TR_NAME *hostname);
-void tr_aaa_server_free(TR_AAA_SERVER *aaa);
-
-TR_AAA_SERVER_ITER *tr_aaa_server_iter_new(TALLOC_CTX *mem_ctx);
-void tr_aaa_server_iter_free(TR_AAA_SERVER_ITER *iter);
-TR_AAA_SERVER *tr_aaa_server_iter_first(TR_AAA_SERVER_ITER *iter, TR_AAA_SERVER *aaa);
-TR_AAA_SERVER *tr_aaa_server_iter_next(TR_AAA_SERVER_ITER *iter);
+void tr_idp_realm_decref(TR_IDP_REALM *realm);
TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_IDP_REALM *idp_realms, TR_NAME *idp_realm_name, TR_NAME *comm, int *shared_out);
TR_AAA_SERVER *tr_default_server_lookup(TR_AAA_SERVER *default_servers, TR_NAME *comm);
--- /dev/null
+/*
+ * Copyright (c) 2018, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TRUST_ROUTER_TR_INET_UTIL_H
+#define TRUST_ROUTER_TR_INET_UTIL_H
+
+#include <arpa/inet.h>
+#include <tr_name_internal.h>
+
+char *tr_parse_host(TALLOC_CTX *mem_ctx, const char *s, int *port_out);
+
+TR_NAME *tr_hostname_and_port_to_name(TR_NAME *hn, int port);
+
+#endif //TRUST_ROUTER_TR_INET_UTIL_H
#include <poll.h> // for nfds_t
#include <sys/socket.h>
-nfds_t tr_sock_listen_all(unsigned int port, int *fd_out, nfds_t max_fd);
+nfds_t tr_sock_listen_all(int port, int *fd_out, nfds_t max_fd);
int tr_sock_accept(int sock);
#endif //TRUST_ROUTER_TR_SOCKET_H
#ifndef TR_UTIL_H
#define TR_UTIL_H
+#include <stddef.h>
#include <trust_router/tr_versioning.h>
/* NB, tr_bin_to_hex() is also prototyped in trust_router/tr_dh.h */
/* TRP update record types */
typedef struct trp_inforec_route {
TR_NAME *trust_router;
+ int trust_router_port;
TR_NAME *next_hop;
- unsigned int next_hop_port;
+ int next_hop_port;
unsigned int metric;
unsigned int interval;
} TRP_INFOREC_ROUTE;
TRPC_INSTANCE *next;
TR_NAME *gssname;
char *server;
- unsigned int port;
+ int port;
TRP_CONNECTION *conn;
TR_MQ *mq; /* msgs from master to trpc */
};
/* TRP Server Instance Data */
struct trps_instance {
char *hostname;
- unsigned int port;
+ int trps_port;
+ int tids_port; /* used for route advertisements; must agree with our tids configuration */
TRP_AUTH_FUNC auth_handler;
TRPS_MSG_FUNC msg_handler;
void *cookie;
void trp_connection_append(TRP_CONNECTION *conn, TRP_CONNECTION *new);
int trp_connection_auth(TRP_CONNECTION *conn, TRP_AUTH_FUNC auth_callback, void *callback_data);
TRP_CONNECTION *trp_connection_accept(TALLOC_CTX *mem_ctx, int listen, TR_NAME *gss_servicename);
-TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, unsigned int port);
+TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, int port);
TRPC_INSTANCE *trpc_new (TALLOC_CTX *mem_ctx);
void trpc_free (TRPC_INSTANCE *trpc);
TR_NAME *trpc_get_gssname(TRPC_INSTANCE *trpc);
void trpc_set_gssname(TRPC_INSTANCE *trpc, TR_NAME *gssname);
unsigned int trpc_get_port(TRPC_INSTANCE *trpc);
-void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port);
+void trpc_set_port(TRPC_INSTANCE *trpc, int port);
TRP_CONNECTION_STATUS trpc_get_status(TRPC_INSTANCE *trpc);
TR_MQ *trpc_get_mq(TRPC_INSTANCE *trpc);
void trpc_set_mq(TRPC_INSTANCE *trpc, TR_MQ *mq);
TRPS_MSG_FUNC msg_handler,
TRP_AUTH_FUNC auth_handler,
const char *hostname,
- unsigned int port,
+ int port,
void *cookie,
int *fd_out,
size_t max_fd);
TR_NAME *trp_inforec_dup_realm(TRP_INFOREC *rec);
TRP_RC trp_inforec_set_realm(TRP_INFOREC *rec, TR_NAME *realm);
TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec);
+int trp_inforec_get_trust_router_port(TRP_INFOREC *rec);
TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router);
+TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router, int port);
TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec);
+int trp_inforec_get_next_hop_port(TRP_INFOREC *rec);
TR_NAME *trp_inforec_dup_next_hop(TRP_INFOREC *rec);
-TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop);
+TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop, int port);
unsigned int trp_inforec_get_metric(TRP_INFOREC *rec);
TRP_RC trp_inforec_set_metric(TRP_INFOREC *rec, unsigned int metric);
unsigned int trp_inforec_get_interval(TRP_INFOREC *rec);
char *server;
TR_GSS_NAMES *gss_names;
TR_NAME *servicename;
- unsigned int port;
+ int port;
unsigned int linkcost;
struct timespec last_conn_attempt;
TRP_PEER_CONN_STATUS outgoing_status;
TR_GSS_NAMES *trp_peer_get_gss_names(TRP_PEER *peer);
TR_NAME *trp_peer_get_servicename(TRP_PEER *peer);
TR_NAME *trp_peer_dup_servicename(TRP_PEER *peer);
-unsigned int trp_peer_get_port(TRP_PEER *peer);
-void trp_peer_set_port(TRP_PEER *peer, unsigned int port);
+int trp_peer_get_port(TRP_PEER *peer);
+void trp_peer_set_port(TRP_PEER *peer, int port);
unsigned int trp_peer_get_linkcost(TRP_PEER *peer);
struct timespec *trp_peer_get_last_conn_attempt(TRP_PEER *peer);
void trp_peer_set_last_conn_attempt(TRP_PEER *peer, struct timespec *time);
TR_NAME *peer;
unsigned int metric;
TR_NAME *trust_router; /* hostname */
- unsigned int trp_port;
- unsigned int tid_port;
+ int trust_router_port;
TR_NAME *next_hop;
+ int next_hop_port;
int selected;
unsigned int interval; /* interval from route update */
struct timespec *expiry;
void trp_route_set_trust_router(TRP_ROUTE *entry, TR_NAME *tr);
TR_NAME *trp_route_get_trust_router(TRP_ROUTE *entry);
TR_NAME *trp_route_dup_trust_router(TRP_ROUTE *entry);
+void trp_route_set_trust_router_port(TRP_ROUTE *entry, int port);
+int trp_route_get_trust_router_port(TRP_ROUTE *entry);
void trp_route_set_peer(TRP_ROUTE *entry, TR_NAME *peer);
TR_NAME *trp_route_get_peer(TRP_ROUTE *entry);
TR_NAME *trp_route_dup_peer(TRP_ROUTE *entry);
void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop);
TR_NAME *trp_route_get_next_hop(TRP_ROUTE *entry);
TR_NAME *trp_route_dup_next_hop(TRP_ROUTE *entry);
+void trp_route_set_next_hop_port(TRP_ROUTE *entry, int port);
+int trp_route_get_next_hop_port(TRP_ROUTE *entry);
void trp_route_set_selected(TRP_ROUTE *entry, int sel);
int trp_route_is_selected(TRP_ROUTE *entry);
void trp_route_set_interval(TRP_ROUTE *entry, int interval);
/* TID Client functions, in tid/tidc.c */
TR_EXPORT TIDC_INSTANCE *tidc_create (void);
-TR_EXPORT int tidc_open_connection (TIDC_INSTANCE *tidc, const char *server, unsigned int port, gss_ctx_id_t *gssctx);
+TR_EXPORT int tidc_open_connection(TIDC_INSTANCE *tidc, const char *server, int port, gss_ctx_id_t *gssctx);
TR_EXPORT int tidc_send_request (TIDC_INSTANCE *tidc, int conn, gss_ctx_id_t gssctx, const char *rp_realm, const char *realm, const char *coi, TIDC_RESP_FUNC *resp_handler, void *cookie);
TR_EXPORT int tidc_fwd_request (TIDC_INSTANCE *tidc, TID_REQ *req, TIDC_RESP_FUNC *resp_handler, void *cookie);
TR_EXPORT DH *tidc_get_dh(TIDC_INSTANCE *);
/* TID Server functions, in tid/tids.c */
TIDS_INSTANCE *tids_new(TALLOC_CTX *mem_ctx);
TR_EXPORT TIDS_INSTANCE *tids_create (void);
-TR_EXPORT int tids_start (TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
- tids_auth_func *auth_handler, const char *hostname,
- unsigned int port, void *cookie);
+TR_EXPORT int tids_start(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
+ tids_auth_func *auth_handler, const char *hostname,
+ int port, void *cookie);
TR_EXPORT nfds_t tids_get_listener(TIDS_INSTANCE *tids, TIDS_REQ_FUNC *req_handler,
tids_auth_func *auth_handler, const char *hostname,
- unsigned int port, void *cookie, int *fd_out, size_t max_fd);
+ int port, void *cookie, int *fd_out, size_t max_fd);
TR_EXPORT int tids_accept(TIDS_INSTANCE *tids, int listen);
TR_EXPORT int tids_send_response (TIDS_INSTANCE *tids, TID_REQ *req, TID_RESP *resp);
TR_EXPORT int tids_send_err_response (TIDS_INSTANCE *tids, TID_REQ *req, const char *err_msg);
TRP_UNSUPPORTED, /* unsupported feature */
TRP_BADARG, /* bad argument */
TRP_CLOCKERR, /* error reading time */
+ TRP_MISSING, /* value not present */
} TRP_RC;
typedef enum trp_inforec_type {
TR_EXPORT TR_NAME *trp_upd_get_peer(TRP_UPD *upd);
TR_NAME *trp_upd_dup_peer(TRP_UPD *upd);
void trp_upd_set_peer(TRP_UPD *upd, TR_NAME *peer);
-void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port);
+void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, int port);
void trp_upd_add_to_provenance(TRP_UPD *upd, TR_NAME *name);
/* Functions for TRP_REQ structures */
int monc_open_connection(MONC_INSTANCE *monc,
const char *server,
- unsigned int port)
+ int port)
{
return tr_gssc_open_connection(monc->gssc, server, port);
}
if (mons) {
mons->hostname = NULL;
- mons->port = 0;
+ mons->mon_port = 0;
mons->tids = NULL;
mons->trps = NULL;
mons->req_handler = NULL;
* @param max_fd
* @return
*/
-int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH_FUNC *auth_handler, const char *hostname,
- unsigned int port, void *cookie, int *fd_out, size_t max_fd)
+int mons_get_listener(MONS_INSTANCE *mons,
+ MONS_REQ_FUNC *req_handler,
+ MONS_AUTH_FUNC *auth_handler,
+ const char *hostname,
+ int port,
+ void *cookie,
+ int *fd_out,
+ size_t max_fd)
{
size_t n_fd=0;
size_t ii=0;
- mons->port = port;
+ mons->mon_port = port;
n_fd = tr_sock_listen_all(port, fd_out, max_fd);
if (n_fd<=0)
tr_err("mons_get_listener: Error opening port %d", port);
}
int tid_req_add_path(TID_REQ *req,
- const char *this_system, unsigned port)
+ const char *this_system, int port)
{
char *path_element = talloc_asprintf(req, "%s:%u",
this_system, port);
talloc_free(tidc);
}
-int tidc_open_connection (TIDC_INSTANCE *tidc,
- const char *server,
- unsigned int port,
- gss_ctx_id_t *gssctx)
+int tidc_open_connection(TIDC_INSTANCE *tidc,
+ const char *server,
+ int port,
+ gss_ctx_id_t *gssctx)
{
- unsigned int use_port = 0;
+ int use_port = 0;
tidc->gssc->gss_ctx = gssctx;
if (0 == port)
TIDS_REQ_FUNC *req_handler,
tids_auth_func *auth_handler,
const char *hostname,
- unsigned int port,
+ int port,
void *cookie,
int *fd_out,
size_t max_fd)
}
/* Process tids requests forever. Should not return except on error. */
-int tids_start (TIDS_INSTANCE *tids,
- TIDS_REQ_FUNC *req_handler,
- tids_auth_func *auth_handler,
- const char *hostname,
- unsigned int port,
- void *cookie)
+int tids_start(TIDS_INSTANCE *tids,
+ TIDS_REQ_FUNC *req_handler,
+ tids_auth_func *auth_handler,
+ const char *hostname,
+ int port,
+ void *cookie)
{
int fd[TR_MAX_SOCKETS]={0};
nfds_t n_fd=0;
return 1;
}
+ /* tell the trps which port the tid server listens on */
+ tr->trps->tids_port = tr->tids->tids_port;
+
/* install TRP handler events */
tr_debug("Initializing Dynamic Trust Router Protocol events.");
if (TRP_SUCCESS != tr_trps_event_init(ev_base, tr)) {
goto cleanup;
}
- if (cfg_mgr->active->internal->monitoring_port == 0) {
+ if (cfg_mgr->active->internal->mons_port == 0) {
tr_notice("tr_mons_event_init: monitoring is disabled, not enabling events or opening sockets");
retval = 0;
goto cleanup;
mons_ev->n_sock_fd = mons_get_listener(mons, tr_mons_req_handler,
tr_mons_auth_handler,
cfg_mgr->active->internal->hostname,
- cfg_mgr->active->internal->monitoring_port,
+ cfg_mgr->active->internal->mons_port,
(void *) cookie, mons_ev->sock_fd,
TR_MAX_SOCKETS);
if (mons_ev->n_sock_fd==0) {
int thread_id;
pthread_mutex_t mutex; /* lock on the mq (separate from the locking within the mq, see below) */
TR_MQ *mq; /* messages from thread to main process; set to NULL to disable response */
- TR_NAME *aaa_hostname;
+ TR_AAA_SERVER *aaa; /* AAA server to contact */
DH *dh_params;
TID_REQ *fwd_req; /* the req to duplicate */
};
static int tr_tids_fwd_cookie_destructor(void *obj)
{
struct tr_tids_fwd_cookie *c=talloc_get_type_abort(obj, struct tr_tids_fwd_cookie);
- if (c->aaa_hostname!=NULL)
- tr_free_name(c->aaa_hostname);
if (c->dh_params!=NULL)
tr_destroy_dh_params(c->dh_params);
return 0;
TIDC_INSTANCE *tidc=tidc_create();
TR_MQ_MSG *msg=NULL;
TR_RESP_COOKIE *cookie=NULL;
+ char *aaa_hostname = NULL;
+ int aaa_port;
int rc=0;
int success=0;
/* create the cookie we will use for our response */
cookie=talloc(tmp_ctx, TR_RESP_COOKIE);
if (cookie==NULL) {
- tr_notice("tr_tids_req_fwd_thread: unable to allocate response cookie.");
+ tr_crit("tr_tids_req_fwd_thread: unable to allocate response cookie.");
success=0;
goto cleanup;
}
}
/* Set-up TID connection */
+ aaa_hostname = tr_name_strdup(tr_aaa_server_get_hostname(args->aaa));
+ if (aaa_hostname == NULL) {
+ tr_crit("tr_tids_req_fwd_thread: unable to allocate AAA hostname string");
+ success=0;
+ goto cleanup;
+ }
+ aaa_port = tr_aaa_server_get_port(args->aaa);
+ if ((aaa_port <= 0) || (aaa_port > 65535)) {
+ tr_notice("tr_tids_req_fwd_thread: invalid port (%d) for %s", aaa_port, aaa_hostname);
+ success=0;
+ goto cleanup;
+ }
+
if (-1==(args->fwd_req->conn = tidc_open_connection(tidc,
- args->aaa_hostname->buf,
- TID_PORT, /* TODO: make this configurable */
- &(args->fwd_req->gssctx)))) {
+ aaa_hostname,
+ aaa_port,
+ &(args->fwd_req->gssctx)))) {
tr_notice("tr_tids_req_fwd_thread: Error in tidc_open_connection.");
/* tids_send_err_response(tids, orig_req, "Can't open connection to next hop TIDS"); */
/* TODO: encode reason for failure */
success=0;
goto cleanup;
};
- tr_debug("tr_tids_req_fwd_thread: thread %d opened TID connection to %s.",
- cookie->thread_id,
- args->aaa_hostname->buf);
+ tr_debug("tr_tids_req_fwd_thread: thread %d opened TID connection to %s:%d.",
+ cookie->thread_id, aaa_hostname, aaa_port);
/* Send a TID request. */
if (0 > (rc = tidc_fwd_request(tidc, args->fwd_req, tr_tidc_resp_handler, (void *)cookie))) {
tr_notice("tr_tids_req_fwd_thread: Error releasing mutex.");
}
+ if (aaa_hostname != NULL)
+ free(aaa_hostname);
+
talloc_free(tmp_ctx);
return NULL;
}
&idp_shared);
} else {
tr_debug("tr_tids_req_handler: route not local.");
- aaa_servers = tr_aaa_server_new(tmp_ctx, trp_route_get_next_hop(route));
+ aaa_servers = tr_aaa_server_new(tmp_ctx); /* cleaned up via talloc */
+ if (aaa_servers == NULL) {
+ tr_err("tr_tids_req_handler: error allocating next hop");
+ retval=-1;
+ goto cleanup;
+ }
+ tr_aaa_server_set_hostname(aaa_servers, trp_route_dup_next_hop(route));
+ if (tr_aaa_server_get_hostname(aaa_servers) == NULL) {
+ tr_err("tr_tids_req_handler: error allocating next hop");
+ retval=-1;
+ goto cleanup;
+ }
+ tr_aaa_server_set_port(aaa_servers, trp_route_get_next_hop_port(route));
idp_shared = 0;
}
goto cleanup;
}
aaa_cookie[n_aaa]->mq=mq;
- aaa_cookie[n_aaa]->aaa_hostname=tr_dup_name(this_aaa->hostname);
+ aaa_cookie[n_aaa]->aaa=this_aaa;
aaa_cookie[n_aaa]->dh_params=tr_dh_dup(orig_req->tidc_dh);
aaa_cookie[n_aaa]->fwd_req=tid_dup_req(fwd_req);
talloc_steal(aaa_cookie[n_aaa], aaa_cookie[n_aaa]->fwd_req);
return NULL;
}
-/* convert an IDP realm into routing table entries. Outputs number in *n_routes */
+/**
+ * convert an IDP realm into routing table entries.
+ *
+ * @param mem_ctx talloc context for the result
+ * @param realm IDP realm whose routes should be generated
+ * @param trust_router hostname for TRP connections to us
+ * @param trust_router_port TRP port of our trust router
+ * @param n_routes (output) the number of routes in the returned array
+ * @return Pointer to an array of pointers to routes
+ */
static TRP_ROUTE **tr_make_local_routes(TALLOC_CTX *mem_ctx,
- TR_IDP_REALM *realm,
- char *trust_router,
- size_t *n_routes)
+ TR_IDP_REALM *realm,
+ const char *trust_router,
+ int trust_router_port,
+ size_t *n_routes)
{
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
TR_APC *comm=NULL;
trp_route_set_peer(new_entry, tr_new_name("")); /* no peer, it's us */
trp_route_set_metric(new_entry, 0);
trp_route_set_trust_router(new_entry, tr_new_name(trust_router));
- trp_route_set_next_hop(new_entry, tr_new_name(""));
+ trp_route_set_trust_router_port(new_entry, trust_router_port);
+ trp_route_set_next_hop(new_entry, tr_new_name("")); /* no next hop */
+ trp_route_set_next_hop_port(new_entry, -1); /* no next hop */
trp_route_set_local(new_entry, 1);
entries[ii]=new_entry;
}
TRP_ROUTE **local_routes=NULL;
size_t n_routes=0;
size_t ii=0;
- char *trust_router_name=talloc_asprintf(tmp_ctx, "%s:%d", cfg->internal->hostname, cfg->internal->trps_port);
-
- /* determine our trust router name */
- if (trust_router_name==NULL)
- return TRP_NOMEM;
for (cur=cfg->ctable->idp_realms; cur!=NULL; cur=cur->next) {
- local_routes=tr_make_local_routes(tmp_ctx, cur, trust_router_name, &n_routes);
+ local_routes= tr_make_local_routes(tmp_ctx, cur, cfg->internal->hostname, cfg->internal->trps_port, &n_routes);
for (ii=0; ii<n_routes; ii++)
trps_add_route(trps, local_routes[ii]);
/* structure for communicating with option parser */
struct cmdline_args {
char *server;
- unsigned int port;
+ int port;
MON_CMD command;
MON_OPT_TYPE options[MAX_OPTIONS];
unsigned int n_options;
if (errno || (tmp_l < 0) || (tmp_l > 65535)) /* max valid port */
argp_usage(state);
- arguments->port=(unsigned int) tmp_l;
+ arguments->port = (int) tmp_l; /* we already checked the range */
break;
case 2:
struct peer_entry {
char *server;
char *gss_name;
- unsigned int port;
+ int port;
unsigned int linkcost;
};
}
/* Initiate connection */
-TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, unsigned int port)
+TRP_RC trp_connection_initiate(TRP_CONNECTION *conn, char *server, int port)
{
int err = 0;
int fd=-1;
- unsigned int use_port=0;
+ int use_port=0;
if (0 == port)
use_port = TRP_PORT;
return tr_dup_name(peer->servicename);
}
-unsigned int trp_peer_get_port(TRP_PEER *peer)
+int trp_peer_get_port(TRP_PEER *peer)
{
return peer->port;
}
-void trp_peer_set_port(TRP_PEER *peer, unsigned int port)
+void trp_peer_set_port(TRP_PEER *peer, int port)
{
peer->port=port;
}
}
/* helper for encoding to json */
-static json_t *server_to_json_string(const char *server, unsigned int port)
+static json_t *server_to_json_string(const char *server, int port)
{
char *s = talloc_asprintf(NULL, "%s:%u", server, port);
json_t *jstr = json_string(s);
entry->comm=NULL;
entry->realm=NULL;
entry->trust_router=NULL;
- entry->trp_port=TRP_PORT;
- entry->tid_port=TID_PORT;
+ entry->trust_router_port=TRP_PORT;
+ entry->next_hop_port=TID_PORT;
entry->peer=NULL;
entry->next_hop=NULL;
entry->selected=0;
return entry->metric;
}
-/* TODO: set the hostname and port for the next hop. Currently assume default TID port. --jlr */
void trp_route_set_next_hop(TRP_ROUTE *entry, TR_NAME *next_hop)
{
if (entry->next_hop!=NULL)
{
return entry->triggered;
}
+
+void trp_route_set_trust_router_port(TRP_ROUTE *entry, int port)
+{
+ if (entry)
+ entry->trust_router_port = port;
+}
+
+/**
+ * Get the port to use for TRP connections to the trust router
+ *
+ * @param entry
+ * @return port, or -1 if entry is null
+ */
+int trp_route_get_trust_router_port(TRP_ROUTE *entry)
+{
+ if (entry)
+ return entry->trust_router_port;
+
+ return -1;
+}
+
+void trp_route_set_next_hop_port(TRP_ROUTE *entry, int port)
+{
+ if (entry)
+ entry->next_hop_port = port;
+}
+
+/**
+ * Get the port to use for TID connections to the next hop
+ *
+ * @param entry
+ * @return port, or -1 if entry is null
+ */
+int trp_route_get_next_hop_port(TRP_ROUTE *entry)
+{
+ if (entry)
+ return entry->next_hop_port;
+
+ return -1;
+}
#include <trust_router/trp.h>
#include <tr_util.h>
#include <tr_json_util.h>
+#include <tr_inet_util.h>
/* Pretty print a route table entry to a newly allocated string. If sep is NULL,
* returns comma+space separated string. */
sep=", ";
result=talloc_asprintf(mem_ctx,
- "%s%s%s%s%s%s%u%s%s%s%s%s%u%s%u%s%s%s%u",
+ "%s%s%s%s%s%s%u%s%s:%d%s%s:%d%s%u%s%u%s%s%s%u",
comm, sep,
realm, sep,
peer, sep,
entry->metric, sep,
- trust_router, sep,
- next_hop, sep,
+ trust_router, entry->trust_router_port, sep,
+ next_hop, entry->next_hop_port, sep,
entry->selected, sep,
entry->local, sep,
expiry, sep,
{
json_t *route_json = NULL;
json_t *retval = NULL;
+ TR_NAME *n;
route_json = json_object();
if (route_json == NULL)
if (trp_route_get_peer(route)->len > 0)
OBJECT_SET_OR_FAIL(route_json, "peer", tr_name_to_json_string(trp_route_get_peer(route)));
OBJECT_SET_OR_FAIL(route_json, "metric", json_integer(trp_route_get_metric(route)));
- OBJECT_SET_OR_FAIL(route_json, "trust_router", tr_name_to_json_string(trp_route_get_trust_router(route)));
- if (trp_route_get_next_hop(route)->len > 0)
- OBJECT_SET_OR_FAIL(route_json, "next_hop", tr_name_to_json_string(trp_route_get_next_hop(route)));
+
+ /* add trust_router as hostname:port */
+ n = tr_hostname_and_port_to_name(
+ trp_route_get_trust_router(route),
+ trp_route_get_trust_router_port(route));
+ if (n == NULL)
+ goto cleanup;
+ OBJECT_SET_OR_FAIL(route_json, "trust_router", tr_name_to_json_string(n));
+ tr_free_name(n);
+
+ /* add next_hop as hostname:port */
+ n = tr_hostname_and_port_to_name(
+ trp_route_get_next_hop(route),
+ trp_route_get_next_hop_port(route));
+ if (n == NULL)
+ goto cleanup;
+ OBJECT_SET_OR_FAIL(route_json, "next_hop", tr_name_to_json_string(n));
+ tr_free_name(n);
+
OBJECT_SET_OR_FAIL(route_json, "selected", json_boolean(trp_route_is_selected(route)));
OBJECT_SET_OR_FAIL(route_json, "local", json_boolean(trp_route_is_local(route)));
OBJECT_SET_OR_SKIP(route_json, "expires", expiry_to_json_string(route));
TR_NAME *trp_inforec_get_trust_router(TRP_INFOREC *rec)
{
switch (rec->type) {
- case TRP_INFOREC_TYPE_ROUTE:
- if (rec->data->route!=NULL)
- return rec->data->route->trust_router;
- break;
- default:
- break;
+ case TRP_INFOREC_TYPE_ROUTE:
+ if (rec->data->route!=NULL)
+ return rec->data->route->trust_router;
+ break;
+ default:
+ break;
}
return NULL;
}
+int trp_inforec_get_trust_router_port(TRP_INFOREC *rec)
+{
+ switch (rec->type) {
+ case TRP_INFOREC_TYPE_ROUTE:
+ if (rec->data->route!=NULL)
+ return rec->data->route->trust_router_port;
+ /* fall through */
+ default:
+ return -1;
+ }
+}
+
TR_NAME *trp_inforec_dup_trust_router(TRP_INFOREC *rec)
{
return tr_dup_name(trp_inforec_get_trust_router(rec));
}
-TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router)
+TRP_RC trp_inforec_set_trust_router(TRP_INFOREC *rec, TR_NAME *trust_router, int port)
{
switch (rec->type) {
case TRP_INFOREC_TYPE_ROUTE:
if (rec->data->route!=NULL) {
rec->data->route->trust_router=trust_router;
+ rec->data->route->trust_router_port = port;
return TRP_SUCCESS;
}
break;
return TRP_ERROR;
}
-/* TODO: need to return hostname/port --jlr */
TR_NAME *trp_inforec_get_next_hop(TRP_INFOREC *rec)
{
switch (rec->type) {
- case TRP_INFOREC_TYPE_ROUTE:
- if (rec->data->route!=NULL)
- return rec->data->route->next_hop;
- break;
- default:
- break;
+ case TRP_INFOREC_TYPE_ROUTE:
+ if (rec->data->route!=NULL)
+ return rec->data->route->next_hop;
+ break;
+ default:
+ break;
}
return NULL;
}
* @param next_hop
* @return TRP_SUCCESS if the value was set, TRP_UNSUPPORTED if the inforec does not support next hop, or an error code on failure
*/
-TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop)
+TRP_RC trp_inforec_set_next_hop(TRP_INFOREC *rec, TR_NAME *next_hop, int port)
{
/* Any inforec types that support next_hop should set it here. */
switch (rec->type) {
case TRP_INFOREC_TYPE_ROUTE:
if (rec->data->route==NULL)
return TRP_ERROR;
- rec->data->route->next_hop=next_hop;
+ rec->data->route->next_hop = next_hop;
+ rec->data->route->next_hop_port = port;
break;
default:
return TRP_SUCCESS;
}
+int trp_inforec_get_next_hop_port(TRP_INFOREC *rec)
+{
+ switch (rec->type) {
+ case TRP_INFOREC_TYPE_ROUTE:
+ if (rec->data->route!=NULL)
+ return rec->data->route->next_hop_port;
+ /* fall through */
+ default:
+ return -1;
+ }
+}
+
unsigned int trp_inforec_get_metric(TRP_INFOREC *rec)
{
switch (rec->type) {
upd->peer=peer;
}
-void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, unsigned int port)
+void trp_upd_set_next_hop(TRP_UPD *upd, const char *hostname, int port)
{
TRP_INFOREC *rec=NULL;
TR_NAME *cpy=NULL;
for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
- switch (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname))) {
+ switch (trp_inforec_set_next_hop(rec, cpy=tr_new_name(hostname), port)) {
case TRP_SUCCESS:
/* Success, the TR_NAME in cpy is now stored with the inforec */
break;
return trpc->port;
}
-void trpc_set_port(TRPC_INSTANCE *trpc, unsigned int port)
+void trpc_set_port(TRPC_INSTANCE *trpc, int port)
{
trpc->port=port;
}
TRPS_INSTANCE *trps=talloc(mem_ctx, TRPS_INSTANCE);
if (trps!=NULL) {
trps->hostname=NULL;
- trps->port=0;
+ trps->trps_port=0;
trps->cookie=NULL;
trps->conn=NULL;
trps->trpc=NULL;
{
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
TR_NAME *label=NULL;
- char *s=talloc_asprintf(tmp_ctx, "%s:%u", trps->hostname, trps->port);
+ char *s=talloc_asprintf(tmp_ctx, "%s:%u", trps->hostname, trps->trps_port);
if (s==NULL)
goto cleanup;
label=tr_new_name(s);
switch (tr_msg_get_msg_type(*msg)) {
case TRP_UPDATE:
trp_upd_set_peer(tr_msg_get_trp_upd(*msg), tr_dup_name(conn_peer));
- trp_upd_set_next_hop(tr_msg_get_trp_upd(*msg), trp_peer_get_server(peer), 0); /* TODO: 0 should be the configured TID port */
/* update provenance if necessary */
trp_upd_add_to_provenance(tr_msg_get_trp_upd(*msg), trp_peer_get_label(peer));
break;
TRPS_MSG_FUNC msg_handler,
TRP_AUTH_FUNC auth_handler,
const char *hostname,
- unsigned int port,
+ int port,
void *cookie,
int *fd_out,
size_t max_fd)
trps->msg_handler = msg_handler;
trps->auth_handler = auth_handler;
trps->hostname = talloc_strdup(trps, hostname);
- trps->port = port;
+ trps->trps_port = port;
trps->cookie = cookie;
}
switch(trp_inforec_get_type(rec)) {
case TRP_INFOREC_TYPE_ROUTE:
if ((trp_inforec_get_trust_router(rec)==NULL)
- || (trp_inforec_get_next_hop(rec)==NULL)) {
+ || (trp_inforec_get_next_hop(rec)==NULL)) {
tr_debug("trps_validate_inforec: missing record info.");
return TRP_ERROR;
}
- /* check for valid metric */
+ /* check for valid ports */
+ if ((trp_inforec_get_trust_router_port(rec) <= 0)
+ || (trp_inforec_get_trust_router_port(rec) > 65535)) {
+ tr_debug("trps_validate_inforec: invalid trust router port (%d)",
+ trp_inforec_get_trust_router_port(rec));
+ return TRP_ERROR;
+ }
+
+ if ((trp_inforec_get_next_hop_port(rec) <= 0)
+ || (trp_inforec_get_next_hop_port(rec) > 65535)) {
+ tr_debug("trps_validate_inforec: invalid next hop port (%d)",
+ trp_inforec_get_next_hop_port(rec));
+ return TRP_ERROR;
+ }
+
+ /* check for valid metric */
if (trp_metric_is_invalid(trp_inforec_get_metric(rec))) {
tr_debug("trps_validate_inforec: invalid metric (%u).", trp_inforec_get_metric(rec));
return TRP_ERROR;
return ts;
}
+
+/* compare hostname/port of the trust router, return 0 if they match */
+static int trust_router_changed(TRP_ROUTE *route, TRP_INFOREC *rec)
+{
+ if (trp_route_get_trust_router_port(route) != trp_inforec_get_trust_router_port(rec))
+ return 1;
+
+ return tr_name_cmp(trp_route_get_trust_router(route),
+ trp_inforec_get_trust_router(rec));
+}
+
static TRP_RC trps_accept_update(TRPS_INSTANCE *trps, TRP_UPD *upd, TRP_INFOREC *rec)
{
TRP_ROUTE *entry=NULL;
trp_route_set_realm(entry, trp_upd_dup_realm(upd));
trp_route_set_peer(entry, trp_upd_dup_peer(upd));
trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec));
+ trp_route_set_trust_router_port(entry, trp_inforec_get_trust_router_port(rec));
trp_route_set_next_hop(entry, trp_inforec_dup_next_hop(rec));
- /* TODO: pass next hop port (now defaults to TID_PORT) --jlr */
+ trp_route_set_next_hop_port(entry, trp_inforec_get_next_hop_port(rec));
if ((trp_route_get_comm(entry)==NULL)
||(trp_route_get_realm(entry)==NULL)
||(trp_route_get_peer(entry)==NULL)
trp_route_set_metric(entry, trp_inforec_get_metric(rec));
trp_route_set_interval(entry, trp_inforec_get_interval(rec));
- /* check whether the trust router has changed */
- if (0!=tr_name_cmp(trp_route_get_trust_router(entry),
- trp_inforec_get_trust_router(rec))) {
+ /* check whether the trust router has changed (either name or port) */
+ if (trust_router_changed(entry, rec)) {
/* The name changed. Set this route as triggered. */
tr_debug("trps_accept_update: trust router for route changed.");
trp_route_set_triggered(entry, 1);
trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec)); /* frees old name */
+ trp_route_set_trust_router_port(entry, trp_inforec_get_trust_router_port(rec));
}
if (!trps_route_retracted(trps, entry)) {
tr_debug("trps_accept_update: route not retracted, setting expiry timer.");
trps_accept_update(trps, upd, rec);
} else {
/* Update is infeasible. Ignore it unless the trust router has changed. */
- if (0!=tr_name_cmp(trp_route_get_trust_router(route),
- trp_inforec_get_trust_router(rec))) {
+ if (trust_router_changed(route, rec)) {
/* the trust router associated with the route has changed, treat update as a retraction */
trps_retract_route(trps, route);
}
trp_route_get_peer(route)));
}
- /* Note that we leave the next hop empty since the recipient fills that in.
- * This is where we add the link cost (currently always 1) to the next peer. */
- if ((trp_inforec_set_trust_router(rec, trp_route_dup_trust_router(route)) != TRP_SUCCESS)
- ||(trp_inforec_set_metric(rec,
- trps_metric_add(trp_route_get_metric(route),
- linkcost)) != TRP_SUCCESS)
- ||(trp_inforec_set_interval(rec, trps_get_update_interval(trps)) != TRP_SUCCESS)) {
+ /*
+ * This is where we add the link cost (currently always 1) to the next peer.
+ *
+ * Here, set next_hop to our TID address/port rather than passing along our own
+ * next_hop. That is the one *we* use to forward requests. We are advertising
+ * ourselves as a hop for our peers.
+ */
+ if ((TRP_SUCCESS != trp_inforec_set_trust_router(rec,
+ trp_route_dup_trust_router(route),
+ trp_route_get_trust_router_port(route)))
+ ||(TRP_SUCCESS != trp_inforec_set_next_hop(rec,
+ tr_new_name(trps->hostname),
+ trps->tids_port))
+ ||(TRP_SUCCESS != trp_inforec_set_metric(rec,
+ trps_metric_add(trp_route_get_metric(route),
+ linkcost)))
+ ||(TRP_SUCCESS != trp_inforec_set_interval(rec, trps_get_update_interval(trps)))) {
tr_err("trps_route_to_inforec: error creating route update.");
talloc_free(rec);
rec=NULL;