My squashed commits
This commit is contained in:
parent
8eec345e49
commit
20b3fe3c48
12
ChangeLog
12
ChangeLog
@ -2,6 +2,18 @@
|
|||||||
Version 1.8.0
|
Version 1.8.0
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|
||||||
|
2011-02-07 Chandra Penke <chandrapenke(at)mcntech.com>
|
||||||
|
|
||||||
|
Add HTTPS support using OpenSSL. HTTPS support is optional and can
|
||||||
|
be enabled by passing the --enable-open-ssl argument to the
|
||||||
|
configure script.
|
||||||
|
|
||||||
|
The following methods are introduced to the public API:
|
||||||
|
UpnpInitOpenSslContext
|
||||||
|
|
||||||
|
When enabled, HTTPS can be used by using "https://" instead of
|
||||||
|
"http://" when passing URLs to the HTTP Client API.
|
||||||
|
|
||||||
2011-02-07 Chandra Penke <chandrapenke(at)mcntech.com>
|
2011-02-07 Chandra Penke <chandrapenke(at)mcntech.com>
|
||||||
|
|
||||||
Refactor HTTP Client API to be more generic.
|
Refactor HTTP Client API to be more generic.
|
||||||
|
@ -324,6 +324,11 @@ if test "x$enable_ipv6" = xyes ; then
|
|||||||
AC_DEFINE(UPNP_ENABLE_IPV6, 1, [see upnpconfig.h])
|
AC_DEFINE(UPNP_ENABLE_IPV6, 1, [see upnpconfig.h])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
RT_BOOL_ARG_ENABLE([open_ssl], [no], [open-ssl support])
|
||||||
|
if test "x$enable_open_ssl" = xyes ; then
|
||||||
|
AC_DEFINE(UPNP_ENABLE_OPEN_SSL, 1, [see upnpconfig.h])
|
||||||
|
fi
|
||||||
|
|
||||||
RT_BOOL_ARG_ENABLE([notification_reordering], [yes], [GENA notification reordering in gena_device.c])
|
RT_BOOL_ARG_ENABLE([notification_reordering], [yes], [GENA notification reordering in gena_device.c])
|
||||||
if test "x$enable_notification_reordering" = xyes ; then
|
if test "x$enable_notification_reordering" = xyes ; then
|
||||||
AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h])
|
AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h])
|
||||||
|
@ -57,6 +57,10 @@
|
|||||||
/* Other systems ??? */
|
/* Other systems ??? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LINE_SIZE 180
|
#define LINE_SIZE 180
|
||||||
#define NAME_SIZE 256
|
#define NAME_SIZE 256
|
||||||
#define MNFT_NAME_SIZE 64
|
#define MNFT_NAME_SIZE 64
|
||||||
@ -578,6 +582,29 @@ EXPORT_SPEC int UpnpInit2(
|
|||||||
unsigned short DestPort);
|
unsigned short DestPort);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the OpenSSL library, and the OpenSSL context for use
|
||||||
|
* with pupnp
|
||||||
|
*
|
||||||
|
* \note This method is only enabled if pupnp is compiled with open-ssl support.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INIT: The SDK is already initialized.
|
||||||
|
* \li \c UPNP_E_INIT_FAILED: The SDK initialization
|
||||||
|
* failed for an unknown reason.
|
||||||
|
*/
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
EXPORT_SPEC int UpnpInitSslContext(
|
||||||
|
/*! If set to 1 initializes the OpenSSL library. Otherwise the application
|
||||||
|
* is responsible for initializing it. If set to 1, then OpenSSL is intialized
|
||||||
|
* with all error strings, and all ciphers loaded. */
|
||||||
|
int initOpenSslLib,
|
||||||
|
/*! The SSL_METHOD to use to create the context. See OpenSSL docs
|
||||||
|
* for more info */
|
||||||
|
const SSL_METHOD *sslMethod);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Terminates the Linux SDK for UPnP Devices.
|
* \brief Terminates the Linux SDK for UPnP Devices.
|
||||||
*
|
*
|
||||||
|
@ -107,5 +107,9 @@
|
|||||||
* (i.e. configure --enable-ipv6) */
|
* (i.e. configure --enable-ipv6) */
|
||||||
#undef UPNP_ENABLE_IPV6
|
#undef UPNP_ENABLE_IPV6
|
||||||
|
|
||||||
|
/** Defined to 1 if the library has been compiled with OpenSSL support
|
||||||
|
* (i.e. configure --enable-open_ssl) */
|
||||||
|
#undef UPNP_ENABLE_OPEN_SSL
|
||||||
|
|
||||||
#endif /* UPNP_CONFIG_H */
|
#endif /* UPNP_CONFIG_H */
|
||||||
|
|
||||||
|
@ -77,6 +77,10 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef IN6_IS_ADDR_GLOBAL
|
#ifndef IN6_IS_ADDR_GLOBAL
|
||||||
#define IN6_IS_ADDR_GLOBAL(a) \
|
#define IN6_IS_ADDR_GLOBAL(a) \
|
||||||
(((((__const uint8_t *) (a))[0] & htonl(0xff000000)) <= htonl(0x3f000000) \
|
(((((__const uint8_t *) (a))[0] & htonl(0xff000000)) <= htonl(0x3f000000) \
|
||||||
@ -177,6 +181,12 @@ int UpnpSdkDeviceregisteredV6 = 0;
|
|||||||
/*! Global variable used in discovery notifications. */
|
/*! Global variable used in discovery notifications. */
|
||||||
Upnp_SID gUpnpSdkNLSuuid;
|
Upnp_SID gUpnpSdkNLSuuid;
|
||||||
|
|
||||||
|
/*! Global variable used as to store the OpenSSL context object
|
||||||
|
* to be used for all SSL/TLS connections
|
||||||
|
*/
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
SSL_CTX *gSslCtx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief (Windows Only) Initializes the Windows Winsock library.
|
* \brief (Windows Only) Initializes the Windows Winsock library.
|
||||||
@ -520,6 +530,24 @@ exit_function:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
int UpnpInitSslContext(int initOpenSslLib, const SSL_METHOD *sslMethod)
|
||||||
|
{
|
||||||
|
if (gSslCtx)
|
||||||
|
return UPNP_E_INIT;
|
||||||
|
if (initOpenSslLib) {
|
||||||
|
SSL_load_error_strings();
|
||||||
|
SSL_library_init();
|
||||||
|
OpenSSL_add_all_algorithms();
|
||||||
|
}
|
||||||
|
gSslCtx = SSL_CTX_new(sslMethod);
|
||||||
|
if (!gSslCtx) {
|
||||||
|
return UPNP_E_INIT_FAILED;
|
||||||
|
}
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int UpnpFinish(void)
|
int UpnpFinish(void)
|
||||||
{
|
{
|
||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
@ -529,7 +557,12 @@ int UpnpFinish(void)
|
|||||||
UpnpClient_Handle client_handle;
|
UpnpClient_Handle client_handle;
|
||||||
#endif
|
#endif
|
||||||
struct Handle_Info *temp;
|
struct Handle_Info *temp;
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
if (gSslCtx) {
|
||||||
|
SSL_CTX_free(gSslCtx);
|
||||||
|
gSslCtx = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (UpnpSdkInit != 1)
|
if (UpnpSdkInit != 1)
|
||||||
return UPNP_E_FINISH;
|
return UPNP_E_FINISH;
|
||||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
|
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
|
||||||
|
@ -216,9 +216,18 @@ int http_FixUrl(IN uri_type *url, OUT uri_type *fixed_url)
|
|||||||
const char *temp_path = "/";
|
const char *temp_path = "/";
|
||||||
|
|
||||||
*fixed_url = *url;
|
*fixed_url = *url;
|
||||||
if (token_string_casecmp(&fixed_url->scheme, "http") != 0) {
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
if (token_string_casecmp(&fixed_url->scheme, "http") != 0 &&
|
||||||
|
token_string_casecmp(&fixed_url->scheme, "https") != 0)
|
||||||
|
{
|
||||||
return UPNP_E_INVALID_URL;
|
return UPNP_E_INVALID_URL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (token_string_casecmp(&fixed_url->scheme, "http") != 0)
|
||||||
|
{
|
||||||
|
return UPNP_E_INVALID_URL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if( fixed_url->hostport.text.size == 0 ) {
|
if( fixed_url->hostport.text.size == 0 ) {
|
||||||
return UPNP_E_INVALID_URL;
|
return UPNP_E_INVALID_URL;
|
||||||
}
|
}
|
||||||
@ -1072,6 +1081,16 @@ int http_OpenHttpConnection(const char *url_str, void **Handle, int timeout)
|
|||||||
ret_code = UPNP_E_SOCKET_CONNECT;
|
ret_code = UPNP_E_SOCKET_CONNECT;
|
||||||
goto errorHandler;
|
goto errorHandler;
|
||||||
}
|
}
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
/* For HTTPS connections start the TLS/SSL handshake. */
|
||||||
|
if (token_string_casecmp(&url.scheme, "https") == 0) {
|
||||||
|
ret_code = sock_ssl_connect(&handle->sock_info);
|
||||||
|
if (ret_code != UPNP_E_SUCCESS) {
|
||||||
|
sock_destroy(&handle->sock_info, SD_BOTH);
|
||||||
|
goto errorHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
errorHandler:
|
errorHandler:
|
||||||
*Handle = handle;
|
*Handle = handle;
|
||||||
return ret_code;
|
return ret_code;
|
||||||
|
@ -52,10 +52,19 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MSG_NOSIGNAL
|
#ifndef MSG_NOSIGNAL
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
/* OpenSSL context defined in upnpapi.c */
|
||||||
|
extern SSL_CTX *gSslCtx;
|
||||||
|
#endif
|
||||||
|
|
||||||
int sock_init(SOCKINFO *info, SOCKET sockfd)
|
int sock_init(SOCKINFO *info, SOCKET sockfd)
|
||||||
{
|
{
|
||||||
assert(info);
|
assert(info);
|
||||||
@ -82,11 +91,37 @@ int sock_init_with_ip(SOCKINFO *info, SOCKET sockfd,
|
|||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
int sock_ssl_connect(SOCKINFO *info)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
info->ssl = SSL_new(gSslCtx);
|
||||||
|
if (!info->ssl) {
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
status = SSL_set_fd(info->ssl, info->socket);
|
||||||
|
if (status == 1) {
|
||||||
|
status = SSL_connect(info->ssl);
|
||||||
|
}
|
||||||
|
if (status == 1) {
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int sock_destroy(SOCKINFO *info, int ShutdownMethod)
|
int sock_destroy(SOCKINFO *info, int ShutdownMethod)
|
||||||
{
|
{
|
||||||
int ret = UPNP_E_SUCCESS;
|
int ret = UPNP_E_SUCCESS;
|
||||||
|
|
||||||
if (info->socket != -1) {
|
if (info->socket != -1) {
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
if (info->ssl) {
|
||||||
|
SSL_shutdown(info->ssl);
|
||||||
|
SSL_free(info->ssl);
|
||||||
|
info->ssl = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
shutdown(info->socket, ShutdownMethod);
|
shutdown(info->socket, ShutdownMethod);
|
||||||
if (sock_close(info->socket) == -1) {
|
if (sock_close(info->socket) == -1) {
|
||||||
ret = UPNP_E_SOCKET_ERROR;
|
ret = UPNP_E_SOCKET_ERROR;
|
||||||
@ -163,16 +198,36 @@ static int sock_read_write(
|
|||||||
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));
|
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));
|
||||||
#endif
|
#endif
|
||||||
if (bRead) {
|
if (bRead) {
|
||||||
/* read data. */
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
numBytes = (long)recv(sockfd, buffer, (size_t)bufsize, MSG_NOSIGNAL);
|
if (info->ssl) {
|
||||||
|
numBytes = (long)SSL_read(info->ssl,
|
||||||
|
buffer, (size_t)bufsize);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#endif
|
||||||
|
/* read data. */
|
||||||
|
numBytes = (long)recv(sockfd, buffer, (size_t)bufsize, MSG_NOSIGNAL);
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
byte_left = bufsize;
|
byte_left = bufsize;
|
||||||
bytes_sent = 0;
|
bytes_sent = 0;
|
||||||
while (byte_left > 0) {
|
while (byte_left > 0) {
|
||||||
/* write data. */
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
num_written = send(sockfd,
|
if (info->ssl) {
|
||||||
buffer + bytes_sent, (size_t)byte_left,
|
num_written = SSL_write(info->ssl,
|
||||||
MSG_DONTROUTE | MSG_NOSIGNAL);
|
buffer + bytes_sent, (size_t)byte_left);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#endif
|
||||||
|
/* write data. */
|
||||||
|
num_written = send(sockfd,
|
||||||
|
buffer + bytes_sent, (size_t)byte_left,
|
||||||
|
MSG_DONTROUTE | MSG_NOSIGNAL);
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (num_written == -1) {
|
if (num_written == -1) {
|
||||||
#ifdef SO_NOSIGPIPE
|
#ifdef SO_NOSIGPIPE
|
||||||
setsockopt(sockfd, SOL_SOCKET,
|
setsockopt(sockfd, SOL_SOCKET,
|
||||||
|
@ -312,6 +312,7 @@ int token_cmp(token *in1, token *in2)
|
|||||||
int parse_hostport(
|
int parse_hostport(
|
||||||
const char *in,
|
const char *in,
|
||||||
size_t max,
|
size_t max,
|
||||||
|
int defaultPort,
|
||||||
hostport_type *out)
|
hostport_type *out)
|
||||||
{
|
{
|
||||||
char workbuf[256];
|
char workbuf[256];
|
||||||
@ -402,9 +403,10 @@ int parse_hostport(
|
|||||||
if (port == 0)
|
if (port == 0)
|
||||||
/* Bad port number. */
|
/* Bad port number. */
|
||||||
return UPNP_E_INVALID_URL;
|
return UPNP_E_INVALID_URL;
|
||||||
} else
|
} else {
|
||||||
/* Port was not specified, use default port. */
|
/* Port was not specified, use default port. */
|
||||||
port = 80;
|
port = defaultPort;
|
||||||
|
}
|
||||||
/* The length of the host and port string can be calculated by */
|
/* The length of the host and port string can be calculated by */
|
||||||
/* subtracting pointers. */
|
/* subtracting pointers. */
|
||||||
hostport_size = (size_t)(c - workbuf);
|
hostport_size = (size_t)(c - workbuf);
|
||||||
@ -673,6 +675,7 @@ int parse_uri(const char *in, size_t max, uri_type *out)
|
|||||||
int begin_path = 0;
|
int begin_path = 0;
|
||||||
size_t begin_hostport = 0;
|
size_t begin_hostport = 0;
|
||||||
size_t begin_fragment = 0;
|
size_t begin_fragment = 0;
|
||||||
|
int defaultPort = 80;
|
||||||
|
|
||||||
begin_hostport = parse_scheme(in, max, &out->scheme);
|
begin_hostport = parse_scheme(in, max, &out->scheme);
|
||||||
if (begin_hostport) {
|
if (begin_hostport) {
|
||||||
@ -687,9 +690,13 @@ int parse_uri(const char *in, size_t max, uri_type *out)
|
|||||||
in[begin_hostport] == '/' &&
|
in[begin_hostport] == '/' &&
|
||||||
in[begin_hostport + 1] == '/') {
|
in[begin_hostport + 1] == '/') {
|
||||||
begin_hostport += 2;
|
begin_hostport += 2;
|
||||||
|
if (token_string_casecmp(&out->scheme, "https") == 0) {
|
||||||
|
defaultPort = 443;
|
||||||
|
}
|
||||||
begin_path = parse_hostport(&in[begin_hostport],
|
begin_path = parse_hostport(&in[begin_hostport],
|
||||||
max - begin_hostport,
|
max - begin_hostport,
|
||||||
&out->hostport);
|
defaultPort,
|
||||||
|
&out->hostport);
|
||||||
if (begin_path >= 0) {
|
if (begin_path >= 0) {
|
||||||
begin_path += (int)begin_hostport;
|
begin_path += (int)begin_hostport;
|
||||||
} else
|
} else
|
||||||
|
@ -40,8 +40,12 @@
|
|||||||
* \file
|
* \file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "upnpconfig.h"
|
||||||
#include "UpnpInet.h" /* for SOCKET, netinet/in */
|
#include "UpnpInet.h" /* for SOCKET, netinet/in */
|
||||||
#include "UpnpGlobal.h" /* for UPNP_INLINE */
|
#include "UpnpGlobal.h" /* for UPNP_INLINE */
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The following are not defined under winsock.h */
|
/* The following are not defined under winsock.h */
|
||||||
#ifndef SD_RECEIVE
|
#ifndef SD_RECEIVE
|
||||||
@ -57,6 +61,9 @@ typedef struct
|
|||||||
SOCKET socket;
|
SOCKET socket;
|
||||||
/*! The following two fields are filled only in incoming requests. */
|
/*! The following two fields are filled only in incoming requests. */
|
||||||
struct sockaddr_storage foreign_sockaddr;
|
struct sockaddr_storage foreign_sockaddr;
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
SSL *ssl;
|
||||||
|
#endif
|
||||||
} SOCKINFO;
|
} SOCKINFO;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -112,6 +119,20 @@ int sock_init_with_ip(
|
|||||||
/*! [in] Remote socket address. */
|
/*! [in] Remote socket address. */
|
||||||
struct sockaddr *foreign_sockaddr);
|
struct sockaddr *foreign_sockaddr);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Associates an SSL object with the socket and begins
|
||||||
|
* the client-side SSL/TLS handshake.
|
||||||
|
*
|
||||||
|
* \return Integer:
|
||||||
|
* \li \c UPNP_E_SUCCESS
|
||||||
|
* \li \c UPNP_E_SOCKET_ERROR
|
||||||
|
*/
|
||||||
|
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||||
|
int sock_ssl_connect(
|
||||||
|
/*! [out] Socket Information Object. */
|
||||||
|
SOCKINFO* info);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Shutsdown the socket using the ShutdownMethod to indicate whether
|
* \brief Shutsdown the socket using the ShutdownMethod to indicate whether
|
||||||
* sends and receives on the socket will be dis-allowed.
|
* sends and receives on the socket will be dis-allowed.
|
||||||
|
@ -285,6 +285,8 @@ int parse_hostport(
|
|||||||
const char *in,
|
const char *in,
|
||||||
/*! [in] Sets a maximum limit. */
|
/*! [in] Sets a maximum limit. */
|
||||||
size_t max,
|
size_t max,
|
||||||
|
/*! [in] The default port if the port is not specified. */
|
||||||
|
int defaultPort,
|
||||||
/*! [out] Output parameter where the host and port are represented as
|
/*! [out] Output parameter where the host and port are represented as
|
||||||
* an internet address. */
|
* an internet address. */
|
||||||
hostport_type *out);
|
hostport_type *out);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user