My squashed commits
This commit is contained in:
parent
8eec345e49
commit
20b3fe3c48
12
ChangeLog
12
ChangeLog
@ -2,6 +2,18 @@
|
||||
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>
|
||||
|
||||
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])
|
||||
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])
|
||||
if test "x$enable_notification_reordering" = xyes ; then
|
||||
AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h])
|
||||
|
@ -57,6 +57,10 @@
|
||||
/* Other systems ??? */
|
||||
#endif
|
||||
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#define LINE_SIZE 180
|
||||
#define NAME_SIZE 256
|
||||
#define MNFT_NAME_SIZE 64
|
||||
@ -578,6 +582,29 @@ EXPORT_SPEC int UpnpInit2(
|
||||
unsigned short DestPort);
|
||||
#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.
|
||||
*
|
||||
|
@ -107,5 +107,9 @@
|
||||
* (i.e. configure --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 */
|
||||
|
||||
|
@ -77,6 +77,10 @@
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifndef IN6_IS_ADDR_GLOBAL
|
||||
#define IN6_IS_ADDR_GLOBAL(a) \
|
||||
(((((__const uint8_t *) (a))[0] & htonl(0xff000000)) <= htonl(0x3f000000) \
|
||||
@ -177,6 +181,12 @@ int UpnpSdkDeviceregisteredV6 = 0;
|
||||
/*! Global variable used in discovery notifications. */
|
||||
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.
|
||||
@ -520,6 +530,24 @@ exit_function:
|
||||
}
|
||||
#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)
|
||||
{
|
||||
#ifdef INCLUDE_DEVICE_APIS
|
||||
@ -529,7 +557,12 @@ int UpnpFinish(void)
|
||||
UpnpClient_Handle client_handle;
|
||||
#endif
|
||||
struct Handle_Info *temp;
|
||||
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
if (gSslCtx) {
|
||||
SSL_CTX_free(gSslCtx);
|
||||
gSslCtx = NULL;
|
||||
}
|
||||
#endif
|
||||
if (UpnpSdkInit != 1)
|
||||
return UPNP_E_FINISH;
|
||||
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 = "/";
|
||||
|
||||
*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;
|
||||
}
|
||||
#else
|
||||
if (token_string_casecmp(&fixed_url->scheme, "http") != 0)
|
||||
{
|
||||
return UPNP_E_INVALID_URL;
|
||||
}
|
||||
#endif
|
||||
if( fixed_url->hostport.text.size == 0 ) {
|
||||
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;
|
||||
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:
|
||||
*Handle = handle;
|
||||
return ret_code;
|
||||
|
@ -52,10 +52,19 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
/* OpenSSL context defined in upnpapi.c */
|
||||
extern SSL_CTX *gSslCtx;
|
||||
#endif
|
||||
|
||||
int sock_init(SOCKINFO *info, SOCKET sockfd)
|
||||
{
|
||||
assert(info);
|
||||
@ -82,11 +91,37 @@ int sock_init_with_ip(SOCKINFO *info, SOCKET sockfd,
|
||||
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 ret = UPNP_E_SUCCESS;
|
||||
|
||||
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);
|
||||
if (sock_close(info->socket) == -1) {
|
||||
ret = UPNP_E_SOCKET_ERROR;
|
||||
@ -163,16 +198,36 @@ static int sock_read_write(
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));
|
||||
#endif
|
||||
if (bRead) {
|
||||
/* read data. */
|
||||
numBytes = (long)recv(sockfd, buffer, (size_t)bufsize, MSG_NOSIGNAL);
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
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 {
|
||||
byte_left = bufsize;
|
||||
bytes_sent = 0;
|
||||
while (byte_left > 0) {
|
||||
/* write data. */
|
||||
num_written = send(sockfd,
|
||||
buffer + bytes_sent, (size_t)byte_left,
|
||||
MSG_DONTROUTE | MSG_NOSIGNAL);
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
if (info->ssl) {
|
||||
num_written = SSL_write(info->ssl,
|
||||
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) {
|
||||
#ifdef SO_NOSIGPIPE
|
||||
setsockopt(sockfd, SOL_SOCKET,
|
||||
|
@ -312,6 +312,7 @@ int token_cmp(token *in1, token *in2)
|
||||
int parse_hostport(
|
||||
const char *in,
|
||||
size_t max,
|
||||
int defaultPort,
|
||||
hostport_type *out)
|
||||
{
|
||||
char workbuf[256];
|
||||
@ -402,9 +403,10 @@ int parse_hostport(
|
||||
if (port == 0)
|
||||
/* Bad port number. */
|
||||
return UPNP_E_INVALID_URL;
|
||||
} else
|
||||
} else {
|
||||
/* Port was not specified, use default port. */
|
||||
port = 80;
|
||||
port = defaultPort;
|
||||
}
|
||||
/* The length of the host and port string can be calculated by */
|
||||
/* subtracting pointers. */
|
||||
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;
|
||||
size_t begin_hostport = 0;
|
||||
size_t begin_fragment = 0;
|
||||
int defaultPort = 80;
|
||||
|
||||
begin_hostport = parse_scheme(in, max, &out->scheme);
|
||||
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 + 1] == '/') {
|
||||
begin_hostport += 2;
|
||||
if (token_string_casecmp(&out->scheme, "https") == 0) {
|
||||
defaultPort = 443;
|
||||
}
|
||||
begin_path = parse_hostport(&in[begin_hostport],
|
||||
max - begin_hostport,
|
||||
&out->hostport);
|
||||
max - begin_hostport,
|
||||
defaultPort,
|
||||
&out->hostport);
|
||||
if (begin_path >= 0) {
|
||||
begin_path += (int)begin_hostport;
|
||||
} else
|
||||
|
@ -40,8 +40,12 @@
|
||||
* \file
|
||||
*/
|
||||
|
||||
#include "upnpconfig.h"
|
||||
#include "UpnpInet.h" /* for SOCKET, netinet/in */
|
||||
#include "UpnpGlobal.h" /* for UPNP_INLINE */
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
/* The following are not defined under winsock.h */
|
||||
#ifndef SD_RECEIVE
|
||||
@ -57,6 +61,9 @@ typedef struct
|
||||
SOCKET socket;
|
||||
/*! The following two fields are filled only in incoming requests. */
|
||||
struct sockaddr_storage foreign_sockaddr;
|
||||
#ifdef UPNP_ENABLE_OPEN_SSL
|
||||
SSL *ssl;
|
||||
#endif
|
||||
} SOCKINFO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -112,6 +119,20 @@ int sock_init_with_ip(
|
||||
/*! [in] Remote socket address. */
|
||||
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
|
||||
* sends and receives on the socket will be dis-allowed.
|
||||
|
@ -285,6 +285,8 @@ int parse_hostport(
|
||||
const char *in,
|
||||
/*! [in] Sets a maximum limit. */
|
||||
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
|
||||
* an internet address. */
|
||||
hostport_type *out);
|
||||
|
Loading…
x
Reference in New Issue
Block a user