diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-10-22 11:43:58 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-10-22 11:43:58 +0200 |
commit | 5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (patch) | |
tree | 037f1ec5bb860846938ddcf29771c24e9c529be0 /src/libcharon/plugins/ha | |
parent | b238cf34df3fe4476ae6b7012e7cb3e9769d4d51 (diff) | |
download | vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.tar.gz vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.zip |
Imported Upstream version 5.3.3
Diffstat (limited to 'src/libcharon/plugins/ha')
-rw-r--r-- | src/libcharon/plugins/ha/ha_ctl.c | 85 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_dispatcher.c | 12 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_ike.c | 1 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_kernel.c | 21 |
4 files changed, 103 insertions, 16 deletions
diff --git a/src/libcharon/plugins/ha/ha_ctl.c b/src/libcharon/plugins/ha/ha_ctl.c index a95499742..54302e852 100644 --- a/src/libcharon/plugins/ha/ha_ctl.c +++ b/src/libcharon/plugins/ha/ha_ctl.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -51,6 +52,41 @@ struct private_ha_ctl_t { }; /** + * Change the permissions of the control FIFO, returns TRUE on success + */ +static bool change_fifo_permissions() +{ + if (chown(HA_FIFO, lib->caps->get_uid(lib->caps), + lib->caps->get_gid(lib->caps)) != 0) + { + DBG1(DBG_CFG, "changing HA FIFO permissions failed: %s", + strerror(errno)); + return FALSE; + } + return TRUE; +} + +/** + * Deletes and creates the control FIFO, returns TRUE on success + */ +static bool recreate_fifo() +{ + mode_t old; + bool success = TRUE; + + unlink(HA_FIFO); + old = umask(S_IRWXO); + if (mkfifo(HA_FIFO, S_IRUSR | S_IWUSR) != 0) + { + DBG1(DBG_CFG, "creating HA FIFO %s failed: %s", HA_FIFO, + strerror(errno)); + success = FALSE; + } + umask(old); + return success && change_fifo_permissions(); +} + +/** * FIFO dispatching function */ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this) @@ -59,13 +95,26 @@ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this) bool oldstate; char buf[8]; u_int segment; + struct stat sb; oldstate = thread_cancelability(TRUE); fifo = open(HA_FIFO, O_RDONLY); thread_cancelability(oldstate); - if (fifo == -1) + if (fifo == -1 || fstat(fifo, &sb) != 0 || !S_ISFIFO(sb.st_mode)) { - DBG1(DBG_CFG, "opening HA fifo failed: %s", strerror(errno)); + if (fifo == -1 && errno != ENOENT) + { + DBG1(DBG_CFG, "opening HA FIFO failed: %s", strerror(errno)); + } + else + { + DBG1(DBG_CFG, "%s is not a FIFO, recreate it", HA_FIFO); + recreate_fifo(); + } + if (fifo != -1) + { + close(fifo); + } sleep(1); return JOB_REQUEUE_FAIR; } @@ -100,6 +149,7 @@ static job_requeue_t dispatch_fifo(private_ha_ctl_t *this) METHOD(ha_ctl_t, destroy, void, private_ha_ctl_t *this) { + unlink(HA_FIFO); free(this); } @@ -109,7 +159,7 @@ METHOD(ha_ctl_t, destroy, void, ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache) { private_ha_ctl_t *this; - mode_t old; + struct stat sb; INIT(this, .public = { @@ -119,20 +169,30 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache) .cache = cache, ); - if (access(HA_FIFO, R_OK|W_OK) != 0) + if (stat(HA_FIFO, &sb) == 0) { - old = umask(S_IRWXO); - if (mkfifo(HA_FIFO, S_IRUSR | S_IWUSR) != 0) + if (!S_ISFIFO(sb.st_mode)) { - DBG1(DBG_CFG, "creating HA FIFO %s failed: %s", - HA_FIFO, strerror(errno)); + DBG1(DBG_CFG, "%s is not a FIFO, recreate it", HA_FIFO); + recreate_fifo(); + } + else if (access(HA_FIFO, R_OK|W_OK) != 0) + { + DBG1(DBG_CFG, "accessing HA FIFO %s denied, recreate it", HA_FIFO); + recreate_fifo(); + } + else + { + change_fifo_permissions(); } - umask(old); } - if (chown(HA_FIFO, lib->caps->get_uid(lib->caps), - lib->caps->get_gid(lib->caps)) != 0) + else if (errno == ENOENT) { - DBG1(DBG_CFG, "changing HA FIFO permissions failed: %s", + recreate_fifo(); + } + else + { + DBG1(DBG_CFG, "accessing HA FIFO %s failed: %s", HA_FIFO, strerror(errno)); } @@ -141,4 +201,3 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache) this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL)); return &this->public; } - diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index 31eeb934e..afa099309 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -135,6 +135,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty; chunk_t secret = chunk_empty, old_skd = chunk_empty; chunk_t dh_local = chunk_empty, dh_remote = chunk_empty, psk = chunk_empty; + host_t *other = NULL; bool ok = FALSE; enumerator = message->create_attribute_enumerator(message); @@ -150,6 +151,9 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message old_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, value.ike_sa_id); break; + case HA_REMOTE_ADDR: + other = value.host->clone(value.host); + break; case HA_IKE_VERSION: version = value.u8; break; @@ -252,6 +256,11 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message charon->ike_sa_manager, old_sa); old_sa = NULL; } + if (other) + { + ike_sa->set_other_host(ike_sa, other); + other = NULL; + } ike_sa->set_state(ike_sa, IKE_CONNECTING); ike_sa->set_proposal(ike_sa, proposal); this->cache->cache(this->cache, ike_sa, message); @@ -270,6 +279,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message { charon->ike_sa_manager->checkin(charon->ike_sa_manager, old_sa); } + DESTROY_IF(other); DESTROY_IF(message); } @@ -637,7 +647,7 @@ static void process_child_add(private_ha_dispatcher_t *this, u_int32_t inbound_spi = 0, outbound_spi = 0; u_int16_t inbound_cpi = 0, outbound_cpi = 0; u_int8_t mode = MODE_TUNNEL, ipcomp = 0; - u_int16_t encr = ENCR_UNDEFINED, integ = AUTH_UNDEFINED, len = 0; + u_int16_t encr = 0, integ = 0, len = 0; u_int16_t esn = NO_EXT_SEQ_NUMBERS; u_int seg_i, seg_o; chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty; diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index 6b4b53c9c..7492dd06e 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -138,6 +138,7 @@ METHOD(listener_t, ike_keys, bool, m->add_attribute(m, HA_PSK, shared->get_key(shared)); } } + m->add_attribute(m, HA_REMOTE_ADDR, ike_sa->get_other_host(ike_sa)); this->socket->push(this->socket, m); this->cache->cache(this->cache, ike_sa, m); diff --git a/src/libcharon/plugins/ha/ha_kernel.c b/src/libcharon/plugins/ha/ha_kernel.c index eed89e0bf..bd43dc351 100644 --- a/src/libcharon/plugins/ha/ha_kernel.c +++ b/src/libcharon/plugins/ha/ha_kernel.c @@ -36,6 +36,8 @@ typedef enum { JHASH_LOOKUP2, /* new variant, http://burtleburtle.net/bob/c/lookup3.c, since 2.6.37 */ JHASH_LOOKUP3, + /* variant with different init values, since 4.1 */ + JHASH_LOOKUP3_1, } jhash_version_t; typedef struct private_ha_kernel_t private_ha_kernel_t; @@ -88,8 +90,15 @@ static jhash_version_t get_jhash_version() } /* FALL */ case 2: - DBG1(DBG_CFG, "detected Linux %d.%d, using new jhash", a, b); - return JHASH_LOOKUP3; + if (a < 4 || (a == 4 && b == 0)) + { + DBG1(DBG_CFG, "detected Linux %d.%d, using new jhash", + a, b); + return JHASH_LOOKUP3; + } + DBG1(DBG_CFG, "detected Linux %d.%d, using new jhash with " + "updated init values", a, b); + return JHASH_LOOKUP3_1; default: break; } @@ -126,6 +135,14 @@ static u_int32_t jhash(jhash_version_t version, u_int32_t a, u_int32_t b) b -= c; b -= a; b ^= (a << 10); c -= a; c -= b; c ^= (b >> 15); break; + case JHASH_LOOKUP3_1: + /* changed with 4.1: # of 32-bit words shifted by 2 and c is + * initialized. we only use the two word variant with SPIs, so it's + * unlikely that b is 0 in that case */ + c += ((b ? 2 : 1) << 2) + 0xdeadbeef; + a += ((b ? 2 : 1) << 2); + b += ((b ? 2 : 1) << 2); + /* FALL */ case JHASH_LOOKUP3: a += 0xdeadbeef; b += 0xdeadbeef; |