Merge branch 'https'

Conflicts:
	miniupnpd/Makefile
	miniupnpd/pf/obsdrdr.c
This commit is contained in:
Thomas Bernard 2014-04-20 18:12:04 +02:00
commit 1dd48971b9
14 changed files with 674 additions and 72 deletions

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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}

View File

@ -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,

View File

@ -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);

View File

@ -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

View 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 */
@ -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 */

View 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 */

View File

@ -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,

View File

@ -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)
{

View File

@ -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 *);

View File

@ -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 }
};