mirror of
https://github.com/status-im/miniupnp.git
synced 2025-01-10 22:25:38 +00:00
Merge branch 'https'
Conflicts: miniupnpd/Makefile miniupnpd/pf/obsdrdr.c
This commit is contained in:
commit
1dd48971b9
@ -1,4 +1,7 @@
|
||||
$Id: Changelog.txt,v 1.366 2014/03/24 11:03:50 nanard Exp $
|
||||
$Id: Changelog.txt,v 1.368 2014/04/09 12:39:53 nanard Exp $
|
||||
|
||||
2014/04/09:
|
||||
Add HTTPS support and skeleton of DeviceProtection implementation
|
||||
|
||||
2014/03/24:
|
||||
start work to enable IPv6 PCP operations
|
||||
|
@ -142,6 +142,8 @@ LIBS = -lkvm
|
||||
LIBS += -lsocket -lnsl -lkstat -lresolv
|
||||
.endif
|
||||
|
||||
LIBS += -lssl -lcrypto
|
||||
|
||||
# set PREFIX variable to install in the wanted place
|
||||
|
||||
INSTALLBINDIR = $(PREFIX)/sbin
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.linux,v 1.84 2014/03/24 10:43:25 nanard Exp $
|
||||
# $Id: Makefile.linux,v 1.86 2014/04/09 07:22:28 nanard Exp $
|
||||
# MiniUPnP project
|
||||
# (c) 2006-2014 Thomas Bernard
|
||||
# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
@ -146,6 +146,8 @@ LIBS += $(shell pkg-config --static --libs-only-l libmnl)
|
||||
LIBS += $(shell pkg-config --static --libs-only-l libnetfilter_conntrack)
|
||||
endif # ($(TEST),1)
|
||||
|
||||
LIBS += $(shell pkg-config --static --libs-only-l libssl)
|
||||
|
||||
TESTUPNPDESCGENOBJS = testupnpdescgen.o upnpdescgen.o
|
||||
|
||||
EXECUTABLES = miniupnpd testupnpdescgen testgetifstats \
|
||||
|
@ -5,7 +5,7 @@
|
||||
#
|
||||
# To compile with pf with OS X 10.7+, you need to specify
|
||||
# path to XNU bsd sources :
|
||||
# INCLUDES="-I.../xnu/bsd I.../xnu/libkern" make -f Makefile.macosx
|
||||
# INCLUDES="-I.../xnu/bsd -I.../xnu/libkern" make -f Makefile.macosx
|
||||
#
|
||||
# To install use :
|
||||
# $ PREFIX=/dummyinstalldir make -f Makefile.macosx install
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# $Id: genconfig.sh,v 1.72 2014/03/10 10:17:17 nanard Exp $
|
||||
# $Id: genconfig.sh,v 1.74 2014/04/09 07:21:00 nanard Exp $
|
||||
# miniupnp daemon
|
||||
# http://miniupnp.free.fr or http://miniupnp.tuxfamily.org/
|
||||
# (c) 2006-2014 Thomas Bernard
|
||||
@ -443,6 +443,9 @@ echo "" >> ${CONFIGFILE}
|
||||
echo "#ifdef IGD_V2" >> ${CONFIGFILE}
|
||||
echo "/* Enable DeviceProtection service (IGDv2) */" >> ${CONFIGFILE}
|
||||
echo "#define ENABLE_DP_SERVICE" >> ${CONFIGFILE}
|
||||
echo "/*#define ENABLE_HTTPS*/" >> ${CONFIGFILE}
|
||||
echo "/*#define HTTPS_CERTFILE \"/path/to/certificate.pem\"*/" >> ${CONFIGFILE}
|
||||
echo "/*#define HTTPS_KEYFILE \"/path/to/private.key\"*/" >> ${CONFIGFILE}
|
||||
echo "" >> ${CONFIGFILE}
|
||||
echo "/* Enable WANIPv6FirewallControl service (IGDv2). needs IPv6 */" >> ${CONFIGFILE}
|
||||
echo "#ifdef ENABLE_IPV6" >> ${CONFIGFILE}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: minissdp.c,v 1.62 2014/03/24 09:31:23 nanard Exp $ */
|
||||
/* $Id: minissdp.c,v 1.64 2014/04/09 11:14:16 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
@ -33,6 +33,14 @@
|
||||
#define LL_SSDP_MCAST_ADDR "FF02::C"
|
||||
#define SL_SSDP_MCAST_ADDR "FF05::C"
|
||||
|
||||
/* maximum lenght of SSDP packets we are generating
|
||||
* (reception is done in a 1500byte buffer) */
|
||||
#ifdef ENABLE_HTTPS
|
||||
#define SSDP_PACKET_MAX_LEN 768
|
||||
#else
|
||||
#define SSDP_PACKET_MAX_LEN 512
|
||||
#endif
|
||||
|
||||
/* AddMulticastMembership()
|
||||
* param s socket
|
||||
* param ifaddr ip v4 address
|
||||
@ -336,11 +344,14 @@ EXT:
|
||||
static void
|
||||
SendSSDPResponse(int s, const struct sockaddr * addr,
|
||||
const char * st, int st_len, const char * suffix,
|
||||
const char * host, unsigned short port, const char * uuidvalue,
|
||||
unsigned int delay)
|
||||
const char * host, unsigned short http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short https_port,
|
||||
#endif
|
||||
const char * uuidvalue, unsigned int delay)
|
||||
{
|
||||
int l, n;
|
||||
char buf[512];
|
||||
char buf[SSDP_PACKET_MAX_LEN];
|
||||
char addr_str[64];
|
||||
socklen_t addrlen;
|
||||
int st_is_uuid;
|
||||
@ -375,6 +386,9 @@ SendSSDPResponse(int s, const struct sockaddr * addr,
|
||||
"EXT:\r\n"
|
||||
"SERVER: " MINIUPNPD_SERVER_STRING "\r\n"
|
||||
"LOCATION: http://%s:%u" ROOTDESC_PATH "\r\n"
|
||||
#ifdef ENABLE_HTTPS
|
||||
"SECURELOCATION.UPNP.ORG: https://%s:%u" ROOTDESC_PATH "\r\n"
|
||||
#endif
|
||||
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" /* UDA v1.1 */
|
||||
"01-NLS: %u\r\n" /* same as BOOTID. UDA v1.1 */
|
||||
"BOOTID.UPNP.ORG: %u\r\n" /* UDA v1.1 */
|
||||
@ -386,7 +400,10 @@ SendSSDPResponse(int s, const struct sockaddr * addr,
|
||||
st_len, st, suffix,
|
||||
uuidvalue, st_is_uuid ? "" : "::",
|
||||
st_is_uuid ? 0 : st_len, st, suffix,
|
||||
host, (unsigned int)port,
|
||||
host, (unsigned int)http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
host, (unsigned int)https_port,
|
||||
#endif
|
||||
upnp_bootid, upnp_bootid, upnp_configid);
|
||||
if(l<0)
|
||||
{
|
||||
@ -396,8 +413,8 @@ SendSSDPResponse(int s, const struct sockaddr * addr,
|
||||
}
|
||||
else if((unsigned)l>=sizeof(buf))
|
||||
{
|
||||
syslog(LOG_WARNING, "%s: truncated output",
|
||||
"SendSSDPResponse()");
|
||||
syslog(LOG_WARNING, "%s: truncated output (%u>=%u)",
|
||||
"SendSSDPResponse()", (unsigned)l, (unsigned)sizeof(buf));
|
||||
l = sizeof(buf) - 1;
|
||||
}
|
||||
addrlen = (addr->sa_family == AF_INET6)
|
||||
@ -452,19 +469,25 @@ static struct {
|
||||
|
||||
static void
|
||||
SendSSDPNotify(int s, const struct sockaddr * dest,
|
||||
const char * host, unsigned short port,
|
||||
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, int ipv6)
|
||||
{
|
||||
char bufr[512];
|
||||
char bufr[SSDP_PACKET_MAX_LEN];
|
||||
int n, 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:%d" ROOTDESC_PATH"\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"
|
||||
@ -477,18 +500,22 @@ SendSSDPNotify(int s, const struct sockaddr * dest,
|
||||
ipv6 ? "[" LL_SSDP_MCAST_ADDR "]" : SSDP_MCAST_ADDR,
|
||||
SSDP_PORT,
|
||||
lifetime,
|
||||
host, port,
|
||||
host, (unsigned int)http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
host, (unsigned int)https_port,
|
||||
#endif
|
||||
nt, suffix, /* NT: */
|
||||
usn1, usn2, usn3, suffix, /* USN: */
|
||||
upnp_bootid, upnp_bootid, upnp_configid );
|
||||
if(l<0)
|
||||
{
|
||||
syslog(LOG_ERR, "SendSSDPNotify() snprintf error");
|
||||
syslog(LOG_ERR, "%s: snprintf error", "SendSSDPNotify()");
|
||||
return;
|
||||
}
|
||||
else if((unsigned int)l >= sizeof(bufr))
|
||||
{
|
||||
syslog(LOG_WARNING, "SendSSDPNotify(): truncated output");
|
||||
syslog(LOG_WARNING, "%s: truncated output (%u>=%u)",
|
||||
"SendSSDPNotify()", (unsigned)l, (unsigned)sizeof(bufr));
|
||||
l = sizeof(bufr) - 1;
|
||||
}
|
||||
n = sendto_or_schedule(s, bufr, l, 0, dest,
|
||||
@ -525,9 +552,16 @@ SendSSDPNotify(int s, const struct sockaddr * dest,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
static void
|
||||
SendSSDPNotifies(int s, const char * host, unsigned short port,
|
||||
SendSSDPNotifies(int s, const char * host, unsigned short http_port,
|
||||
unsigned short https_port,
|
||||
unsigned int lifetime, int ipv6)
|
||||
#else
|
||||
static void
|
||||
SendSSDPNotifies(int s, const char * host, unsigned short http_port,
|
||||
unsigned int lifetime, int ipv6)
|
||||
#endif
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_storage sockname;
|
||||
@ -561,7 +595,10 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
||||
ver_str[0] = '\0';
|
||||
else
|
||||
snprintf(ver_str, sizeof(ver_str), "%d", known_service_types[i].version);
|
||||
SendSSDPNotify(s, (struct sockaddr *)&sockname, host, port,
|
||||
SendSSDPNotify(s, (struct sockaddr *)&sockname, host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].s, ver_str, /* NT: */
|
||||
known_service_types[i].uuid, "::",
|
||||
known_service_types[i].s, /* ver_str, USN: */
|
||||
@ -569,7 +606,10 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
||||
if(0==memcmp(known_service_types[i].s,
|
||||
"urn:schemas-upnp-org:device", sizeof("urn:schemas-upnp-org:device")-1))
|
||||
{
|
||||
SendSSDPNotify(s, (struct sockaddr *)&sockname, host, port,
|
||||
SendSSDPNotify(s, (struct sockaddr *)&sockname, host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].uuid, "", /* NT: */
|
||||
known_service_types[i].uuid, "", "", /* ver_str, USN: */
|
||||
lifetime, ipv6);
|
||||
@ -580,7 +620,10 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
||||
|
||||
void
|
||||
SendSSDPNotifies2(int * sockets,
|
||||
unsigned short port,
|
||||
unsigned short http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short https_port,
|
||||
#endif
|
||||
unsigned int lifetime)
|
||||
{
|
||||
int i;
|
||||
@ -589,13 +632,19 @@ SendSSDPNotifies2(int * sockets,
|
||||
lan_addr != NULL;
|
||||
lan_addr = lan_addr->list.le_next)
|
||||
{
|
||||
SendSSDPNotifies(sockets[i], lan_addr->str, port,
|
||||
SendSSDPNotifies(sockets[i], lan_addr->str, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
lifetime, 0);
|
||||
i++;
|
||||
#ifdef ENABLE_IPV6
|
||||
if(sockets[i] >= 0)
|
||||
{
|
||||
SendSSDPNotifies(sockets[i], ipv6_addr_for_http_with_brackets, port,
|
||||
SendSSDPNotifies(sockets[i], ipv6_addr_for_http_with_brackets, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
lifetime, 1);
|
||||
}
|
||||
i++;
|
||||
@ -606,7 +655,11 @@ SendSSDPNotifies2(int * sockets,
|
||||
/* ProcessSSDPRequest()
|
||||
* process SSDP M-SEARCH requests and responds to them */
|
||||
void
|
||||
ProcessSSDPRequest(int s, unsigned short port)
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPRequest(int s, unsigned short http_port, unsigned short https_port)
|
||||
#else
|
||||
ProcessSSDPRequest(int s, unsigned short http_port)
|
||||
#endif
|
||||
{
|
||||
int n;
|
||||
char bufr[1500];
|
||||
@ -633,13 +686,28 @@ ProcessSSDPRequest(int s, unsigned short port)
|
||||
}
|
||||
return;
|
||||
}
|
||||
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername, port);
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername,
|
||||
http_port, https_port);
|
||||
#else
|
||||
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername,
|
||||
http_port);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
void
|
||||
ProcessSSDPData(int s, const char *bufr, int n,
|
||||
const struct sockaddr * sender, unsigned short port) {
|
||||
const struct sockaddr * sender,
|
||||
unsigned short http_port, unsigned short https_port)
|
||||
#else
|
||||
void
|
||||
ProcessSSDPData(int s, const char *bufr, int n,
|
||||
const struct sockaddr * sender,
|
||||
unsigned short http_port)
|
||||
#endif
|
||||
{
|
||||
int i, l;
|
||||
struct lan_addr_s * lan_addr = NULL;
|
||||
const char * st = NULL;
|
||||
@ -847,7 +915,10 @@ ProcessSSDPData(int s, const char *bufr, int n,
|
||||
#else
|
||||
known_service_types[i].s, l, ver_str,
|
||||
#endif
|
||||
announced_host, port,
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].uuid,
|
||||
delay);
|
||||
break;
|
||||
@ -873,7 +944,10 @@ ProcessSSDPData(int s, const char *bufr, int n,
|
||||
l = (int)strlen(known_service_types[i].s);
|
||||
SendSSDPResponse(s, sender,
|
||||
known_service_types[i].s, l, ver_str,
|
||||
announced_host, port,
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].uuid,
|
||||
delay);
|
||||
}
|
||||
@ -882,17 +956,29 @@ ProcessSSDPData(int s, const char *bufr, int n,
|
||||
delay += delay_increment;
|
||||
#endif
|
||||
SendSSDPResponse(s, sender, uuidvalue_igd, strlen(uuidvalue_igd), "",
|
||||
announced_host, port, uuidvalue_igd, delay);
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_igd, delay);
|
||||
#ifdef DELAY_MSEARCH_RESPONSE
|
||||
delay += delay_increment;
|
||||
#endif
|
||||
SendSSDPResponse(s, sender, uuidvalue_wan, strlen(uuidvalue_wan), "",
|
||||
announced_host, port, uuidvalue_wan, delay);
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_wan, delay);
|
||||
#ifdef DELAY_MSEARCH_RESPONSE
|
||||
delay += delay_increment;
|
||||
#endif
|
||||
SendSSDPResponse(s, sender, uuidvalue_wcd, strlen(uuidvalue_wcd), "",
|
||||
announced_host, port, uuidvalue_wcd, delay);
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_wcd, delay);
|
||||
}
|
||||
/* responds to request by UUID value */
|
||||
l = (int)strlen(uuidvalue_igd);
|
||||
@ -905,22 +991,31 @@ ProcessSSDPData(int s, const char *bufr, int n,
|
||||
{
|
||||
syslog(LOG_INFO, "ssdp:uuid (IGD) found");
|
||||
SendSSDPResponse(s, sender, st, st_len, "",
|
||||
announced_host, port, uuidvalue_igd,
|
||||
delay);
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_igd, delay);
|
||||
}
|
||||
else if(0 == memcmp(st, uuidvalue_wan, l))
|
||||
{
|
||||
syslog(LOG_INFO, "ssdp:uuid (WAN) found");
|
||||
SendSSDPResponse(s, sender, st, st_len, "",
|
||||
announced_host, port, uuidvalue_wan,
|
||||
delay);
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_wan, delay);
|
||||
}
|
||||
else if(0 == memcmp(st, uuidvalue_wcd, l))
|
||||
{
|
||||
syslog(LOG_INFO, "ssdp:uuid (WCD) found");
|
||||
SendSSDPResponse(s, sender, st, st_len, "",
|
||||
announced_host, port, uuidvalue_wcd,
|
||||
delay);
|
||||
announced_host, http_port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_wcd, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -942,7 +1037,7 @@ SendSSDPbyebye(int s, const struct sockaddr * dest,
|
||||
int ipv6)
|
||||
{
|
||||
int n, l;
|
||||
char bufr[512];
|
||||
char bufr[SSDP_PACKET_MAX_LEN];
|
||||
|
||||
l = snprintf(bufr, sizeof(bufr),
|
||||
"NOTIFY * HTTP/1.1\r\n"
|
||||
@ -962,12 +1057,13 @@ SendSSDPbyebye(int s, const struct sockaddr * dest,
|
||||
upnp_bootid, upnp_bootid, upnp_configid);
|
||||
if(l<0)
|
||||
{
|
||||
syslog(LOG_ERR, "SendSSDPbyebye() snprintf error");
|
||||
syslog(LOG_ERR, "%s: snprintf error", "SendSSDPbyebye()");
|
||||
return -1;
|
||||
}
|
||||
else if((unsigned int)l >= sizeof(bufr))
|
||||
{
|
||||
syslog(LOG_WARNING, "SendSSDPbyebye(): truncated output");
|
||||
syslog(LOG_WARNING, "%s: truncated output (%u>=%u)",
|
||||
"SendSSDPbyebye()", (unsigned)l, (unsigned)sizeof(bufr));
|
||||
l = sizeof(bufr) - 1;
|
||||
}
|
||||
n = sendto_or_schedule(s, bufr, l, 0, dest,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: minissdp.h,v 1.10 2011/05/23 12:39:41 nanard Exp $ */
|
||||
/* $Id: minissdp.h,v 1.12 2014/04/09 07:20:59 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2007 Thomas Bernard
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
#ifndef MINISSDP_H_INCLUDED
|
||||
@ -14,28 +14,39 @@ OpenAndConfSSDPReceiveSocket(int ipv6);
|
||||
|
||||
int
|
||||
OpenAndConfSSDPNotifySockets(int * sockets);
|
||||
/*OpenAndConfSSDPNotifySockets(int * sockets,
|
||||
struct lan_addr_s * lan_addr, int n_lan_addr);*/
|
||||
|
||||
/*void
|
||||
SendSSDPNotifies(int s, const char * host, unsigned short port,
|
||||
unsigned int lifetime);*/
|
||||
#ifdef ENABLE_HTTPS
|
||||
void
|
||||
SendSSDPNotifies2(int * sockets,
|
||||
unsigned short port,
|
||||
unsigned short http_port,
|
||||
unsigned short https_port,
|
||||
unsigned int lifetime);
|
||||
/*SendSSDPNotifies2(int * sockets, struct lan_addr_s * lan_addr, int n_lan_addr,
|
||||
unsigned short port,
|
||||
unsigned int lifetime);*/
|
||||
#else
|
||||
void
|
||||
SendSSDPNotifies2(int * sockets,
|
||||
unsigned short http_port,
|
||||
unsigned int lifetime);
|
||||
#endif
|
||||
|
||||
void
|
||||
ProcessSSDPRequest(int s, unsigned short port);
|
||||
/*ProcessSSDPRequest(int s, struct lan_addr_s * lan_addr, int n_lan_addr,
|
||||
unsigned short port);*/
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPRequest(int s,
|
||||
unsigned short http_port, unsigned short https_port);
|
||||
#else
|
||||
ProcessSSDPRequest(int s, unsigned short http_port);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
void
|
||||
ProcessSSDPData(int s, const char *bufr, int n,
|
||||
const struct sockaddr * sendername, unsigned short port);
|
||||
const struct sockaddr * sendername,
|
||||
unsigned short http_port, unsigned short https_port);
|
||||
#else
|
||||
void
|
||||
ProcessSSDPData(int s, const char *bufr, int n,
|
||||
const struct sockaddr * sendername,
|
||||
unsigned short http_port);
|
||||
#endif
|
||||
|
||||
int
|
||||
SendSSDPGoodbye(int * sockets, int n);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: miniupnpd.c,v 1.190 2014/03/24 10:49:44 nanard Exp $ */
|
||||
/* $Id: miniupnpd.c,v 1.193 2014/04/09 14:08:11 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
@ -632,6 +632,9 @@ struct runtime_vars {
|
||||
/* LAN IP addresses for SSDP traffic and HTTP */
|
||||
/* moved to global vars */
|
||||
int port; /* HTTP Port */
|
||||
#ifdef ENABLE_HTTPS
|
||||
int https_port; /* HTTPS Port */
|
||||
#endif
|
||||
int notify_interval; /* seconds between SSDP announces */
|
||||
/* unused rules cleaning related variables : */
|
||||
int clean_ruleset_threshold; /* threshold for removing unused rules */
|
||||
@ -833,6 +836,9 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
||||
|
||||
LIST_INIT(&lan_addrs);
|
||||
v->port = -1;
|
||||
#ifdef ENABLE_HTTPS
|
||||
v->https_port = -1;
|
||||
#endif
|
||||
v->notify_interval = 30; /* seconds between SSDP announces */
|
||||
v->clean_ruleset_threshold = 20;
|
||||
v->clean_ruleset_interval = 0; /* interval between ruleset check. 0=disabled */
|
||||
@ -875,6 +881,11 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
||||
case UPNPPORT:
|
||||
v->port = atoi(ary_options[i].value);
|
||||
break;
|
||||
#ifdef ENABLE_HTTPS
|
||||
case UPNPHTTPSPORT:
|
||||
v->https_port = atoi(ary_options[i].value);
|
||||
break;
|
||||
#endif
|
||||
case UPNPBITRATE_UP:
|
||||
upstream_bitrate = strtoul(ary_options[i].value, 0, 0);
|
||||
break;
|
||||
@ -1126,6 +1137,16 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
||||
if(i+1 < argc)
|
||||
v->port = atoi(argv[++i]);
|
||||
else
|
||||
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
|
||||
break;
|
||||
#ifdef ENABLE_HTTPS
|
||||
case 'H':
|
||||
if(i+1 < argc)
|
||||
v->https_port = atoi(argv[++i]);
|
||||
else
|
||||
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
|
||||
break;
|
||||
#endif
|
||||
#ifdef ENABLE_NFQUEUE
|
||||
case 'Q':
|
||||
if(i+1<argc)
|
||||
@ -1148,8 +1169,6 @@ init(int argc, char * * argv, struct runtime_vars * v)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
fprintf(stderr, "Option -%c takes one argument.\n", argv[i][1]);
|
||||
break;
|
||||
case 'P':
|
||||
if(i+1 < argc)
|
||||
pidfilename = argv[++i];
|
||||
@ -1385,6 +1404,9 @@ print_usage:
|
||||
"\t\t[-a listening_ip]"
|
||||
#else
|
||||
"\t\t[-a listening_ip ext_ip]"
|
||||
#endif
|
||||
#ifdef ENABLE_HTTPS
|
||||
" [-H https_port]"
|
||||
#endif
|
||||
" [-p port] [-d]"
|
||||
#if defined(USE_PF) || defined(USE_IPF)
|
||||
@ -1453,6 +1475,12 @@ main(int argc, char * * argv)
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
int shttpl_v4 = -1; /* socket for HTTP (ipv4 only) */
|
||||
#endif
|
||||
#ifdef ENABLE_HTTPS
|
||||
int shttpsl = -1; /* socket for HTTPS */
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
int shttpsl_v4 = -1; /* socket for HTTPS (ipv4 only) */
|
||||
#endif
|
||||
#endif /* ENABLE_HTTPS */
|
||||
int sudp = -1; /* IP v4 socket for receiving SSDP */
|
||||
#ifdef ENABLE_IPV6
|
||||
int sudpv6 = -1; /* IP v6 socket for receiving SSDP */
|
||||
@ -1496,6 +1524,10 @@ main(int argc, char * * argv)
|
||||
|
||||
if(init(argc, argv, &v) != 0)
|
||||
return 1;
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(init_ssl() < 0)
|
||||
return 1;
|
||||
#endif /* ENABLE_HTTPS */
|
||||
/* count lan addrs */
|
||||
addr_count = 0;
|
||||
for(lan_addr = lan_addrs.lh_first; lan_addr != NULL; lan_addr = lan_addr->list.le_next)
|
||||
@ -1545,7 +1577,6 @@ main(int argc, char * * argv)
|
||||
|
||||
if(GETFLAG(ENABLEUPNPMASK))
|
||||
{
|
||||
|
||||
/* open socket for HTTP connections. Listen on the 1st LAN address */
|
||||
#ifdef ENABLE_IPV6
|
||||
shttpl = OpenAndConfHTTPSocket((v.port > 0) ? v.port : 0, 1);
|
||||
@ -1558,6 +1589,15 @@ main(int argc, char * * argv)
|
||||
return 1;
|
||||
}
|
||||
if(v.port <= 0) {
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in6);
|
||||
if (getsockname(shttpl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.port = ntohs(sockinfo.sin6_port);
|
||||
#else /* ENABLE_IPV6 */
|
||||
struct sockaddr_in sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
if (getsockname(shttpl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
@ -1565,6 +1605,7 @@ main(int argc, char * * argv)
|
||||
return 1;
|
||||
}
|
||||
v.port = ntohs(sockinfo.sin_port);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
}
|
||||
syslog(LOG_NOTICE, "HTTP listening on port %d", v.port);
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
@ -1575,6 +1616,47 @@ main(int argc, char * * argv)
|
||||
return 1;
|
||||
}
|
||||
#endif /* V6SOCKETS_ARE_V6ONLY */
|
||||
#ifdef ENABLE_HTTPS
|
||||
/* https */
|
||||
#ifdef ENABLE_IPV6
|
||||
shttpsl = OpenAndConfHTTPSocket((v.https_port > 0) ? v.https_port : 0, 1);
|
||||
#else /* ENABLE_IPV6 */
|
||||
shttpsl = OpenAndConfHTTPSocket((v.https_port > 0) ? v.https_port : 0);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
if(shttpl < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTPS. EXITING");
|
||||
return 1;
|
||||
}
|
||||
if(v.https_port <= 0) {
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in6);
|
||||
if (getsockname(shttpsl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.https_port = ntohs(sockinfo.sin6_port);
|
||||
#else /* ENABLE_IPV6 */
|
||||
struct sockaddr_in sockinfo;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
if (getsockname(shttpsl, (struct sockaddr *)&sockinfo, &len) < 0) {
|
||||
syslog(LOG_ERR, "getsockname(): %m");
|
||||
return 1;
|
||||
}
|
||||
v.https_port = ntohs(sockinfo.sin_port);
|
||||
#endif /* ENABLE_IPV6 */
|
||||
}
|
||||
syslog(LOG_NOTICE, "HTTPS listening on port %d", v.https_port);
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
shttpsl_v4 = OpenAndConfHTTPSocket(v.https_port, 0);
|
||||
if(shttpsl_v4 < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to open socket for HTTPS on port %hu (IPv4). EXITING", v.https_port);
|
||||
return 1;
|
||||
}
|
||||
#endif /* V6SOCKETS_ARE_V6ONLY */
|
||||
#endif /* ENABLE_HTTPS */
|
||||
#ifdef ENABLE_IPV6
|
||||
if(find_ipv6_addr(NULL, ipv6_addr_for_http_with_brackets, sizeof(ipv6_addr_for_http_with_brackets)) > 0) {
|
||||
syslog(LOG_NOTICE, "HTTP IPv6 address given to control points : %s",
|
||||
@ -1712,6 +1794,9 @@ main(int argc, char * * argv)
|
||||
if (GETFLAG(ENABLEUPNPMASK))
|
||||
SendSSDPNotifies2(snotify,
|
||||
(unsigned short)v.port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
(unsigned short)v.https_port,
|
||||
#endif
|
||||
v.notify_interval << 1);
|
||||
memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval));
|
||||
timeout.tv_sec = v.notify_interval;
|
||||
@ -1803,6 +1888,20 @@ main(int argc, char * * argv)
|
||||
max_fd = MAX( max_fd, shttpl_v4);
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_HTTPS
|
||||
if (shttpsl >= 0)
|
||||
{
|
||||
FD_SET(shttpsl, &readset);
|
||||
max_fd = MAX( max_fd, shttpsl);
|
||||
}
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
if (shttpsl_v4 >= 0)
|
||||
{
|
||||
FD_SET(shttpsl_v4, &readset);
|
||||
max_fd = MAX( max_fd, shttpsl_v4);
|
||||
}
|
||||
#endif
|
||||
#endif /* ENABLE_HTTPS */
|
||||
#ifdef ENABLE_IPV6
|
||||
if (sudpv6 >= 0)
|
||||
{
|
||||
@ -2040,13 +2139,21 @@ main(int argc, char * * argv)
|
||||
if(sudp >= 0 && FD_ISSET(sudp, &readset))
|
||||
{
|
||||
/*syslog(LOG_INFO, "Received UDP Packet");*/
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPRequest(sudp, (unsigned short)v.port, (unsigned short)v.https_port);
|
||||
#else
|
||||
ProcessSSDPRequest(sudp, (unsigned short)v.port);
|
||||
#endif
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
if(sudpv6 >= 0 && FD_ISSET(sudpv6, &readset))
|
||||
{
|
||||
syslog(LOG_INFO, "Received UDP Packet (IPv6)");
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPRequest(sudpv6, (unsigned short)v.port, (unsigned short)v.https_port);
|
||||
#else
|
||||
ProcessSSDPRequest(sudpv6, (unsigned short)v.port);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_IFACEWATCHER
|
||||
@ -2089,6 +2196,30 @@ main(int argc, char * * argv)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(shttpsl >= 0 && FD_ISSET(shttpsl, &readset))
|
||||
{
|
||||
struct upnphttp * tmp;
|
||||
tmp = ProcessIncomingHTTP(shttpsl);
|
||||
if(tmp)
|
||||
{
|
||||
InitSSL_upnphttp(tmp);
|
||||
LIST_INSERT_HEAD(&upnphttphead, tmp, entries);
|
||||
}
|
||||
}
|
||||
#if defined(V6SOCKETS_ARE_V6ONLY) && defined(ENABLE_IPV6)
|
||||
if(shttpsl_v4 >= 0 && FD_ISSET(shttpsl_v4, &readset))
|
||||
{
|
||||
struct upnphttp * tmp;
|
||||
tmp = ProcessIncomingHTTP(shttpsl_v4);
|
||||
if(tmp)
|
||||
{
|
||||
InitSSL_upnphttp(tmp);
|
||||
LIST_INSERT_HEAD(&upnphttphead, tmp, entries);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* ENABLE_HTTPS */
|
||||
#ifdef ENABLE_NFQUEUE
|
||||
/* process NFQ packets */
|
||||
if(nfqh >= 0 && FD_ISSET(nfqh, &readset))
|
||||
@ -2199,6 +2330,9 @@ shutdown:
|
||||
free(lan_addr);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
free_ssl();
|
||||
#endif
|
||||
#ifdef ENABLE_NATPMP
|
||||
free(snatpmp);
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* author: Ryan Wagoner
|
||||
* (c) 2006-2013 Thomas Bernard
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
@ -32,6 +32,10 @@ static const struct {
|
||||
{ UPNPEXT_IP, "ext_ip" },
|
||||
{ UPNPLISTENING_IP, "listening_ip" },
|
||||
{ UPNPPORT, "port" },
|
||||
{ UPNPPORT, "http_port" }, /* "port" and "http_port" are synonims */
|
||||
#ifdef ENABLE_HTTPS
|
||||
{ UPNPHTTPSPORT, "https_port" },
|
||||
#endif /* ENABLE_HTTPS */
|
||||
{ UPNPBITRATE_UP, "bitrate_up" },
|
||||
{ UPNPBITRATE_DOWN, "bitrate_down" },
|
||||
{ UPNPPRESENTATIONURL, "presentation_url" },
|
||||
@ -136,8 +140,10 @@ readoptionsfile(const char * fname)
|
||||
/* check for comments or empty lines */
|
||||
if(name[0] == '#' || name[0] == '\0') continue;
|
||||
|
||||
len = strlen(name); /* length of the whole line excluding leading
|
||||
* and ending white spaces */
|
||||
/* check for UPnP permissions rule */
|
||||
if(0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4))
|
||||
if((len > 6) && (0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4)))
|
||||
{
|
||||
tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
|
||||
if(tmp == NULL)
|
||||
@ -163,7 +169,7 @@ readoptionsfile(const char * fname)
|
||||
}
|
||||
#ifdef PCP_SADSCP
|
||||
/* check for DSCP values configuration */
|
||||
if(0 == memcmp(name, "set_learn_dscp", sizeof("set_learn_dscp")-1) )
|
||||
if((len > 15) && 0 == memcmp(name, "set_learn_dscp", sizeof("set_learn_dscp")-1) )
|
||||
{
|
||||
tmp = realloc(dscp_values_list, sizeof(struct dscp_values) * (num_dscp_values+1));
|
||||
if(tmp == NULL)
|
||||
@ -307,4 +313,3 @@ freeoptions(void)
|
||||
}
|
||||
|
||||
#endif /* DISABLE_CONFIG_FILE */
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* author: Ryan Wagoner
|
||||
* (c) 2006-2013 Thomas Bernard
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
@ -18,7 +18,10 @@ enum upnpconfigoptions {
|
||||
UPNPEXT_IFNAME = 1, /* ext_ifname */
|
||||
UPNPEXT_IP, /* ext_ip */
|
||||
UPNPLISTENING_IP, /* listening_ip */
|
||||
UPNPPORT, /* "port" */
|
||||
UPNPPORT, /* "port" / "http_port" */
|
||||
#ifdef ENABLE_HTTPS
|
||||
UPNPHTTPSPORT, /* "https_port" */
|
||||
#endif
|
||||
UPNPBITRATE_UP, /* "bitrate_up" */
|
||||
UPNPBITRATE_DOWN, /* "bitrate_down" */
|
||||
UPNPPRESENTATIONURL, /* presentation_url */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: $ */
|
||||
/* $Id: portinuse.c,v 1.3 2014/04/01 12:52:50 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* (c) 2007-2014 Thomas Bernard
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
@ -74,8 +74,10 @@ port_in_use(const char *if_name,
|
||||
const char * udpfile = "/proc/net/udp";
|
||||
#endif
|
||||
|
||||
if(getifaddr(if_name, ip_addr_str, INET_ADDRSTRLEN, &ip_addr, NULL) < 0)
|
||||
if(getifaddr(if_name, ip_addr_str, INET_ADDRSTRLEN, &ip_addr, NULL) < 0) {
|
||||
ip_addr.s_addr = 0;
|
||||
ip_addr_str[0] = '\0';
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "Check protocol %s for port %d on ext_if %s %s, %08X",
|
||||
(proto==IPPROTO_TCP)?"tcp":"udp", eport, if_name,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: upnphttp.c,v 1.87 2014/03/14 21:26:01 nanard Exp $ */
|
||||
/* $Id: upnphttp.c,v 1.91 2014/04/09 14:08:12 nanard Exp $ */
|
||||
/* Project : miniupnp
|
||||
* Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* Author : Thomas Bernard
|
||||
@ -29,6 +29,93 @@
|
||||
#include "upnpevents.h"
|
||||
#include "upnputils.h"
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/conf.h>
|
||||
static SSL_CTX *ssl_ctx = NULL;
|
||||
|
||||
#ifndef HTTPS_CERTFILE
|
||||
#define HTTPS_CERTFILE "/etc/ssl/certs/ssl-cert-snakeoil.pem"
|
||||
#endif
|
||||
#ifndef HTTPS_KEYFILE
|
||||
#define HTTPS_KEYFILE "/etc/ssl/private/ssl-cert-snakeoil.key"
|
||||
#endif
|
||||
|
||||
static void
|
||||
syslogsslerr(void)
|
||||
{
|
||||
unsigned long err;
|
||||
char buffer[256];
|
||||
while((err = ERR_get_error()) != 0) {
|
||||
syslog(LOG_ERR, "%s", ERR_error_string(err, buffer));
|
||||
}
|
||||
}
|
||||
|
||||
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
syslog(LOG_DEBUG, "verify_callback(%d, %p)", preverify_ok, ctx);
|
||||
return preverify_ok;
|
||||
}
|
||||
|
||||
int init_ssl(void)
|
||||
{
|
||||
SSL_METHOD *method;
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
method = TLSv1_server_method();
|
||||
if(method == NULL) {
|
||||
syslog(LOG_ERR, "TLSv1_server_method() failed");
|
||||
syslogsslerr();
|
||||
return -1;
|
||||
}
|
||||
ssl_ctx = SSL_CTX_new(method);
|
||||
if(ssl_ctx == NULL) {
|
||||
syslog(LOG_ERR, "SSL_CTX_new() failed");
|
||||
syslogsslerr();
|
||||
return -1;
|
||||
}
|
||||
/* set the local certificate */
|
||||
if(!SSL_CTX_use_certificate_file(ssl_ctx, HTTPS_CERTFILE, SSL_FILETYPE_PEM)) {
|
||||
syslog(LOG_ERR, "SSL_CTX_use_certificate_file(%s) failed", HTTPS_CERTFILE);
|
||||
syslogsslerr();
|
||||
return -1;
|
||||
}
|
||||
/* set the private key */
|
||||
if(!SSL_CTX_use_PrivateKey_file(ssl_ctx, HTTPS_KEYFILE, SSL_FILETYPE_PEM)) {
|
||||
syslog(LOG_ERR, "SSL_CTX_use_PrivateKey_file(%s) failed", HTTPS_KEYFILE);
|
||||
syslogsslerr();
|
||||
return -1;
|
||||
}
|
||||
/* verify private key */
|
||||
if(!SSL_CTX_check_private_key(ssl_ctx)) {
|
||||
syslog(LOG_ERR, "SSL_CTX_check_private_key() failed");
|
||||
syslogsslerr();
|
||||
return -1;
|
||||
}
|
||||
/*SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verify_callback);*/
|
||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, verify_callback);
|
||||
/*SSL_CTX_set_verify_depth(depth);*/
|
||||
syslog(LOG_INFO, "using %s", SSLeay_version(SSLEAY_VERSION));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_ssl(void)
|
||||
{
|
||||
/* free context */
|
||||
if(ssl_ctx != NULL) {
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
ssl_ctx = NULL;
|
||||
}
|
||||
ERR_remove_state(0);
|
||||
ENGINE_cleanup();
|
||||
CONF_modules_unload(1);
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
}
|
||||
#endif /* ENABLE_HTTPS */
|
||||
|
||||
struct upnphttp *
|
||||
New_upnphttp(int s)
|
||||
{
|
||||
@ -45,9 +132,40 @@ New_upnphttp(int s)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
void
|
||||
InitSSL_upnphttp(struct upnphttp * h)
|
||||
{
|
||||
int r;
|
||||
h->ssl = SSL_new(ssl_ctx);
|
||||
if(h->ssl == NULL) {
|
||||
syslog(LOG_ERR, "SSL_new() failed");
|
||||
syslogsslerr();
|
||||
abort();
|
||||
}
|
||||
if(!SSL_set_fd(h->ssl, h->socket)) {
|
||||
syslog(LOG_ERR, "SSL_set_fd() failed");
|
||||
syslogsslerr();
|
||||
abort();
|
||||
}
|
||||
r = SSL_accept(h->ssl); /* start the handshaking */
|
||||
if(r < 0) {
|
||||
int err;
|
||||
err = SSL_get_error(h->ssl, r);
|
||||
syslog(LOG_DEBUG, "SSL_accept() returned %d, SSL_get_error() %d", r, err);
|
||||
if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
|
||||
syslog(LOG_ERR, "SSL_accept() failed");
|
||||
syslogsslerr();
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_HTTPS */
|
||||
|
||||
void
|
||||
CloseSocket_upnphttp(struct upnphttp * h)
|
||||
{
|
||||
/* SSL_shutdown() ? */
|
||||
if(close(h->socket) < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "CloseSocket_upnphttp: close(%d): %m", h->socket);
|
||||
@ -61,6 +179,10 @@ Delete_upnphttp(struct upnphttp * h)
|
||||
{
|
||||
if(h)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl)
|
||||
SSL_free(h->ssl);
|
||||
#endif
|
||||
if(h->socket >= 0)
|
||||
CloseSocket_upnphttp(h);
|
||||
if(h->req_buf)
|
||||
@ -702,9 +824,29 @@ Process_upnphttp(struct upnphttp * h)
|
||||
switch(h->state)
|
||||
{
|
||||
case EWaitingForHttpRequest:
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
n = SSL_read(h->ssl, buf, sizeof(buf));
|
||||
} else {
|
||||
n = recv(h->socket, buf, sizeof(buf), 0);
|
||||
}
|
||||
#else
|
||||
n = recv(h->socket, buf, sizeof(buf), 0);
|
||||
#endif
|
||||
if(n<0)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
int err;
|
||||
err = SSL_get_error(h->ssl, n);
|
||||
if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
syslog(LOG_ERR, "SSL_read() failed");
|
||||
syslogsslerr();
|
||||
h->state = EToDelete;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if(errno != EAGAIN &&
|
||||
errno != EWOULDBLOCK &&
|
||||
errno != EINTR)
|
||||
@ -713,6 +855,9 @@ Process_upnphttp(struct upnphttp * h)
|
||||
h->state = EToDelete;
|
||||
}
|
||||
/* if errno is EAGAIN, EWOULDBLOCK or EINTR, try again later */
|
||||
#ifdef ENABLE_HTTPS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(n==0)
|
||||
{
|
||||
@ -749,9 +894,29 @@ Process_upnphttp(struct upnphttp * h)
|
||||
}
|
||||
break;
|
||||
case EWaitingForHttpContent:
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
n = SSL_read(h->ssl, buf, sizeof(buf));
|
||||
} else {
|
||||
n = recv(h->socket, buf, sizeof(buf), 0);
|
||||
}
|
||||
#else
|
||||
n = recv(h->socket, buf, sizeof(buf), 0);
|
||||
#endif
|
||||
if(n<0)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
int err;
|
||||
err = SSL_get_error(h->ssl, n);
|
||||
if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
syslog(LOG_ERR, "SSL_read() failed");
|
||||
syslogsslerr();
|
||||
h->state = EToDelete;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if(errno != EAGAIN &&
|
||||
errno != EWOULDBLOCK &&
|
||||
errno != EINTR)
|
||||
@ -760,6 +925,9 @@ Process_upnphttp(struct upnphttp * h)
|
||||
h->state = EToDelete;
|
||||
}
|
||||
/* if errno is EAGAIN, EWOULDBLOCK or EINTR, try again later */
|
||||
#ifdef ENABLE_HTTPS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(n==0)
|
||||
{
|
||||
@ -941,10 +1109,33 @@ SendResp_upnphttp(struct upnphttp * h)
|
||||
|
||||
while (h->res_sent < h->res_buflen)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
n = SSL_write(h->ssl, h->res_buf + h->res_sent,
|
||||
h->res_buflen - h->res_sent);
|
||||
} else {
|
||||
n = send(h->socket, h->res_buf + h->res_sent,
|
||||
h->res_buflen - h->res_sent, 0);
|
||||
}
|
||||
#else
|
||||
n = send(h->socket, h->res_buf + h->res_sent,
|
||||
h->res_buflen - h->res_sent, 0);
|
||||
#endif
|
||||
if(n<0)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
int err;
|
||||
err = SSL_get_error(h->ssl, n);
|
||||
if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
|
||||
/* try again later */
|
||||
return 0;
|
||||
}
|
||||
syslog(LOG_ERR, "SSL_write() failed");
|
||||
syslogsslerr();
|
||||
break;
|
||||
} else {
|
||||
#endif
|
||||
if(errno == EINTR)
|
||||
continue; /* try again immediatly */
|
||||
if(errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
@ -954,6 +1145,9 @@ SendResp_upnphttp(struct upnphttp * h)
|
||||
}
|
||||
syslog(LOG_ERR, "send(res_buf): %m");
|
||||
break; /* avoid infinite loop */
|
||||
#ifdef ENABLE_HTTPS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(n == 0)
|
||||
{
|
||||
@ -976,10 +1170,34 @@ SendRespAndClose_upnphttp(struct upnphttp * h)
|
||||
|
||||
while (h->res_sent < h->res_buflen)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
n = SSL_write(h->ssl, h->res_buf + h->res_sent,
|
||||
h->res_buflen - h->res_sent);
|
||||
} else {
|
||||
n = send(h->socket, h->res_buf + h->res_sent,
|
||||
h->res_buflen - h->res_sent, 0);
|
||||
}
|
||||
#else
|
||||
n = send(h->socket, h->res_buf + h->res_sent,
|
||||
h->res_buflen - h->res_sent, 0);
|
||||
#endif
|
||||
if(n<0)
|
||||
{
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl) {
|
||||
int err;
|
||||
err = SSL_get_error(h->ssl, n);
|
||||
if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
|
||||
/* try again later */
|
||||
h->state = ESendingAndClosing;
|
||||
return;
|
||||
}
|
||||
syslog(LOG_ERR, "SSL_write() failed");
|
||||
syslogsslerr();
|
||||
break; /* avoid infinite loop */
|
||||
} else {
|
||||
#endif
|
||||
if(errno == EINTR)
|
||||
continue; /* try again immediatly */
|
||||
if(errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
@ -990,6 +1208,9 @@ SendRespAndClose_upnphttp(struct upnphttp * h)
|
||||
}
|
||||
syslog(LOG_ERR, "send(res_buf): %m");
|
||||
break; /* avoid infinite loop */
|
||||
#ifdef ENABLE_HTTPS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(n == 0)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $Id: upnphttp.h,v 1.35 2012/10/03 21:03:50 nanard Exp $ */
|
||||
/* $Id: upnphttp.h,v 1.38 2014/04/09 14:08:13 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2012 Thomas Bernard
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
@ -13,6 +13,10 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
#include <openssl/ssl.h>
|
||||
#endif /* ENABLE_HTTPS */
|
||||
|
||||
#if 0
|
||||
/* according to "UPnP Device Architecture 1.0" */
|
||||
#define UPNP_VERSION_STRING "UPnP/1.0"
|
||||
@ -53,7 +57,10 @@ struct upnphttp {
|
||||
#ifdef ENABLE_IPV6
|
||||
int ipv6;
|
||||
struct in6_addr clientaddr_v6;
|
||||
#endif
|
||||
#endif /* ENABLE_IPV6 */
|
||||
#ifdef ENABLE_HTTPS
|
||||
SSL * ssl;
|
||||
#endif /* ENABLE_HTTPS */
|
||||
enum httpStates state;
|
||||
char HttpVer[16];
|
||||
/* request */
|
||||
@ -101,11 +108,20 @@ struct upnphttp {
|
||||
#define FLAG_ALLOW_POST 0x100
|
||||
#define FLAG_ALLOW_SUB_UNSUB 0x200
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
int init_ssl(void);
|
||||
void free_ssl(void);
|
||||
#endif /* ENABLE_HTTPS */
|
||||
|
||||
/* New_upnphttp() */
|
||||
struct upnphttp *
|
||||
New_upnphttp(int);
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
void
|
||||
InitSSL_upnphttp(struct upnphttp *);
|
||||
#endif /* ENABLE_HTTPS */
|
||||
|
||||
/* CloseSocket_upnphttp() */
|
||||
void
|
||||
CloseSocket_upnphttp(struct upnphttp *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: upnpsoap.c,v 1.122 2014/03/10 11:04:53 nanard Exp $ */
|
||||
/* $Id: upnpsoap.c,v 1.123 2014/04/09 12:39:54 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2014 Thomas Bernard
|
||||
@ -1827,6 +1827,104 @@ GetPinholePackets(struct upnphttp * h, const char * action)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DP_SERVICE
|
||||
static void
|
||||
SendSetupMessage(struct upnphttp * h, const char * action)
|
||||
{
|
||||
static const char resp[] =
|
||||
"<u:%sResponse "
|
||||
"xmlns:u=\"%s\">"
|
||||
"<NewOutMessage>%s</NewOutMessage>"
|
||||
"</u:%sResponse>";
|
||||
char body[1024];
|
||||
int bodylen;
|
||||
struct NameValueParserData data;
|
||||
const char * ProtocolType; /* string */
|
||||
const char * InMessage; /* base64 */
|
||||
const char * OutMessage = ""; /* base64 */
|
||||
|
||||
ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);
|
||||
ProtocolType = GetValueFromNameValueList(&data, "NewProtocolType"); /* string */
|
||||
InMessage = GetValueFromNameValueList(&data, "NewInMessage"); /* base64 */
|
||||
|
||||
if(ProtocolType == NULL || InMessage == NULL)
|
||||
{
|
||||
ClearNameValueList(&data);
|
||||
SoapError(h, 402, "Invalid Args");
|
||||
return;
|
||||
}
|
||||
/*if(strcmp(ProtocolType, "DeviceProtection:1") != 0)*/
|
||||
if(strcmp(ProtocolType, "WPS") != 0)
|
||||
{
|
||||
ClearNameValueList(&data);
|
||||
SoapError(h, 600, "Argument Value Invalid"); /* 703 ? */
|
||||
return;
|
||||
}
|
||||
/* TODO : put here code for WPS */
|
||||
|
||||
bodylen = snprintf(body, sizeof(body), resp,
|
||||
action, "urn:schemas-upnp-org:service:DeviceProtection:1",
|
||||
OutMessage, action);
|
||||
BuildSendAndCloseSoapResp(h, body, bodylen);
|
||||
ClearNameValueList(&data);
|
||||
}
|
||||
|
||||
static void
|
||||
GetSupportedProtocols(struct upnphttp * h, const char * action)
|
||||
{
|
||||
static const char resp[] =
|
||||
"<u:%sResponse "
|
||||
"xmlns:u=\"%s\">"
|
||||
"<NewProtocolList>%s</NewProtocolList>"
|
||||
"</u:%sResponse>";
|
||||
char body[1024];
|
||||
int bodylen;
|
||||
const char * ProtocolList =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<SupportedProtocols xmlns=\"urn:schemas-upnp-org:gw:DeviceProtection\""
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
|
||||
" xsi:schemaLocation=\"urn:schemas-upnp-org:gw:DeviceProtection"
|
||||
" http://www.upnp.org/schemas/gw/DeviceProtection-v1.xsd\">"
|
||||
"<Introduction><Name>WPS</Name></Introduction>"
|
||||
"<Login><Name>PKCS5</Name></Login>"
|
||||
"</SupportedProtocols>";
|
||||
|
||||
bodylen = snprintf(body, sizeof(body), resp,
|
||||
action, "urn:schemas-upnp-org:service:DeviceProtection:1",
|
||||
ProtocolList, action);
|
||||
BuildSendAndCloseSoapResp(h, body, bodylen);
|
||||
}
|
||||
|
||||
static void
|
||||
GetAssignedRoles(struct upnphttp * h, const char * action)
|
||||
{
|
||||
static const char resp[] =
|
||||
"<u:%sResponse "
|
||||
"xmlns:u=\"%s\">"
|
||||
"<NewRoleList>%s</NewRoleList>"
|
||||
"</u:%sResponse>";
|
||||
char body[1024];
|
||||
int bodylen;
|
||||
const char * RoleList = "Public"; /* list of roles separated by spaces */
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
if(h->ssl != NULL) {
|
||||
/* we should get the Roles of the session (based on client certificate) */
|
||||
X509 * peercert;
|
||||
peercert = SSL_get_peer_certificate(h->ssl);
|
||||
if(peercert != NULL) {
|
||||
RoleList = "Admin Basic";
|
||||
X509_free(peercert);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bodylen = snprintf(body, sizeof(body), resp,
|
||||
action, "urn:schemas-upnp-org:service:DeviceProtection:1",
|
||||
RoleList, action);
|
||||
BuildSendAndCloseSoapResp(h, body, bodylen);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Windows XP as client send the following requests :
|
||||
* GetConnectionTypeInfo
|
||||
@ -1884,6 +1982,12 @@ soapMethods[] =
|
||||
{ "DeletePinhole", DeletePinhole}, /* Required */
|
||||
{ "CheckPinholeWorking", CheckPinholeWorking}, /* Optional */
|
||||
{ "GetPinholePackets", GetPinholePackets}, /* Required */
|
||||
#endif
|
||||
#ifdef ENABLE_DP_SERVICE
|
||||
/* DeviceProtection */
|
||||
{ "SendSetupMessage", SendSetupMessage}, /* Required */
|
||||
{ "GetSupportedProtocols", GetSupportedProtocols}, /* Required */
|
||||
{ "GetAssignedRoles", GetAssignedRoles}, /* Required */
|
||||
#endif
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user