diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1998-05-18 21:25:42 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1998-05-18 21:25:42 +0000 |
commit | 766b80be3e4beddda92a8835ad57042f38c1d941 (patch) | |
tree | 780da7aa6e314d6555e39c2e9bcffa81f3cca7d8 | |
parent | 36901152f2c312784811a6f7594f0612b974f4db (diff) |
support kernel notifies for setsockopt/getsockopt interface and fix various
small bugs.
-rw-r--r-- | sbin/ipsec/photurisd/config.c | 9 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_identity_request.c | 9 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_identity_response.c | 9 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_spi_needed.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/handle_spi_update.c | 7 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/identity.c | 15 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/kernel.c | 212 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/kernel.h | 9 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/schedule.c | 13 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/server.c | 40 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/server.h | 3 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/state.c | 6 | ||||
-rw-r--r-- | sbin/ipsec/photurisd/state.h | 23 |
13 files changed, 292 insertions, 69 deletions
diff --git a/sbin/ipsec/photurisd/config.c b/sbin/ipsec/photurisd/config.c index 1dbd1c02c4a..8b58f2ca048 100644 --- a/sbin/ipsec/photurisd/config.c +++ b/sbin/ipsec/photurisd/config.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: config.c,v 1.6 1998/03/04 11:43:15 provos Exp $"; +static char rcsid[] = "$Id: config.c,v 1.7 1998/05/18 21:25:20 provos Exp $"; #endif #define _CONFIG_C_ @@ -926,6 +926,11 @@ pick_attrib(struct stateob *st, u_int8_t **attrib, u_int16_t *attribsize) } } } + if (count == 0) { + log_error(0, "no attributes in attribute list for %s in pick_attrib()", + st->address); + return -1; + } if ((*attrib = calloc(count, sizeof(u_int8_t))) == NULL) { log_error(1, "calloc() in in pick_attrib()"); diff --git a/sbin/ipsec/photurisd/handle_identity_request.c b/sbin/ipsec/photurisd/handle_identity_request.c index fee093ad3e5..73d1affc8e9 100644 --- a/sbin/ipsec/photurisd/handle_identity_request.c +++ b/sbin/ipsec/photurisd/handle_identity_request.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: handle_identity_request.c,v 1.5 1998/03/04 11:43:20 provos Exp $"; +static char rcsid[] = "$Id: handle_identity_request.c,v 1.6 1998/05/18 21:25:23 provos Exp $"; #endif #include <stdio.h> @@ -296,7 +296,7 @@ handle_identity_request(u_char *packet, int size, char *address, spi_insert(spi); #ifdef IPSEC - kernel_insert_spi(spi); + kernel_insert_spi(st, spi); #endif schedule_insert(UPDATE, st->olifetime/2, spi->SPI, SPI_SIZE); } @@ -311,6 +311,7 @@ handle_identity_request(u_char *packet, int size, char *address, log_error(1, "strdup() in handle_identity_request()"); return -1; } + spi->flags |= st->flags & IPSEC_NOTIFY ? SPI_NOTIFY : 0; bcopy(st->icookie, spi->icookie, COOKIE_SIZE); spi->attribsize = st->uSPIattribsize; spi->attributes = calloc(spi->attribsize, sizeof(u_int8_t)); @@ -331,7 +332,7 @@ handle_identity_request(u_char *packet, int size, char *address, spi_insert(spi); #ifdef IPSEC - kernel_insert_spi(spi); + kernel_insert_spi(st, spi); #endif } diff --git a/sbin/ipsec/photurisd/handle_identity_response.c b/sbin/ipsec/photurisd/handle_identity_response.c index 8674421c8f7..258a232aac3 100644 --- a/sbin/ipsec/photurisd/handle_identity_response.c +++ b/sbin/ipsec/photurisd/handle_identity_response.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: handle_identity_response.c,v 1.5 1998/03/04 11:43:21 provos Exp $"; +static char rcsid[] = "$Id: handle_identity_response.c,v 1.6 1998/05/18 21:25:25 provos Exp $"; #endif #include <stdio.h> @@ -243,7 +243,7 @@ handle_identity_response(u_char *packet, int size, char *address, spi_insert(spi); #ifdef IPSEC - kernel_insert_spi(spi); + kernel_insert_spi(st, spi); #endif schedule_insert(UPDATE, st->olifetime/2, spi->SPI, SPI_SIZE); } @@ -257,6 +257,7 @@ handle_identity_response(u_char *packet, int size, char *address, log_error(1, "strdup() in handle_identity_response()"); return -1; } + spi->flags |= st->flags & IPSEC_NOTIFY ? SPI_NOTIFY : 0; bcopy(st->icookie, spi->icookie, COOKIE_SIZE); spi->attribsize = st->uSPIattribsize; spi->attributes = calloc(spi->attribsize, sizeof(u_int8_t)); @@ -277,7 +278,7 @@ handle_identity_response(u_char *packet, int size, char *address, spi_insert(spi); #ifdef IPSEC - kernel_insert_spi(spi); + kernel_insert_spi(st, spi); #endif } return 0; diff --git a/sbin/ipsec/photurisd/handle_spi_needed.c b/sbin/ipsec/photurisd/handle_spi_needed.c index 0cdb1946971..3ea5b20a3a2 100644 --- a/sbin/ipsec/photurisd/handle_spi_needed.c +++ b/sbin/ipsec/photurisd/handle_spi_needed.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: handle_spi_needed.c,v 1.5 1998/03/04 11:43:23 provos Exp $"; +static char rcsid[] = "$Id: handle_spi_needed.c,v 1.6 1998/05/18 21:25:27 provos Exp $"; #endif #include <stdio.h> @@ -190,7 +190,7 @@ handle_spi_needed(u_char *packet, int size, char *address, spi_insert(spi); schedule_insert(UPDATE, st->olifetime/2, spi->SPI, SPI_SIZE); #ifdef IPSEC - kernel_insert_spi(spi); + kernel_insert_spi(st, spi); #endif return 0; } diff --git a/sbin/ipsec/photurisd/handle_spi_update.c b/sbin/ipsec/photurisd/handle_spi_update.c index 3d5e284c867..7cde3dcce29 100644 --- a/sbin/ipsec/photurisd/handle_spi_update.c +++ b/sbin/ipsec/photurisd/handle_spi_update.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: handle_spi_update.c,v 1.5 1998/03/04 11:43:24 provos Exp $"; +static char rcsid[] = "$Id: handle_spi_update.c,v 1.6 1998/05/18 21:25:28 provos Exp $"; #endif #include <stdio.h> @@ -167,6 +167,7 @@ handle_spi_update(u_char *packet, int size, char *address, log_error(1, "calloc() in handle_spi_update()"); return -1; } + spi->flags |= st->flags & IPSEC_NOTIFY ? SPI_NOTIFY : 0; bcopy(attributes, spi->attributes, attribsize); spi->attribsize = attribsize; bcopy(st->icookie, spi->icookie, COOKIE_SIZE); @@ -178,7 +179,7 @@ handle_spi_update(u_char *packet, int size, char *address, spi_insert(spi); #ifdef IPSEC - kernel_insert_spi(spi); + kernel_insert_spi(st, spi); #endif return 0; } diff --git a/sbin/ipsec/photurisd/identity.c b/sbin/ipsec/photurisd/identity.c index e4ec661fcaf..90f91f15a9f 100644 --- a/sbin/ipsec/photurisd/identity.c +++ b/sbin/ipsec/photurisd/identity.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: identity.c,v 1.5 1998/03/04 11:43:29 provos Exp $"; +static char rcsid[] = "$Id: identity.c,v 1.6 1998/05/18 21:25:30 provos Exp $"; #endif #define _IDENTITY_C_ @@ -350,9 +350,14 @@ get_secrets(struct stateob *st, int mode) } } - if((strlen(remote_secret) == 0 && (mode & ID_REMOTE)) || - (strlen(local_ident) == 0 && (mode & (ID_LOCAL|ID_LOCALPAIR))) ) { - log_error(0, "Can't find identities or secrets in get_secrets()"); + if(strlen(remote_secret) == 0 && (mode & ID_REMOTE)) { + log_error(0, "Can't find remote secret for %s in get_secrets()", + st->uSPIident+2); + return -1; + } + + if (strlen(local_ident) == 0 && (mode & (ID_LOCAL|ID_LOCALPAIR)) ) { + log_error(0, "Can't find local identity in get_secrets()"); return -1; } diff --git a/sbin/ipsec/photurisd/kernel.c b/sbin/ipsec/photurisd/kernel.c index f4c29ebad52..8dab2f16130 100644 --- a/sbin/ipsec/photurisd/kernel.c +++ b/sbin/ipsec/photurisd/kernel.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,10 +28,23 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/* + * The following functions handle the interaction of the Photuris daemon + * with the PF_ENCAP interface as used by OpenBSD's IPSec implementation. + * This is the only file which needs to be changed for making Photuris + * work with other kernel interfaces. + * The SPI object here can actually hold two SPIs, one for encryption + * and one for authentication. + */ + #ifndef lint -static char rcsid[] = "$Id: kernel.c,v 1.7 1998/03/16 20:49:50 provos Exp $"; +static char rcsid[] = "$Id: kernel.c,v 1.8 1998/05/18 21:25:31 provos Exp $"; #endif +#include <time.h> +#include <sys/time.h> + #include <sys/param.h> #include <sys/file.h> #include <sys/socket.h> @@ -69,6 +82,7 @@ static char rcsid[] = "$Id: kernel.c,v 1.7 1998/03/16 20:49:50 provos Exp $"; #include "spi.h" #include "kernel.h" #include "errlog.h" +#include "server.h" #ifdef DEBUG #include "config.h" #endif @@ -159,7 +173,7 @@ kernel_get_socket(void) void kernel_set_socket_policy(int sd) { - u_char level; + int level; /* * Need to bypass system security policy, so I can send and @@ -168,13 +182,13 @@ kernel_set_socket_policy(int sd) level = IPSEC_LEVEL_BYPASS; /* Did I mention I'm privileged? */ if (setsockopt(sd, IPPROTO_IP, IP_AUTH_LEVEL, (char *)&level, - sizeof (u_char)) == -1) + sizeof (int)) == -1) crit_error(1, "setsockopt: can not bypass ipsec authentication policy"); if (setsockopt(sd, IPPROTO_IP, IP_ESP_TRANS_LEVEL, - (char *)&level, sizeof (u_char)) == -1) + (char *)&level, sizeof (int)) == -1) crit_error(1, "setsockopt: can not bypass ipsec esp transport policy"); if (setsockopt(sd, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, - (char *)&level, sizeof (u_char)) == -1) + (char *)&level, sizeof (int)) == -1) crit_error(1, "setsockopt: can not bypass ipsec esp network policy"); } @@ -235,7 +249,7 @@ kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, int proto) kernel_debug(("kernel_reserve_single_spi: %s, %08x\n", srcaddress, spi)); - bzero(buffer, EMT_ENABLESPI_FLEN); + bzero(buffer, EMT_RESERVESPI_FLEN); em = (struct encap_msghdr *)buffer; @@ -542,6 +556,10 @@ kernel_disable_spi(in_addr_t isrc, in_addr_t ismask, return 1; } +/* + * Remove a single SPI from the kernel database. + */ + int kernel_delete_spi(char *address, u_int8_t *spi, int proto) { @@ -569,8 +587,14 @@ kernel_delete_spi(char *address, u_int8_t *spi, int proto) return 1; } +/* + * Creates the correspondings SPI's with the kernel and establishes + * routing if necessary, i.e. when the SPIs were not created by + * kernel notifies. + */ + int -kernel_insert_spi(struct spiob *SPI) +kernel_insert_spi(struct stateob *st, struct spiob *SPI) { u_int8_t *spi; u_int8_t *attributes; @@ -641,13 +665,19 @@ kernel_insert_spi(struct spiob *SPI) log_error(0, "kernel_group_spi() in kernel_insert_spi()"); } - if (!(SPI->flags & SPI_OWNER) && !(SPI->flags & SPI_NOTIFY)) { - if (kernel_enable_spi(SPI->isrc, SPI->ismask, - SPI->idst, SPI->idmask, - SPI->address, spi, proto, - ENABLE_FLAG_REPLACE|ENABLE_FLAG_LOCAL) == -1) - log_error(0, "kernel_enable_spi() in kernel_insert_spi()"); - } + if (!(SPI->flags & SPI_OWNER)) + if (!(SPI->flags & SPI_NOTIFY)) { + if (kernel_enable_spi(SPI->isrc, SPI->ismask, + SPI->idst, SPI->idmask, + SPI->address, spi, proto, + ENABLE_FLAG_REPLACE|ENABLE_FLAG_LOCAL) == -1) + log_error(0, "kernel_enable_spi() in kernel_insert_spi()"); + } else { + /* + * Inform the kernel that we obtained the requested SA + */ + kernel_notify_result(st, SPI, proto); + } /* Is this what people call perfect forward security ? */ bzero(SPI->sessionkey, SPI->sessionkeysize); @@ -657,6 +687,14 @@ kernel_insert_spi(struct spiob *SPI) return 1; } +/* + * Deletes an SPI object, which means removing the SPIs from the + * kernel database and the deletion of all routes which were + * established on our behalf. Routes for SA's which were created by + * kernel notifies also get removed, since they are not any longer + * valid anyway. + */ + int kernel_unlink_spi(struct spiob *ospi) { @@ -736,3 +774,147 @@ kernel_unlink_spi(struct spiob *ospi) return 1; } + +/* + * Handles Notifies from the kernel, which can include Requests for new + * SAs, soft and hard expirations for already established SAs. + */ + +void +kernel_handle_notify(int sd) +{ + struct encap_msghdr em; + int msglen; + + if ((msglen = recvfrom(sd, (char *)&em, sizeof(em),0, NULL,0)) == -1) { + log_error(1, "recvfrom() in kernel_handle_notify()"); + return; + } + + if (msglen != em.em_msglen) { + log_error(0, "message length incorrect in kernel_handle_notify(): got %d where it should be %d", msglen, em.em_msglen); + return; + } + + if (em.em_type != EMT_NOTIFY) { + log_error(0, "message type is not notify in kernel_handle_notify()"); + return; + } + +#ifdef DEBUG + printf("Received EMT_NOTIFY message: subtype %d\n", em.em_not_type); +#endif + + switch (em.em_not_type) { + case NOTIFY_SOFT_EXPIRE: + case NOTIFY_HARD_EXPIRE: + log_error(0, "Notify is an SA Expiration - not yet supported.\n"); + return; + case NOTIFY_REQUEST_SA: +#ifdef DEBUG + printf("Notify SA Request for IP: %s, require %d\n", + inet_ntoa(em.em_not_dst), em.em_not_satype); +#endif + kernel_request_sa(&em); + break; + default: + log_error(0, "Unknown notify message in kernel_handle_notify"); + return; + } +} + +/* + * Tries to establish a new SA according to the information in a + * REQUEST_SA notify message received from the kernel. + */ + +int +kernel_request_sa(struct encap_msghdr *em) +{ + struct stateob *st; + time_t tm; + char *address = inet_ntoa(em->em_not_dst); + + /* Try to find an already established exchange which is still valid */ + st = state_find(address); + + tm = time(NULL); + while (st != NULL && st->lifetime <= tm) + st = state_find_next(st, address); + + if (st == NULL) { + /* No established exchange found, start a new one */ + if ((st = state_new()) == NULL) { + log_error(0, "state_new() failed in kernel_request_sa() for remote ip %s", + address); + return (-1); + } + /* Set up the state information */ + strncpy(st->address, address, sizeof(st->address)-1); + st->port = global_port; + st->sport = em->em_not_sport; + st->dport = em->em_not_dport; + st->protocol = em->em_not_protocol; + + /* + * For states which were created by kernel notifies we wont + * set up routes since other keying daemons might habe beaten + * us in establishing SAs. The kernel has to decide which SA + * will actually be routed. + */ + st->flags = IPSEC_NOTIFY; + if (em->em_not_satype & NOTIFY_SATYPE_CONF) + st->flags |= IPSEC_OPT_ENC; + if (em->em_not_satype & NOTIFY_SATYPE_AUTH) + st->flags |= IPSEC_OPT_AUTH; + /* XXX - handling of tunnel requests missing */ + if (start_exchange(global_socket, st, st->address, st->port) == -1) { + log_error(0, "start_exchange() in kernel_request_sa() - informing kernel of failure"); + /* Inform kernel of our failure */ + kernel_notify_result(st, NULL, 0); + state_value_reset(st); + free(st); + return (-1); + } else + state_insert(st); + } else { + /* + * We need different attributes for this exchange, send + * an SPI_NEEDED message. + */ + } +} + +/* + * Report the established SA or either our failure to create an SA + * to the kernel. + * Passing a SPI of NULL means failure. + */ + +void +kernel_notify_result(struct stateob *st, struct spiob *spi, int proto) +{ + struct encap_msghdr em; + + bzero((char *)&em, sizeof(em)); + em.em_type = EMT_NOTIFY; + em.em_msglen = EMT_NOTIFY_FLEN; + em.em_version = PFENCAP_VERSION_1; + em.em_not_type = NOTIFY_REQUEST_SA; + if (spi != NULL) { + em.em_not_spi = htonl((spi->SPI[0]<<24) + (spi->SPI[1]<<16) + + (spi->SPI[2]<<8) + spi->SPI[3]); + em.em_not_dst.s_addr = inet_addr(spi->address); + em.em_not_src.s_addr = inet_addr(spi->local_address); + em.em_not_sproto = proto; + } + if (st != NULL) { + em.em_not_dst.s_addr = inet_addr(st->address); + em.em_not_sport = st->sport; + em.em_not_dport = st->dport; + em.em_not_protocol = st->protocol; + } + + if (!kernel_xf_set(&em)) + log_error(1, "kernel_xf_set() in kernel_notify_result()"); +} diff --git a/sbin/ipsec/photurisd/kernel.h b/sbin/ipsec/photurisd/kernel.h index 625b2fdb426..92704d589fc 100644 --- a/sbin/ipsec/photurisd/kernel.h +++ b/sbin/ipsec/photurisd/kernel.h @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: kernel.h,v 1.5 1998/03/16 20:49:51 provos Exp $ */ +/* $Id: kernel.h,v 1.6 1998/05/18 21:25:33 provos Exp $ */ /* * kernel.h: * security paramter index creation. @@ -66,6 +66,7 @@ int kernel_disable_spi(in_addr_t isrc, in_addr_t ismask, char *address, u_int8_t *spi, int proto, int flags); int kernel_delete_spi(char *address, u_int8_t *spi, int proto); +int kernel_request_sa(struct encap_msghdr *em); #else #define EXTERN extern #endif @@ -77,10 +78,12 @@ EXTERN u_int32_t kernel_reserve_spi( char *srcaddress, int options); EXTERN u_int32_t kernel_reserve_single_spi(char *srcaddress, u_int32_t spi, int proto); -EXTERN int kernel_insert_spi(struct spiob *SPI); +EXTERN int kernel_insert_spi(struct stateob *st, struct spiob *SPI); EXTERN int kernel_unlink_spi(struct spiob *ospi); EXTERN int init_kernel(void); EXTERN int kernel_get_socket(void); EXTERN void kernel_set_socket_policy(int sd); +EXTERN void kernel_handle_notify(int sd); +EXTERN void kernel_notify_result(struct stateob *, struct spiob *, int); #endif /* _KERNEL_H */ diff --git a/sbin/ipsec/photurisd/schedule.c b/sbin/ipsec/photurisd/schedule.c index a0749558ba3..98973b5afb4 100644 --- a/sbin/ipsec/photurisd/schedule.c +++ b/sbin/ipsec/photurisd/schedule.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Parts derived from code by Angelos D. Keromytis, kermit@forthnet.gr @@ -35,7 +35,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: schedule.c,v 1.6 1998/03/04 11:43:49 provos Exp $"; +static char rcsid[] = "$Id: schedule.c,v 1.7 1998/05/18 21:25:35 provos Exp $"; #endif #define _SCHEDULE_C_ @@ -233,6 +233,9 @@ schedule_process(int sock) if (st->phase == COOKIE_REQUEST && st->resource == 0) { log_error(0, "no anwser for cookie request to %s:%d", st->address, st->port); +#ifdef IPSEC + kernel_notify_result(st, NULL, 0); +#endif break; } else if(st->phase == COOKIE_REQUEST) { /* Try again with updated counters */ @@ -280,8 +283,8 @@ schedule_process(int sock) } #ifdef DEBUG - printf("Resending packet type %d, length %d.\n", - st->phase, st->packetlen); + printf("Resending packet to %s type %d, length %d.\n", + st->address, st->phase, st->packetlen); #endif tmp->tm = tm + retrans_timeout; } @@ -374,7 +377,7 @@ schedule_process(int sock) spi_insert(nspi); schedule_insert(UPDATE, st->olifetime/2, nspi->SPI, SPI_SIZE); #ifdef IPSEC - kernel_insert_spi(nspi); + kernel_insert_spi(st, nspi); #endif break; default: diff --git a/sbin/ipsec/photurisd/server.c b/sbin/ipsec/photurisd/server.c index 4010799a6e0..718a17cd54a 100644 --- a/sbin/ipsec/photurisd/server.c +++ b/sbin/ipsec/photurisd/server.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Parts derived from code by Angelos D. Keromytis, kermit@forthnet.gr @@ -35,7 +35,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: server.c,v 1.4 1998/03/16 20:49:53 provos Exp $"; +static char rcsid[] = "$Id: server.c,v 1.5 1998/05/18 21:25:36 provos Exp $"; #endif #define _SERVER_C_ @@ -80,6 +80,8 @@ init_server(void) struct ifconf ifconf; char buf[1024]; + readfds = normfds = NULL; + if (global_port == 0) { #ifndef PHOTURIS_PORT struct servent *ser; @@ -101,6 +103,9 @@ init_server(void) setsockopt(global_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); +#ifdef IPSEC + kernel_set_socket_policy(global_socket); +#endif /* get the local addresses */ @@ -138,7 +143,11 @@ init_server(void) log_error(0, "%s is not a FIFO in init_server()", PHOTURIS_FIFO); /* We listen on a named pipe */ +#if defined(linux) || defined(_AIX) + if ((sockets[0] = open(PHOTURIS_FIFO, O_RDWR| O_NONBLOCK, 0)) == -1) +#else if ((sockets[0] = open(PHOTURIS_FIFO, O_RDONLY | O_NONBLOCK, 0)) == -1) +#endif crit_error(1, "open() in init_server()"); i = 1; /* One interface already */ @@ -227,18 +236,26 @@ server(void) { struct sockaddr_in sin; struct timeval timeout; - fd_set readfds, normfds; - int i, d; + int i, d, size; setvbuf(stdout, (char *)NULL, _IOLBF, 0); - FD_ZERO(&normfds); + size = howmany(sockets[num_ifs-1], NFDBITS) * sizeof(fd_mask); + normfds = (fd_set *)malloc(size); + if (normfds == NULL) + crit_error(1, "malloc(%d) for fd_set", size); + + readfds = (fd_set *)malloc(size); + if (readfds == NULL) + crit_error(1, "malloc(%d) for fd_set", size); + + memset((void *)normfds, 0, size); for (i=0; i<num_ifs; i++) - FD_SET(sockets[i], &normfds); + FD_SET(sockets[i], normfds); while (1) { - bcopy(&normfds, &readfds, sizeof(normfds)); + bcopy(normfds, readfds, size); /* Timeout till next job */ timeout.tv_usec = 0; @@ -249,7 +266,7 @@ server(void) #endif if (select(sockets[num_ifs-1]+1, - &readfds, (fd_set *) NULL, (fd_set *) NULL, + readfds, (fd_set *) NULL, (fd_set *) NULL, (timeout.tv_sec == -1 ? NULL : &timeout)) < 0) if (errno == EINTR) continue; @@ -257,9 +274,10 @@ server(void) crit_error(1, "select() in server()"); for (i=0; i<num_ifs; i++) { - if (FD_ISSET(sockets[i], &readfds)) { - /* XXX - As long as we have no PF_KEY */ - if (addresses[i] == NULL) + if (FD_ISSET(sockets[i], readfds)) { + if (i == 1) /* PF_ENCAP NOTIFIES */ + kernel_handle_notify(sockets[i]); + else if (addresses[i] == NULL) process_api(sockets[i], global_socket); else if (strcmp("127.0.0.1", inet_ntoa(sin.sin_addr))) { d = sizeof(struct sockaddr_in); diff --git a/sbin/ipsec/photurisd/server.h b/sbin/ipsec/photurisd/server.h index 708090a008d..8991de3118b 100644 --- a/sbin/ipsec/photurisd/server.h +++ b/sbin/ipsec/photurisd/server.h @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: server.h,v 1.1 1997/07/18 22:48:50 provos Exp $ */ +/* $Id: server.h,v 1.2 1998/05/18 21:25:38 provos Exp $ */ /* * server.h: * handling interfaces and communication @@ -47,5 +47,6 @@ EXTERN int init_server(void); EXTERN int server(void); EXTERN int global_port; EXTERN int global_socket; +EXTERN fd_set *readfds, *normfds; #endif /* _SERVER_H */ diff --git a/sbin/ipsec/photurisd/state.c b/sbin/ipsec/photurisd/state.c index 7a8d63dbe81..fe60213d6b2 100644 --- a/sbin/ipsec/photurisd/state.c +++ b/sbin/ipsec/photurisd/state.c @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -223,8 +223,8 @@ struct stateob * state_find(char *address) { struct stateob *tmp = stateob; - while(tmp!=NULL) { - if(address == NULL || !strcmp(address, tmp->address)) + while (tmp != NULL) { + if (address == NULL || !strcmp(address, tmp->address)) return tmp; tmp = tmp->next; } diff --git a/sbin/ipsec/photurisd/state.h b/sbin/ipsec/photurisd/state.h index dc5e7ecbd0b..302543be074 100644 --- a/sbin/ipsec/photurisd/state.h +++ b/sbin/ipsec/photurisd/state.h @@ -1,5 +1,5 @@ /* - * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> + * Copyright 1997,1998 Niels Provos <provos@physnet.uni-hamburg.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: state.h,v 1.6 1998/05/13 10:01:12 niklas Exp $ */ +/* $Id: state.h,v 1.7 1998/05/18 21:25:41 provos Exp $ */ /* * state.h: * state object @@ -47,13 +47,14 @@ #include "packets.h" /* Possible values of flags */ -#define IPSEC_OPT_ENC 0x001 /* Negotiate encryption */ -#define IPSEC_OPT_AUTH 0x002 /* Negotiate authentication */ -#define IPSEC_OPT_TUNNEL 0x004 /* Negotiate tunnel mode */ -#define IPSEC_OPT_REPLAY 0x100 /* Encryption with replay protection */ -#define IPSEC_OPT_ENC_AUTH 0x200 /* Encryption with authentication */ -#define IPSEC_OPT_XOR 0x400 /* Encryption with XOR */ -#define IPSEC_OPT_COMPRESS 0x800 /* Encryption with COMPRESS */ +#define IPSEC_OPT_ENC 0x0001 /* Negotiate encryption */ +#define IPSEC_OPT_AUTH 0x0002 /* Negotiate authentication */ +#define IPSEC_OPT_TUNNEL 0x0004 /* Negotiate tunne mode */ +#define IPSEC_OPT_REPLAY 0x0100 /* Encryption with replay protection */ +#define IPSEC_OPT_ENC_AUTH 0x0200 /* Encryption with authentication */ +#define IPSEC_OPT_XOR 0x0400 /* Encryption with XOR */ +#define IPSEC_OPT_COMPRESS 0x0800 /* Encryption with COMPRESS */ +#define IPSEC_NOTIFY 0x1000 /* State created by kernel notify */ struct stateob { struct stateob *next; /* Linked list */ @@ -67,7 +68,9 @@ struct stateob { in_addr_t idst, idmask; /* Accept destination for tunnel */ char address[16]; /* Remote address */ - u_int16_t port; /* Remote port */ + u_int16_t port; /* Remote port for Photuris daemon */ + u_int16_t sport, dport; /* Only used by notify at the moment */ + u_int8_t protocol; /* to pass back to the kernel */ u_int8_t icookie[COOKIE_SIZE]; /* Initator cookie */ u_int8_t rcookie[COOKIE_SIZE]; /* Responder cookie */ |