diff options
author | 2000-12-15 07:29:44 +0000 | |
---|---|---|
committer | 2000-12-15 07:29:44 +0000 | |
commit | 13c5f470953bd7516812e7427cbb4e8d17551e50 (patch) | |
tree | 8ec26c1c4367a3716d3155448b21c98fa0f0f4a9 | |
parent | only create new exchange on SA expires, when there has been used. (diff) | |
download | wireguard-openbsd-13c5f470953bd7516812e7427cbb4e8d17551e50.tar.xz wireguard-openbsd-13c5f470953bd7516812e7427cbb4e8d17551e50.zip |
return resource exhaustion message on memory allocation error. poll on
the pfkey fd so that we dont block when a message gets lossed.
-rw-r--r-- | sbin/photurisd/handle_value_request.c | 43 | ||||
-rw-r--r-- | sbin/photurisd/kernel.c | 117 | ||||
-rw-r--r-- | sbin/photurisd/log.h | 6 |
3 files changed, 101 insertions, 65 deletions
diff --git a/sbin/photurisd/handle_value_request.c b/sbin/photurisd/handle_value_request.c index 07588fb302d..d728c9339c7 100644 --- a/sbin/photurisd/handle_value_request.c +++ b/sbin/photurisd/handle_value_request.c @@ -29,12 +29,12 @@ */ /* * handle_value_request: - * receive a VALUE_REQUEST packet; return -1 on failure, 0 on success + * receive a VALUE_REQUEST packet; return (-1) on failure, 0 on success * */ #ifndef lint -static char rcsid[] = "$Id: handle_value_request.c,v 1.5 2000/12/15 02:50:38 provos Exp $"; +static char rcsid[] = "$Id: handle_value_request.c,v 1.6 2000/12/15 07:29:44 provos Exp $"; #endif #include <stdio.h> @@ -84,11 +84,11 @@ handle_value_request(u_char *packet, int size, u_int8_t rcookie[COOKIE_SIZE]; if (size < VALUE_REQUEST_MIN) - return -1; /* packet too small */ + return (-1); /* packet too small */ if (packet_check(packet, size, &vr_msg) == -1) { log_print("bad packet structure in handle_value_request()"); - return -1; + return (-1); } header = (struct value_request *) packet; @@ -112,7 +112,7 @@ handle_value_request(u_char *packet, int size, header->icookie, header->rcookie, header->counter, BAD_COOKIE); send_packet(); - return 0; + return (0); } /* Check exchange value - XXX doesn't check long form */ @@ -153,7 +153,7 @@ handle_value_request(u_char *packet, int size, sstart += scheme_get_len(schemes+sstart); } if (sstart >= ssize) - return -1; /* Did not find a scheme - XXX log */ + return (-1); /* Did not find a scheme - XXX log */ /* now check the exchange value */ test = BN_new(); @@ -182,7 +182,7 @@ handle_value_request(u_char *packet, int size, BN_free(mod); if ((st = state_new()) == NULL) - return -1; + goto resourcefail; /* Default options */ st->flags = IPSEC_OPT_ENC|IPSEC_OPT_AUTH; @@ -191,7 +191,7 @@ handle_value_request(u_char *packet, int size, st->uSPIoattrib = calloc(parts[1].size, sizeof(u_int8_t)); if (st->uSPIoattrib == NULL) { state_value_reset(st); - return -1; + goto resourcefail; } bcopy(parts[1].where, st->uSPIoattrib, parts[1].size); st->uSPIoattribsize = parts[1].size; @@ -206,7 +206,7 @@ handle_value_request(u_char *packet, int size, st->scheme = calloc(vsize, sizeof(u_int8_t)); if (st->scheme == NULL) { state_value_reset(st); - return -1; + goto resourcefail; } bcopy(header->scheme, st->scheme, 2); if (genp != NULL) { @@ -232,7 +232,8 @@ handle_value_request(u_char *packet, int size, st->texchange = calloc(st->texchangesize, sizeof(u_int8_t)); if (st->texchange == NULL) { log_error("calloc() in handle_value_request()"); - return -1; + state_value_reset(st); + goto resourcefail; } bcopy(parts[0].where, st->texchange, st->texchangesize); @@ -246,8 +247,9 @@ handle_value_request(u_char *packet, int size, bcopy(&header->counter, st->uSPITBV, 3); if ((st->roschemes = calloc(ssize, sizeof(u_int8_t))) == NULL) { + log_error("calloc() in handle_value_request()"); state_value_reset(st); - return -1; + goto resourcefail; } bcopy(schemes, st->roschemes, ssize); st->roschemesize = ssize; @@ -255,18 +257,23 @@ handle_value_request(u_char *packet, int size, if (pick_attrib(st, &(st->oSPIoattrib), &(st->oSPIoattribsize)) == -1) { state_value_reset(st); - return -1; + goto resourcefail; } st->lifetime = exchange_timeout + time(NULL); /* Now put the filled state object in the chain */ state_insert(st); + } else if (st->phase != VALUE_RESPONSE) { + LOG_DBG((LOG_PROTOCOL, 55, __FUNCTION__ + ": value request from %s, but we are in state %d", + st->address, st->phase)); + return (-1); } packet_size = PACKET_BUFFER_SIZE; if (photuris_value_response(st, packet_buffer, &packet_size) == -1) - return -1; + return (-1); send_packet(); @@ -288,5 +295,13 @@ handle_value_request(u_char *packet, int size, st->retries = 0; st->phase = VALUE_RESPONSE; - return 0; + return (0); + + resourcefail: + packet_size = PACKET_BUFFER_SIZE; + photuris_error_message(st, packet_buffer, &packet_size, + header->icookie, header->rcookie, + header->counter, RESOURCE_LIMIT); + send_packet(); + return (0); } diff --git a/sbin/photurisd/kernel.c b/sbin/photurisd/kernel.c index 4cd37fd5b81..3b8b2faad0a 100644 --- a/sbin/photurisd/kernel.c +++ b/sbin/photurisd/kernel.c @@ -39,7 +39,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: kernel.c,v 1.18 2000/12/15 02:42:08 provos Exp $"; +static char rcsid[] = "$Id: kernel.c,v 1.19 2000/12/15 07:29:44 provos Exp $"; #endif #include <time.h> @@ -64,6 +64,7 @@ static char rcsid[] = "$Id: kernel.c,v 1.18 2000/12/15 02:42:08 provos Exp $"; #include <stdlib.h> #include <string.h> #include <paths.h> +#include <poll.h> #include <net/pfkeyv2.h> #include <netinet/ip_ipsp.h> @@ -84,6 +85,8 @@ static char rcsid[] = "$Id: kernel.c,v 1.18 2000/12/15 02:42:08 provos Exp $"; #include "config.h" #endif +#define POLL_TIMEOUT 500 + #define SPITOINT(x) (((x)[0]<<24) + ((x)[1]<<16) + ((x)[2]<<8) + (x)[3]) #define KERNEL_XF_SET(x) kernel_xf_set(sd, buffer, BUFFER_SIZE, iov, cnt, x) @@ -329,56 +332,74 @@ kernel_queue_msg(struct sadb_msg *smsg) int kernel_xf_read(int sd, char *buffer, int blen, int seq) { - struct sadb_msg *sres = (struct sadb_msg *)buffer; - int len, forus; + struct sadb_msg *sres = (struct sadb_msg *)buffer; + int len, forus; + + /* + * Read in response from the kernel. If seq number and/or PID are + * given, we need to check PID and sequence number to see if it + * really is a message for us. + */ + do { + struct pollfd pfd; + + pfd.fd = sd; + pfd.events = POLLIN; + pfd.revents = 0; + + if (poll(&pfd, 1, POLL_TIMEOUT) == -1) { + log_error(__FUNCTION__": poll"); + return (0); + } - /* - * Read in response from the kernel. If seq number and/or PID are - * given, we need to check PID and sequence number to see if it - * really is a message for us. - */ - do { - if (recv(sd, sres, sizeof(*sres), MSG_PEEK) != sizeof(*sres)) { - log_error(__FUNCTION__": read()"); - return (0); - } - len = sres->sadb_msg_len * 8; - if (len >= BUFFER_SIZE) { - log_print(__FUNCTION__": PFKEYV2 message len %d too big", len); - return (0); - } - if (read(sd, sres, len) != len) { - log_error(__FUNCTION__": read()"); - return (0); - } + if (!(pfd.revents & POLLIN)) { + log_print(__FUNCTION__": no reply from pfkey"); + return (0); + } + + if (recv(sd, sres, sizeof(*sres), MSG_PEEK) != sizeof(*sres)) { + log_error(__FUNCTION__": read()"); + return (0); + } + len = sres->sadb_msg_len * 8; + if (len >= BUFFER_SIZE) { + log_print(__FUNCTION__ + ": PFKEYV2 message len %d too big", len); + return (0); + } + if (read(sd, sres, len) != len) { + log_error(__FUNCTION__": read()"); + return (0); + } - forus = !(sres->sadb_msg_pid && sres->sadb_msg_pid != pfkey_pid) && - !(seq && sres->sadb_msg_seq != seq); - - if (!forus) { - switch (sres->sadb_msg_type) { - case SADB_ACQUIRE: - case SADB_EXPIRE: - kernel_queue_msg(sres); - break; - default: - LOG_DBG((LOG_KERNEL, 50, __FUNCTION__ - ": skipping message type %d", - sres->sadb_msg_type)); - break; - } - } + forus = !(sres->sadb_msg_pid && + sres->sadb_msg_pid != pfkey_pid) && + !(seq && sres->sadb_msg_seq != seq); + + if (!forus) { + switch (sres->sadb_msg_type) { + case SADB_ACQUIRE: + case SADB_EXPIRE: + kernel_queue_msg(sres); + break; + default: + LOG_DBG((LOG_KERNEL, 50, __FUNCTION__ + ": skipping message type %d", + sres->sadb_msg_type)); + break; + } + } - } while (!forus); + } while (!forus); - if (sres->sadb_msg_errno) { - LOG_DBG((LOG_KERNEL, 40, __FUNCTION__": PFKEYV2 result: %s", - strerror(sres->sadb_msg_errno))); - errno = sres->sadb_msg_errno; - return (0); - } + if (sres->sadb_msg_errno) { + LOG_DBG((LOG_KERNEL, 40, __FUNCTION__": PFKEYV2 result: %s", + strerror(sres->sadb_msg_errno))); + errno = sres->sadb_msg_errno; + return (0); + } - return (1); + return (1); } int @@ -1090,12 +1111,12 @@ kernel_unlink_spi(struct spiob *ospi) if (esp != NULL) { if (kernel_delete_spi(p, SPITOINT(ospi->SPI), IPPROTO_ESP) == -1) - log_print(__FUNCTION__": kernel_delete_spi()"); + log_print(__FUNCTION__": kernel_delete_spi() failed"); } if (ah != NULL) { if (kernel_delete_spi(p, SPITOINT(ospi->SPI), IPPROTO_AH) == -1) - log_print(__FUNCTION__": kernel_delete_spi()"); + log_print(__FUNCTION__": kernel_delete_spi() failed"); } return (1); diff --git a/sbin/photurisd/log.h b/sbin/photurisd/log.h index 43d5379ded9..53c4d774a4b 100644 --- a/sbin/photurisd/log.h +++ b/sbin/photurisd/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.2 2000/12/14 23:28:58 provos Exp $ */ +/* $OpenBSD: log.h,v 1.3 2000/12/15 07:29:45 provos Exp $ */ /* $EOM: log.h,v 1.19 2000/03/30 14:27:23 ho Exp $ */ /* @@ -47,11 +47,11 @@ #define LOG_SIZE 200 enum log_classes { - LOG_MISC, LOG_TRANSPORT, LOG_CRYPTO, LOG_TIMER, LOG_SPI, LOG_KERNEL, + LOG_MISC, LOG_PROTOCOL, LOG_CRYPTO, LOG_TIMER, LOG_SPI, LOG_KERNEL, LOG_ENDCLASS }; #define LOG_CLASSES_TEXT \ - { "Misc", "Trpt", "Cryp", "Timr", "SPI ", "Kern" } + { "Misc", "Prot", "Cryp", "Timr", "SPI ", "Kern" } /* * "Class" LOG_REPORT will always be logged to the current log channel, |