miniupnpd: adding HTTPS support
This commit is contained in:
parent
29e951c1e5
commit
bbe96a15b6
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile,v 1.80 2014/04/07 10:32:20 nanard Exp $
|
||||
# $Id: Makefile,v 1.81 2014/04/09 10:30:08 nanard Exp $
|
||||
# MiniUPnP project
|
||||
# http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
# Author: Thomas Bernard
|
||||
|
@ -138,6 +138,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 \
|
||||
|
|
|
@ -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,7 @@ 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 "" >> ${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
|
||||
|
@ -336,8 +336,11 @@ 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 port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short https_port,
|
||||
#endif
|
||||
const char * uuidvalue, unsigned int delay)
|
||||
{
|
||||
int l, n;
|
||||
char buf[512];
|
||||
|
@ -375,6 +378,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 */
|
||||
|
@ -387,6 +393,9 @@ SendSSDPResponse(int s, const struct sockaddr * addr,
|
|||
uuidvalue, st_is_uuid ? "" : "::",
|
||||
st_is_uuid ? 0 : st_len, st, suffix,
|
||||
host, (unsigned int)port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
host, (unsigned int)https_port,
|
||||
#endif
|
||||
upnp_bootid, upnp_bootid, upnp_configid);
|
||||
if(l<0)
|
||||
{
|
||||
|
@ -453,6 +462,9 @@ static struct {
|
|||
static void
|
||||
SendSSDPNotify(int s, const struct sockaddr * dest,
|
||||
const char * host, unsigned short 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)
|
||||
|
@ -464,7 +476,10 @@ SendSSDPNotify(int s, const struct sockaddr * dest,
|
|||
"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,13 +492,16 @@ SendSSDPNotify(int s, const struct sockaddr * dest,
|
|||
ipv6 ? "[" LL_SSDP_MCAST_ADDR "]" : SSDP_MCAST_ADDR,
|
||||
SSDP_PORT,
|
||||
lifetime,
|
||||
host, port,
|
||||
host, (unsigned int)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))
|
||||
|
@ -527,6 +545,9 @@ SendSSDPNotify(int s, const struct sockaddr * dest,
|
|||
|
||||
static void
|
||||
SendSSDPNotifies(int s, const char * host, unsigned short port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short https_port,
|
||||
#endif
|
||||
unsigned int lifetime, int ipv6)
|
||||
{
|
||||
#ifdef ENABLE_IPV6
|
||||
|
@ -562,6 +583,9 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
|||
else
|
||||
snprintf(ver_str, sizeof(ver_str), "%d", known_service_types[i].version);
|
||||
SendSSDPNotify(s, (struct sockaddr *)&sockname, host, 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: */
|
||||
|
@ -570,6 +594,9 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
|||
"urn:schemas-upnp-org:device", sizeof("urn:schemas-upnp-org:device")-1))
|
||||
{
|
||||
SendSSDPNotify(s, (struct sockaddr *)&sockname, host, port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].uuid, "", /* NT: */
|
||||
known_service_types[i].uuid, "", "", /* ver_str, USN: */
|
||||
lifetime, ipv6);
|
||||
|
@ -581,6 +608,9 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
|||
void
|
||||
SendSSDPNotifies2(int * sockets,
|
||||
unsigned short port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short https_port,
|
||||
#endif
|
||||
unsigned int lifetime)
|
||||
{
|
||||
int i;
|
||||
|
@ -590,12 +620,18 @@ SendSSDPNotifies2(int * sockets,
|
|||
lan_addr = lan_addr->list.le_next)
|
||||
{
|
||||
SendSSDPNotifies(sockets[i], lan_addr->str, 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,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
lifetime, 1);
|
||||
}
|
||||
i++;
|
||||
|
@ -606,7 +642,11 @@ SendSSDPNotifies2(int * sockets,
|
|||
/* ProcessSSDPRequest()
|
||||
* process SSDP M-SEARCH requests and responds to them */
|
||||
void
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPRequest(int s, unsigned short port, unsigned short https_port)
|
||||
#else
|
||||
ProcessSSDPRequest(int s, unsigned short port)
|
||||
#endif
|
||||
{
|
||||
int n;
|
||||
char bufr[1500];
|
||||
|
@ -633,13 +673,24 @@ ProcessSSDPRequest(int s, unsigned short port)
|
|||
}
|
||||
return;
|
||||
}
|
||||
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername, port);
|
||||
ProcessSSDPData(s, bufr, n, (struct sockaddr *)&sendername,
|
||||
#ifdef ENABLE_HTTPS
|
||||
port, https_port);
|
||||
#else
|
||||
port);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ProcessSSDPData(int s, const char *bufr, int n,
|
||||
const struct sockaddr * sender, unsigned short port) {
|
||||
const struct sockaddr * sender,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short port, unsigned short https_port)
|
||||
#else
|
||||
unsigned short port)
|
||||
#endif
|
||||
{
|
||||
int i, l;
|
||||
struct lan_addr_s * lan_addr = NULL;
|
||||
const char * st = NULL;
|
||||
|
@ -848,6 +899,9 @@ ProcessSSDPData(int s, const char *bufr, int n,
|
|||
known_service_types[i].s, l, ver_str,
|
||||
#endif
|
||||
announced_host, port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].uuid,
|
||||
delay);
|
||||
break;
|
||||
|
@ -874,6 +928,9 @@ ProcessSSDPData(int s, const char *bufr, int n,
|
|||
SendSSDPResponse(s, sender,
|
||||
known_service_types[i].s, l, ver_str,
|
||||
announced_host, port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
known_service_types[i].uuid,
|
||||
delay);
|
||||
}
|
||||
|
@ -882,17 +939,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, 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, 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, port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_wcd, delay);
|
||||
}
|
||||
/* responds to request by UUID value */
|
||||
l = (int)strlen(uuidvalue_igd);
|
||||
|
@ -905,22 +974,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, 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, 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, port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
https_port,
|
||||
#endif
|
||||
uuidvalue_wcd, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $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
|
||||
|
@ -23,19 +23,31 @@ SendSSDPNotifies(int s, const char * host, unsigned short port,
|
|||
void
|
||||
SendSSDPNotifies2(int * sockets,
|
||||
unsigned short port,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short https_port,
|
||||
#endif
|
||||
unsigned int lifetime);
|
||||
/*SendSSDPNotifies2(int * sockets, struct lan_addr_s * lan_addr, int n_lan_addr,
|
||||
unsigned short port,
|
||||
unsigned int lifetime);*/
|
||||
|
||||
void
|
||||
#ifdef ENABLE_HTTPS
|
||||
ProcessSSDPRequest(int s, unsigned short port, unsigned short https_port);
|
||||
#else
|
||||
ProcessSSDPRequest(int s, unsigned short port);
|
||||
#endif
|
||||
/*ProcessSSDPRequest(int s, struct lan_addr_s * lan_addr, int n_lan_addr,
|
||||
unsigned short port);*/
|
||||
|
||||
void
|
||||
ProcessSSDPData(int s, const char *bufr, int n,
|
||||
const struct sockaddr * sendername, unsigned short port);
|
||||
const struct sockaddr * sendername,
|
||||
#ifdef ENABLE_HTTPS
|
||||
unsigned short port, unsigned short https_port);
|
||||
#else
|
||||
unsigned short 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.192 2014/04/09 11:07:36 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 */
|
||||
|
@ -1126,6 +1132,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 +1164,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 +1399,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 +1470,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 +1519,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)
|
||||
|
@ -1558,6 +1585,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 +1601,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 +1612,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 +1790,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 +1884,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)
|
||||
{
|
||||
|
@ -2039,13 +2134,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
|
||||
|
@ -2088,6 +2191,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))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: upnphttp.c,v 1.87 2014/03/14 21:26:01 nanard Exp $ */
|
||||
/* $Id: upnphttp.c,v 1.90 2014/04/09 13:15:43 nanard Exp $ */
|
||||
/* Project : miniupnp
|
||||
* Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* Author : Thomas Bernard
|
||||
|
@ -29,6 +29,66 @@
|
|||
#include "upnpevents.h"
|
||||
#include "upnputils.h"
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
#include <openssl/err.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));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* ENABLE_HTTPS */
|
||||
|
||||
struct upnphttp *
|
||||
New_upnphttp(int s)
|
||||
{
|
||||
|
@ -45,9 +105,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 +152,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 +797,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 +828,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 +867,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 +898,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 +1082,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 +1118,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 +1143,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 +1181,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.37 2014/04/09 13:15:45 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,19 @@ struct upnphttp {
|
|||
#define FLAG_ALLOW_POST 0x100
|
||||
#define FLAG_ALLOW_SUB_UNSUB 0x200
|
||||
|
||||
#ifdef ENABLE_HTTPS
|
||||
int init_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 *);
|
||||
|
|
Loading…
Reference in New Issue