From 359c5d8805608121f26cbd59e96d0e8be358d8e6 Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Sat, 24 Oct 2015 17:02:11 +0200 Subject: [PATCH] add a validation of SSDP packet generation checks it doesn't overflow SSDP_PACKET_MAX_LEN --- miniupnpd/.gitignore | 2 + miniupnpd/Makefile.linux | 14 ++++-- miniupnpd/testssdppktgen.c | 100 +++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 miniupnpd/testssdppktgen.c diff --git a/miniupnpd/.gitignore b/miniupnpd/.gitignore index e7446c7..2bf6061 100644 --- a/miniupnpd/.gitignore +++ b/miniupnpd/.gitignore @@ -17,3 +17,5 @@ netfilter/testiptcrdr_peer testdescs validateupnppermissions validategetifaddr +testssdppktgen +validatessdppktgen diff --git a/miniupnpd/Makefile.linux b/miniupnpd/Makefile.linux index bcd02b1..48b69f3 100644 --- a/miniupnpd/Makefile.linux +++ b/miniupnpd/Makefile.linux @@ -153,7 +153,8 @@ TESTUPNPDESCGENOBJS = testupnpdescgen.o upnpdescgen.o EXECUTABLES = miniupnpd testupnpdescgen testgetifstats \ testupnppermissions miniupnpdctl testgetifaddr \ - testgetroute testasyncsendto testportinuse + testgetroute testasyncsendto testportinuse \ + testssdppktgen .PHONY: all clean install depend genuuid @@ -198,7 +199,7 @@ else sed -i -e "s/^uuid=[-0-9a-f]*/uuid=`($(STAGING_DIR_HOST)/bin/genuuid||$(STAGING_DIR_HOST)/bin/uuidgen||$(STAGING_DIR_HOST)/bin/uuid) 2>/dev/null`/" miniupnpd.conf endif -check: validateupnppermissions validategetifaddr +check: validateupnppermissions validategetifaddr validatessdppktgen validateupnppermissions: testupnppermissions testupnppermissions.sh ./testupnppermissions.sh @@ -208,6 +209,10 @@ validategetifaddr: testgetifaddr testgetifaddr.sh ./testgetifaddr.sh touch $@ +validatessdppktgen: testssdppktgen + ./testssdppktgen + touch $@ + miniupnpd: $(BASEOBJS) $(LNXOBJS) $(NETFILTEROBJS) testupnpdescgen: $(TESTUPNPDESCGENOBJS) @@ -220,6 +225,8 @@ testgetifaddr: testgetifaddr.o getifaddr.o testgetroute: testgetroute.o linux/getroute.o upnputils.o +testssdppktgen: testssdppktgen.o + testasyncsendto: testasyncsendto.o asyncsendto.o upnputils.o \ linux/getroute.o @@ -236,7 +243,7 @@ depend: config.h $(ALLOBJS:.o=.c) $(TESTUPNPDESCGENOBJS:.o=.c) \ testgetifstats.c testupnppermissions.c testgetifaddr.c \ testgetroute.c testasyncsendto.c testportinuse.c \ - miniupnpdctl.c 2>/dev/null + miniupnpdctl.c testssdppktgen.c 2>/dev/null # DO NOT DELETE @@ -313,3 +320,4 @@ testgetroute.o: config.h miniupnpdtypes.h testasyncsendto.o: miniupnpdtypes.h config.h upnputils.h asyncsendto.h testportinuse.o: macros.h config.h portinuse.h miniupnpdctl.o: macros.h +testssdppktgen.o: macros.h config.h miniupnpdpath.h upnphttp.h diff --git a/miniupnpd/testssdppktgen.c b/miniupnpd/testssdppktgen.c new file mode 100644 index 0000000..5de7998 --- /dev/null +++ b/miniupnpd/testssdppktgen.c @@ -0,0 +1,100 @@ +/* $Id: $ */ +#include +#include +#include + +#include "config.h" +#include "miniupnpdpath.h" +#include "upnphttp.h" +#include "macros.h" + +#define SSDP_PORT 1900 + +char uuidvalue_igd[] = "uuid:12345678-0000-0000-0000-000000abcd01"; +unsigned upnp_bootid; +unsigned upnp_configid; + +static int +MakeSSDPPacket(const char * dest_str, + const char * host, unsigned short http_port, +#ifdef ENABLE_HTTPS + unsigned short https_port, +#endif + const char * nt, const char * suffix, + const char * usn1, const char * usn2, const char * usn3, + unsigned int lifetime) +{ + char bufr[SSDP_PACKET_MAX_LEN]; + int l; + + l = snprintf(bufr, sizeof(bufr), + "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%d\r\n" + "CACHE-CONTROL: max-age=%u\r\n" + "LOCATION: http://%s:%u" ROOTDESC_PATH "\r\n" +#ifdef ENABLE_HTTPS + "SECURELOCATION.UPNP.ORG: https://%s:%u" ROOTDESC_PATH "\r\n" +#endif + "SERVER: " MINIUPNPD_SERVER_STRING "\r\n" + "NT: %s%s\r\n" + "USN: %s%s%s%s\r\n" + "NTS: ssdp:alive\r\n" + "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" /* UDA v1.1 */ + "01-NLS: %u\r\n" /* same as BOOTID field. UDA v1.1 */ + "BOOTID.UPNP.ORG: %u\r\n" /* UDA v1.1 */ + "CONFIGID.UPNP.ORG: %u\r\n" /* UDA v1.1 */ + "\r\n", + dest_str, SSDP_PORT, /* HOST: */ + lifetime, /* CACHE-CONTROL: */ + host, (unsigned int)http_port, /* LOCATION: */ +#ifdef ENABLE_HTTPS + host, (unsigned int)https_port, /* SECURE-LOCATION: */ +#endif + nt, suffix, /* NT: */ + usn1, usn2, usn3, suffix, /* USN: */ + upnp_bootid, /* 01-NLS: */ + upnp_bootid, /* BOOTID.UPNP.ORG: */ + upnp_configid ); /* CONFIGID.UPNP.ORG: */ + if(l<0) { + syslog(LOG_ERR, "%s: snprintf error", "MakeSSDPPacket()"); + return -1; + } else if((unsigned int)l >= sizeof(bufr)) { + syslog(LOG_WARNING, "%s: truncated output (%u>=%u)", + "MakeSSDPPacket()", (unsigned)l, (unsigned)sizeof(bufr)); + l = sizeof(bufr) - 1; + return -1; + } + return 0; +} + + +int main(int argc, char * * argv) +{ + int r; + UNUSED(argc); UNUSED(argv); + + openlog("testssdppktgen", LOG_CONS|LOG_PERROR, LOG_USER); + upnp_bootid = (unsigned)time(NULL); + upnp_configid = 1234567890; + r = MakeSSDPPacket("123.456.789.123", "222.222.222.222", 12345, +#ifdef ENABLE_HTTPS + 54321, +#endif /* ENABLE_HTTPS */ + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", "1", + uuidvalue_igd, "", "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", + 1234567890); + if(r < 0) return 1; +#ifdef ENABLE_IPV6 + r = MakeSSDPPacket("[1234:5678:abcd:ef00:1234:5678:abcd:ef00]", + "[1000:2000:3000:4000:5000:6000:7000:8000]", 12345, +#ifdef ENABLE_HTTPS + 54321, +#endif /* ENABLE_HTTPS */ + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", "1", + uuidvalue_igd, "", "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:", + 1234567890); + if(r < 0) return 1; +#endif /* ENABLE_IPV6 */ + return 0; +} +