summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/irmd')
-rw-r--r--src/irmd/configfile.c9
-rw-r--r--src/irmd/ipcp.c2
-rw-r--r--src/irmd/main.c117
-rw-r--r--src/irmd/reg/flow.h1
-rw-r--r--src/irmd/reg/reg.c9
-rw-r--r--src/irmd/reg/reg.h3
-rw-r--r--src/irmd/reg/tests/reg_test.c7
7 files changed, 96 insertions, 52 deletions
diff --git a/src/irmd/configfile.c b/src/irmd/configfile.c
index 2dfb41a8..ce9fc8fc 100644
--- a/src/irmd/configfile.c
+++ b/src/irmd/configfile.c
@@ -922,8 +922,10 @@ static int toml_name(toml_table_t * table,
toml_array_t * progs;
toml_array_t * args;
toml_datum_t lb;
+ toml_datum_t senc;
toml_datum_t scrt;
toml_datum_t skey;
+ toml_datum_t cenc;
toml_datum_t ccrt;
toml_datum_t ckey;
@@ -955,6 +957,9 @@ static int toml_name(toml_table_t * table,
log_err("Invalid load-balancing policy for %s.", name);
return -1;
}
+ senc = toml_string_in(table, "server_enc_file");
+ if (senc.ok && cp_chk_path(info.s.enc, senc.u.s) < 0)
+ return -1;
scrt = toml_string_in(table, "server_crt_file");
if (scrt.ok && cp_chk_path(info.s.crt, scrt.u.s) < 0)
@@ -964,6 +969,10 @@ static int toml_name(toml_table_t * table,
if (skey.ok && cp_chk_path(info.s.key, skey.u.s) < 0)
return -1;
+ cenc = toml_string_in(table, "client_enc_file");
+ if (cenc.ok && cp_chk_path(info.c.enc, cenc.u.s) < 0)
+ return -1;
+
ccrt = toml_string_in(table, "client_crt_file");
if (ccrt.ok && cp_chk_path(info.c.crt, ccrt.u.s) < 0)
return -1;
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index fdee6a75..6226aeda 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -497,7 +497,7 @@ int ipcp_flow_alloc_resp(const struct flow_info * flow,
msg.pid = flow->n_pid;
msg.has_response = true;
msg.response = response;
- msg.has_pk = true;
+ msg.has_pk = response == 0;
msg.pk.data = data.data;
msg.pk.len = data.len;
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 05f9236f..834a7a8c 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -455,12 +455,18 @@ static void name_update_sec_paths(struct name_info * info)
assert(info != NULL);
+ if (strlen(info->s.enc) == 0)
+ sprintf(info->s.enc, "%s/%s/enc.cfg", srv_dir, info->name);
+
if (strlen(info->s.crt) == 0)
sprintf(info->s.crt, "%s/%s/crt.pem", srv_dir, info->name);
if (strlen(info->s.key) == 0)
sprintf(info->s.key, "%s/%s/key.pem", srv_dir, info->name);
+ if (strlen(info->c.enc) == 0)
+ sprintf(info->c.enc, "%s/%s/enc.cfg", cli_dir, info->name);
+
if (strlen(info->c.crt) == 0)
sprintf(info->c.crt, "%s/%s/crt.pem", cli_dir, info->name);
@@ -816,7 +822,8 @@ static bool file_exists(const char * path)
static int load_credentials(const char * name,
const struct name_sec_paths * paths,
void ** pkp,
- void ** crt)
+ void ** crt,
+ bool * crypt)
{
assert(paths != NULL);
assert(pkp != NULL);
@@ -825,6 +832,11 @@ static int load_credentials(const char * name,
*pkp = NULL;
*crt = NULL;
+ /* TODO: Allow configuration. For now, encrypt if path exists */
+ *crypt = file_exists(paths->enc);
+ if (*crypt)
+ log_info("Encryption enabled for %s.", name);
+
if (!file_exists(paths->crt) || !file_exists(paths->key)) {
log_info("No security info for %s.", name);
return 0;
@@ -853,7 +865,8 @@ static int load_credentials(const char * name,
static int load_srv_credentials(const char * name,
void ** pkp,
- void ** crt)
+ void ** crt,
+ bool * crypt)
{
struct name_info info;
@@ -866,12 +879,13 @@ static int load_srv_credentials(const char * name,
return -ENAME;
}
- return load_credentials(name, &info.s, pkp, crt);
+ return load_credentials(name, &info.s, pkp, crt, crypt);
}
static int load_cli_credentials(const char * name,
void ** pkp,
- void ** crt)
+ void ** crt,
+ bool * crypt)
{
struct name_info info;
@@ -884,7 +898,7 @@ static int load_cli_credentials(const char * name,
return -ENAME;
}
- return load_credentials(name, &info.c, pkp, crt);
+ return load_credentials(name, &info.c, pkp, crt, crypt);
}
#define ID_IS_EQUAL(id1, id2) (memcmp(id1, id2, OAP_ID_SIZE) == 0)
@@ -1029,14 +1043,15 @@ static int flow_accept(struct flow_info * flow,
buffer_t * data,
struct timespec * abstime)
{
- struct oap_hdr oap_hdr; /* incoming request */
- struct oap_hdr r_oap_hdr; /* outgoing response */
- uint8_t buf[MSGBUFSZ]; /* buffer for local ephkey */
- buffer_t lpk = BUF_INIT; /* local ephemeral pubkey */
- char name[NAME_SIZE + 1]; /* name for flow */
- void * pkp = NULL; /* signing private key */
- void * crt = NULL; /* signing certificate */
- int err;
+ struct oap_hdr oap_hdr; /* incoming request */
+ struct oap_hdr r_oap_hdr; /* outgoing response */
+ uint8_t buf[MSGBUFSZ]; /* buffer for local ephkey */
+ buffer_t lpk = BUF_INIT; /* local ephemeral pubkey */
+ char name[NAME_SIZE + 1]; /* name for flow */
+ void * pkp = NULL; /* signing private key */
+ void * crt = NULL; /* signing certificate */
+ int err;
+ bool crypt;
/* piggyback of user data not yet implemented */
assert(data != NULL && BUF_IS_EMPTY(data));
@@ -1082,12 +1097,18 @@ static int flow_accept(struct flow_info * flow,
if (reg_get_name_for_flow_id(name, flow->id) < 0) {
log_err("Failed to get name for flow %d.", flow->id);
err = -EIPCP;
- goto fail_oap_hdr;
+ goto fail_cred;
}
log_dbg("IPCP %d accepting flow %d for %s.",
flow->n_pid, flow->id, name);
+ if (load_srv_credentials(name, &pkp, &crt, &crypt) < 0) {
+ log_err("Failed to load security keys for %s.", name);
+ err = -EAUTH;
+ goto fail_cred;
+ }
+
if (oap_hdr_decode(oap_hdr.hdr, &oap_hdr) < 0) {
log_err("Failed to decode OAP header from %s.", name);
err = -EIPCP;
@@ -1101,10 +1122,16 @@ static int flow_accept(struct flow_info * flow,
goto fail_oap_hdr;
}
- if (flow->qs.cypher_s != 0) { /* crypto requested */
- uint8_t * s; /* symmetric encryption key */
- ssize_t key_len; /* length of local pubkey */
- void * pkp = NULL; /* ephemeral private key pair */
+ if (crypt && oap_hdr.eph.len == 0) {
+ log_warn("Encryption required but no key provided.");
+ err = -ECRYPT;
+ goto fail_oap_hdr;
+ }
+
+ if (oap_hdr.eph.len > 0) { /* crypto requested */
+ uint8_t * s; /* symmetric encryption key */
+ ssize_t key_len; /* length of local pubkey */
+ void * pkp = NULL; /* ephemeral private key pair */
s = malloc(SYMMKEYSZ);
if (s == NULL) {
@@ -1140,12 +1167,6 @@ static int flow_accept(struct flow_info * flow,
crypt_dh_pkp_destroy(pkp);
}
- if (load_srv_credentials(name, &pkp, &crt) < 0) {
- log_err("Failed to load security keys for %s.", name);
- err = -EAUTH;
- goto fail_cred;
- }
-
if (oap_hdr_init(oap_hdr.id, pkp, crt, lpk, *data, &r_oap_hdr) < 0) {
log_err("Failed to create OAP header.");
err = -ENOMEM;
@@ -1178,15 +1199,15 @@ static int flow_accept(struct flow_info * flow,
return 0;
fail_r_oap_hdr:
- crypt_free_crt(crt);
- crypt_free_key(pkp);
- fail_cred:
freebuf(*symmkey);
fail_derive:
clrbuf(lpk);
fail_keys:
oap_hdr_fini(&oap_hdr);
fail_oap_hdr:
+ crypt_free_crt(crt);
+ crypt_free_key(pkp);
+ fail_cred:
assert(lpk.data == NULL && lpk.len == 0);
ipcp_flow_alloc_resp(flow, err, lpk);
fail_wait:
@@ -1354,11 +1375,14 @@ static int flow_alloc(struct flow_info * flow,
uint8_t idbuf[OAP_ID_SIZE];
buffer_t id;
int err;
+ bool crypt;
/* piggyback of user data not yet implemented */
assert(data != NULL && BUF_IS_EMPTY(data));
assert(symmkey != NULL && BUF_IS_EMPTY(symmkey));
+ log_info("Allocating flow for %d to %s.", flow->n_pid, dst);
+
if (random_buffer(idbuf, OAP_ID_SIZE) < 0) {
log_err("Failed to generate ID.");
err = -EIRMD;
@@ -1368,7 +1392,13 @@ static int flow_alloc(struct flow_info * flow,
id.data = idbuf;
id.len = OAP_ID_SIZE;
- if (flow->qs.cypher_s > 0) {
+ if (load_cli_credentials(dst, &cpkp, &ccrt, &crypt) < 0) {
+ log_err("Failed to load security keys for %s.", dst);
+ err = -EAUTH;
+ goto fail_cred;
+ }
+
+ if (crypt > 0) {
ssize_t key_len;
s = malloc(SYMMKEYSZ);
@@ -1391,12 +1421,6 @@ static int flow_alloc(struct flow_info * flow,
log_dbg("Generated ephemeral keys for %d.", flow->n_pid);
}
- if (load_cli_credentials(dst, &cpkp, &ccrt) < 0) {
- log_err("Failed to load security keys for %s.", dst);
- err = -EAUTH;
- goto fail_cred;
- }
-
if (oap_hdr_init(id, cpkp, ccrt, lpk, *data, &oap_hdr) < 0) {
log_err("Failed to create OAP header.");
err = -ENOMEM;
@@ -1405,9 +1429,6 @@ static int flow_alloc(struct flow_info * flow,
#ifdef DEBUG_PROTO_OAP
debug_oap_hdr_snd(&oap_hdr);
#endif
-
- log_info("Allocating flow for %d to %s.", flow->n_pid, dst);
-
if (reg_create_flow(flow) < 0) {
log_err("Failed to create flow.");
err = -EBADF;
@@ -1447,11 +1468,16 @@ static int flow_alloc(struct flow_info * flow,
if (err == -1) {
log_dbg("Flow allocation terminated.");
- err = -EPIPE;
+ err = -EIPCP;
goto fail_alloc;
}
- assert(err == 0);
+ log_dbg("Response received for flow %d to %s.", flow->id, dst);
+
+ if (err < 0) {
+ log_warn("Flow allocation rejected for %s: %d.", dst, err);
+ goto fail_alloc;
+ }
if (oap_hdr_decode(r_oap_hdr.hdr, &r_oap_hdr) < 0) {
log_err("Failed to decode OAP header.");
@@ -1463,6 +1489,7 @@ static int flow_alloc(struct flow_info * flow,
#endif
if (irm_check_oap_hdr(&r_oap_hdr, flow->mpl) < 0) {
log_err("OAP header failed replay check.");
+ err = -EAUTH;
goto fail_r_oap_hdr;
}
@@ -1472,7 +1499,7 @@ static int flow_alloc(struct flow_info * flow,
goto fail_r_oap_hdr;
}
- if (flow->qs.cypher_s != 0) { /* crypto requested */
+ if (lpk.len > 0) { /* crypto requested */
if (crypt_dh_derive(pkp, r_oap_hdr.eph, s) < 0) {
log_err("Failed to derive secret for %d.", flow->id);
err = -ECRYPT;
@@ -1508,13 +1535,13 @@ static int flow_alloc(struct flow_info * flow,
fail_flow:
oap_hdr_fini(&oap_hdr);
fail_oap_hdr:
- crypt_free_crt(ccrt);
- crypt_free_key(cpkp);
- fail_cred:
crypt_dh_pkp_destroy(pkp);
fail_pkp:
free(s);
fail_malloc:
+ crypt_free_crt(ccrt);
+ crypt_free_key(cpkp);
+ fail_cred:
clrbuf(id);
fail_id:
return err;
@@ -1616,9 +1643,9 @@ static int flow_alloc_reply(struct flow_info * flow,
int response,
buffer_t * data)
{
- flow->state = response ? FLOW_DEALLOCATED : FLOW_ALLOCATED;
+ flow->state = response != 0 ? FLOW_DEALLOCATED : FLOW_ALLOCATED;
- if (reg_respond_alloc(flow, data) < 0) {
+ if (reg_respond_alloc(flow, data, response) < 0) {
log_err("Failed to reply to flow %d.", flow->id);
flow->state = FLOW_DEALLOCATED;
return -EBADF;
diff --git a/src/irmd/reg/flow.h b/src/irmd/reg/flow.h
index aba0d7a4..d1e4811c 100644
--- a/src/irmd/reg/flow.h
+++ b/src/irmd/reg/flow.h
@@ -38,6 +38,7 @@ struct reg_flow {
struct list_head next;
struct flow_info info;
+ int response;
buffer_t data;
struct timespec t0;
diff --git a/src/irmd/reg/reg.c b/src/irmd/reg/reg.c
index 91385260..a24a9d1d 100644
--- a/src/irmd/reg/reg.c
+++ b/src/irmd/reg/reg.c
@@ -1714,7 +1714,7 @@ int reg_wait_flow_allocated(struct flow_info * info,
stop = true;
break;
case FLOW_DEALLOCATED:
- ret = -1;
+ ret = flow->response;
stop = true;
break;
default:
@@ -1746,7 +1746,8 @@ int reg_wait_flow_allocated(struct flow_info * info,
}
int reg_respond_alloc(struct flow_info * info,
- buffer_t * pbuf)
+ buffer_t * pbuf,
+ int response)
{
struct reg_flow * flow;
@@ -1779,7 +1780,9 @@ int reg_respond_alloc(struct flow_info * info,
if (reg_flow_update(flow, info) < 0) {
log_err("Failed to create flow structs.");
goto fail_flow;
- };
+ }
+
+ flow->response = response;
if (info->state == FLOW_ALLOCATED)
reg_flow_set_data(flow, pbuf);
diff --git a/src/irmd/reg/reg.h b/src/irmd/reg/reg.h
index 57257dd5..7728c80f 100644
--- a/src/irmd/reg/reg.h
+++ b/src/irmd/reg/reg.h
@@ -126,7 +126,8 @@ int reg_wait_flow_allocated(struct flow_info * info,
const struct timespec * abstime);
int reg_respond_alloc(struct flow_info * info,
- buffer_t * pbuf);
+ buffer_t * pbuf,
+ int response);
int reg_prepare_flow_accept(struct flow_info * info);
diff --git a/src/irmd/reg/tests/reg_test.c b/src/irmd/reg/tests/reg_test.c
index d18f5733..4699beab 100644
--- a/src/irmd/reg/tests/reg_test.c
+++ b/src/irmd/reg/tests/reg_test.c
@@ -174,6 +174,9 @@ static void * test_flow_respond_alloc(void * o)
{
struct flow_info * info = (struct flow_info *) o;
buffer_t pbuf = BUF_INIT;
+ int response;
+
+ response = (info->state == FLOW_ALLOCATED) ? 0 : -1;
if (info->state == FLOW_ALLOCATED) {
pbuf.data = (uint8_t *) strdup(TEST_DATA2);
@@ -184,7 +187,7 @@ static void * test_flow_respond_alloc(void * o)
pbuf.len = strlen((char *) pbuf.data) + 1;
}
- reg_respond_alloc(info, &pbuf);
+ reg_respond_alloc(info, &pbuf, response);
return (void *) 0;
fail:
@@ -224,7 +227,7 @@ static int test_reg_accept_flow_success(void)
struct flow_info n_1_info = {
.n_1_pid = TEST_N_1_PID,
- .qs = qos_data_crypt,
+ .qs = qos_data,
.state = FLOW_ALLOCATED /* RESPONSE SUCCESS */
};