summaryrefslogtreecommitdiff
path: root/sbin/photurisd/state.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/photurisd/state.c')
-rw-r--r--sbin/photurisd/state.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/sbin/photurisd/state.c b/sbin/photurisd/state.c
new file mode 100644
index 00000000000..fe60213d6b2
--- /dev/null
+++ b/sbin/photurisd/state.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de>
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Niels Provos.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+/*
+ * state.c:
+ * functions for handling states
+ */
+
+#define _STATE_C_
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include "photuris.h"
+#include "state.h"
+#include "schedule.h"
+#include "errlog.h"
+
+static struct stateob *stateob = NULL;
+
+int
+state_insert(struct stateob *ob)
+{
+ struct stateob *tmp;
+
+ ob->next = NULL;
+
+ if(stateob == NULL) {
+ stateob = ob;
+ return 1;
+ }
+
+ tmp=stateob;
+ while(tmp->next!=NULL)
+ tmp = tmp->next;
+
+ tmp->next = ob;
+ return 1;
+}
+
+int
+state_unlink(struct stateob *ob)
+{
+ struct stateob *tmp;
+ if(stateob == ob) {
+ stateob = ob->next;
+ free(ob);
+ return 1;
+ }
+
+ for(tmp=stateob; tmp!=NULL; tmp=tmp->next) {
+ if(tmp->next==ob) {
+ tmp->next=ob->next;
+ free(ob);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+state_save_verification(struct stateob *st, u_int8_t *buf, u_int16_t len)
+{
+ if (st->verification == NULL || len > st->versize) {
+ if (st->verification != NULL)
+ free(st->verification);
+
+ if ((st->verification = calloc(len, sizeof(u_int8_t))) == NULL) {
+ log_error(1, "calloc() in state_save_verification()");
+ return -1;
+ }
+ }
+
+ bcopy(buf, st->verification, len);
+ st->versize = len;
+ return 0;
+}
+
+
+/*
+ * Copies configuration flags from one state to the other
+ */
+
+void
+state_copy_flags(struct stateob *src, struct stateob *dst)
+{
+ dst->initiator = src->initiator;
+
+ if (src->user != NULL)
+ dst->user = strdup(src->user);
+
+ dst->flags = src->flags;
+ dst->isrc = src->isrc;
+ dst->ismask = src->ismask;
+ dst->idst = src->idst;
+ dst->idmask = src->idmask;
+
+ strncpy(dst->address, src->address, sizeof(src->address)-1);
+ dst->address[sizeof(dst->address)-1] = 0;
+
+ dst->lifetime = src->lifetime;
+ dst->exchange_lifetime = src->exchange_lifetime;
+ dst->spi_lifetime = src->spi_lifetime;
+}
+
+struct stateob *
+state_new(void)
+{
+ struct stateob *p;
+
+ if((p = calloc(1, sizeof(struct stateob)))==NULL)
+ return NULL;
+
+ mpz_init(p->modulus);
+ mpz_init(p->generator);
+
+ p->exchange_lifetime = exchange_lifetime;
+ p->spi_lifetime = spi_lifetime;
+
+ return p;
+}
+
+int
+state_value_reset(struct stateob *ob)
+{
+ mpz_clear(ob->modulus);
+ mpz_clear(ob->generator);
+
+ if (ob->texchange != NULL)
+ free(ob->texchange);
+ if (ob->exchangevalue != NULL)
+ free(ob->exchangevalue);
+
+ if (ob->verification != NULL)
+ free(ob->verification);
+ if (ob->roschemes != NULL)
+ free(ob->roschemes);
+ if (ob->scheme != NULL)
+ free(ob->scheme);
+ if (ob->shared != NULL)
+ free(ob->shared);
+
+ if (ob->user != NULL)
+ free(ob->user);
+
+ if (ob->oSPIident != NULL)
+ free(ob->oSPIident);
+ if (ob->oSPIattrib != NULL)
+ free(ob->oSPIattrib);
+ if (ob->oSPIoattrib != NULL)
+ free(ob->oSPIoattrib);
+ if (ob->oSPIsecret != NULL)
+ free(ob->oSPIsecret);
+ if (ob->oSPIidentver != NULL)
+ free(ob->oSPIidentver);
+ if (ob->oSPIidentchoice != NULL)
+ free(ob->oSPIidentchoice);
+ if (ob->oSPIprivacyctx != NULL)
+ free(ob->oSPIprivacyctx);
+
+ if (ob->uSPIident != NULL)
+ free(ob->uSPIident);
+ if (ob->uSPIattrib != NULL)
+ free(ob->uSPIattrib);
+ if (ob->uSPIoattrib != NULL)
+ free(ob->uSPIoattrib);
+ if (ob->uSPIsecret != NULL)
+ free(ob->uSPIsecret);
+ if (ob->uSPIidentver != NULL)
+ free(ob->uSPIidentver);
+ if (ob->uSPIidentchoice != NULL)
+ free(ob->uSPIidentchoice);
+ if (ob->uSPIprivacyctx != NULL)
+ free(ob->uSPIprivacyctx);
+
+ if (ob->packet != NULL)
+ free(ob->packet);
+
+ return 1;
+}
+
+/*
+ * find the state ob with matching address
+ */
+
+struct stateob *
+state_root(void)
+{
+ return stateob;
+}
+
+struct stateob *
+state_find(char *address)
+{
+ struct stateob *tmp = stateob;
+ while (tmp != NULL) {
+ if (address == NULL || !strcmp(address, tmp->address))
+ return tmp;
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+struct stateob *
+state_find_next(struct stateob *prev, char *address)
+{
+ struct stateob *tmp = prev->next;
+ while(tmp!=NULL) {
+ if(address == NULL || !strcmp(address, tmp->address))
+ return tmp;
+ tmp = tmp->next;
+ }
+ return NULL;
+}
+
+
+struct stateob *
+state_find_cookies(char *address, u_int8_t *icookie, u_int8_t *rcookie)
+{
+ struct stateob *tmp;
+
+ tmp = state_find(address);
+ while(tmp!=NULL) {
+ if (!bcmp(tmp->icookie, icookie, COOKIE_SIZE) &&
+ (rcookie == NULL || !bcmp(tmp->rcookie, rcookie, COOKIE_SIZE)))
+ return tmp;
+ tmp = state_find_next(tmp, address);
+ }
+
+ return NULL;
+}
+
+void
+state_cleanup()
+{
+ struct stateob *p;
+ struct stateob *tmp = stateob;
+ while(tmp!=NULL) {
+ p = tmp;
+ tmp = tmp->next;
+ state_value_reset(p);
+ free(p);
+ }
+ stateob = NULL;
+}
+
+void
+state_expire(void)
+{
+ struct stateob *tmp = stateob, *p;
+ time_t tm;
+
+ tm = time(NULL);
+ while (tmp != NULL) {
+ if ((tmp->retries < max_retries || tmp->resource) &&
+ (tmp->lifetime == -1 || tmp->lifetime > tm)) {
+ tmp = tmp->next;
+ continue;
+ }
+#ifdef DEBUG
+ printf("Expiring state to %s in phase %d\n",
+ tmp->address, tmp->phase);
+#endif
+ p = tmp;
+ tmp = tmp->next;
+ state_value_reset(p);
+ state_unlink(p);
+ }
+}