summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorprovos <provos@openbsd.org>2000-12-15 07:29:44 +0000
committerprovos <provos@openbsd.org>2000-12-15 07:29:44 +0000
commit13c5f470953bd7516812e7427cbb4e8d17551e50 (patch)
tree8ec26c1c4367a3716d3155448b21c98fa0f0f4a9
parentonly create new exchange on SA expires, when there has been used. (diff)
downloadwireguard-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.c43
-rw-r--r--sbin/photurisd/kernel.c117
-rw-r--r--sbin/photurisd/log.h6
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,