fixed a bug in ssl handling

This commit is contained in:
hyung-hwan 2012-09-15 14:27:14 +00:00
parent 2179c2a88b
commit 99f1b5453b
4 changed files with 53 additions and 42 deletions

View File

@ -286,7 +286,6 @@ struct qse_httpd_client_t
/* == PRIVATE == */ /* == PRIVATE == */
qse_htrd_t* htrd; qse_htrd_t* htrd;
int secure;
int status; int status;
qse_httpd_task_trigger_t trigger[QSE_HTTPD_TASK_TRIGGER_MAX]; qse_httpd_task_trigger_t trigger[QSE_HTTPD_TASK_TRIGGER_MAX];
qse_ntime_t last_active; qse_ntime_t last_active;

View File

@ -379,10 +379,10 @@ qse_httpd_t* qse_httpd_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
if (httpd == QSE_NULL) return QSE_NULL; if (httpd == QSE_NULL) return QSE_NULL;
xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd);
QSE_MEMSET (xtn, 0, xtnsize);
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
xtn->ssl_ctx = QSE_NULL; /*init_xtn_ssl (xtn, "http01.pem", "http01.key");*/
init_xtn_ssl (xtn, "http01.pem", "http01.key");
#endif #endif
qse_httpd_pushecb (httpd, &std_ecb); qse_httpd_pushecb (httpd, &std_ecb);
@ -396,12 +396,23 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd)
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
static int sockaddr_to_nwad ( union sockaddr_t
const struct sockaddr_storage* addr, qse_nwad_t* nwad) {
struct sockaddr_in in4;
#if defined(AF_INET6)
struct sockaddr_in6 in6;
#endif
};
typedef union sockaddr_t sockaddr_t;
#define SOCKADDR_FAMILY(x) (((struct sockaddr_in*)(x))->sin_family)
static int sockaddr_to_nwad (const sockaddr_t* addr, qse_nwad_t* nwad)
{ {
int addrsize = -1; int addrsize = -1;
switch (addr->ss_family) switch (SOCKADDR_FAMILY(addr))
{ {
case AF_INET: case AF_INET:
{ {
@ -436,8 +447,7 @@ static int sockaddr_to_nwad (
return addrsize; return addrsize;
} }
static int nwad_to_sockaddr ( static int nwad_to_sockaddr (const qse_nwad_t* nwad, sockaddr_t* addr)
const qse_nwad_t* nwad, struct sockaddr_storage* addr)
{ {
int addrsize = -1; int addrsize = -1;
@ -483,9 +493,7 @@ static int nwad_to_sockaddr (
static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server) static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
{ {
int fd = -1, flag; int fd = -1, flag;
/* TODO: if AF_INET6 is not defined sockaddr_storage is not available... sockaddr_t addr;
* create your own union or somehting similar... */
struct sockaddr_storage addr;
int addrsize; int addrsize;
addrsize = nwad_to_sockaddr (&server->nwad, &addr); addrsize = nwad_to_sockaddr (&server->nwad, &addr);
@ -495,7 +503,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
return -1; return -1;
} }
fd = socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP); fd = socket (SOCKADDR_FAMILY(&addr), SOCK_STREAM, IPPROTO_TCP);
if (fd <= -1) goto oops; if (fd <= -1) goto oops;
flag = fcntl (fd, F_GETFD); flag = fcntl (fd, F_GETFD);
@ -518,7 +526,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1) if (bind (fd, (struct sockaddr*)&addr, addrsize) <= -1)
{ {
#if defined(IPV6_V6ONLY) #if defined(IPV6_V6ONLY)
if (errno == EADDRINUSE && addr.ss_family == AF_INET6) if (errno == EADDRINUSE && SOCKADDR_FAMILY(&addr) == AF_INET6)
{ {
int on = 1; int on = 1;
setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
@ -552,7 +560,7 @@ static int server_accept (
qse_httpd_t* httpd, qse_httpd_t* httpd,
qse_httpd_server_t* server, qse_httpd_client_t* client) qse_httpd_server_t* server, qse_httpd_client_t* client)
{ {
struct sockaddr_storage addr; sockaddr_t addr;
#ifdef HAVE_SOCKLEN_T #ifdef HAVE_SOCKLEN_T
socklen_t addrlen; socklen_t addrlen;
@ -619,9 +627,7 @@ qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer) static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
{ {
int fd = -1, flag; int fd = -1, flag;
/* TODO: if AF_INET6 is not defined sockaddr_storage is not available... sockaddr_t addr;
* create your own union or somehting similar... */
struct sockaddr_storage addr;
int addrsize; int addrsize;
int connected = 1; int connected = 1;
@ -632,7 +638,7 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
return -1; return -1;
} }
fd = socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP); fd = socket (SOCKADDR_FAMILY(&addr), SOCK_STREAM, IPPROTO_TCP);
if (fd <= -1) goto oops; if (fd <= -1) goto oops;
flag = fcntl (fd, F_GETFD); flag = fcntl (fd, F_GETFD);
@ -1093,7 +1099,7 @@ static qse_ssize_t client_recv (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_t* httpd, qse_httpd_client_t* client,
qse_mchar_t* buf, qse_size_t bufsize) qse_mchar_t* buf, qse_size_t bufsize)
{ {
if (client->secure) if (client->status & CLIENT_SECURE)
{ {
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
int ret = SSL_read (client->handle2.ptr, buf, bufsize); int ret = SSL_read (client->handle2.ptr, buf, bufsize);
@ -1121,7 +1127,7 @@ static qse_ssize_t client_send (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_t* httpd, qse_httpd_client_t* client,
const qse_mchar_t* buf, qse_size_t bufsize) const qse_mchar_t* buf, qse_size_t bufsize)
{ {
if (client->secure) if (client->status & CLIENT_SECURE)
{ {
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
int ret = SSL_write (client->handle2.ptr, buf, bufsize); int ret = SSL_write (client->handle2.ptr, buf, bufsize);
@ -1149,7 +1155,7 @@ static qse_ssize_t client_sendfile (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_t* httpd, qse_httpd_client_t* client,
qse_ubi_t handle, qse_foff_t* offset, qse_size_t count) qse_ubi_t handle, qse_foff_t* offset, qse_size_t count)
{ {
if (client->secure) if (client->status & CLIENT_SECURE)
{ {
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
return xsendfile_ssl (client->handle2.ptr, handle.i, offset, count); return xsendfile_ssl (client->handle2.ptr, handle.i, offset, count);
@ -1167,23 +1173,27 @@ static int client_accepted (qse_httpd_t* httpd, qse_httpd_client_t* client)
{ {
httpd_xtn_t* xtn = (httpd_xtn_t*) qse_httpd_getxtn (httpd); httpd_xtn_t* xtn = (httpd_xtn_t*) qse_httpd_getxtn (httpd);
if (client->secure) if (client->status & CLIENT_SECURE)
{ {
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
int ret; int ret;
SSL* ssl; SSL* ssl;
if (!xtn->ssl_ctx)
{
/* delayed initialization of ssl */
if (init_xtn_ssl (xtn, "http01.pem", "http01.key") <= -1)
{
return -1;
}
}
QSE_ASSERT (xtn->ssl_ctx != QSE_NULL);
if (client->handle2.ptr) if (client->handle2.ptr)
{ {
ssl = client->handle2.ptr; ssl = client->handle2.ptr;
} }
else if (!xtn->ssl_ctx)
{
/* no ssl */
qse_printf (QSE_T("NO SSL\n"));
qse_fflush (QSE_STDOUT);
return -1;
}
else else
{ {
ssl = SSL_new (xtn->ssl_ctx); ssl = SSL_new (xtn->ssl_ctx);
@ -1224,7 +1234,7 @@ qse_fflush (QSE_STDOUT);
static void client_closed (qse_httpd_t* httpd, qse_httpd_client_t* client) static void client_closed (qse_httpd_t* httpd, qse_httpd_client_t* client)
{ {
if (client->secure) if (client->status & CLIENT_SECURE)
{ {
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
if (client->handle2.ptr) if (client->handle2.ptr)

View File

@ -42,17 +42,6 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (httpd)
#define DEFAULT_PORT 80 #define DEFAULT_PORT 80
#define DEFAULT_SECURE_PORT 443 #define DEFAULT_SECURE_PORT 443
/* client->status */
#define CLIENT_BAD (1 << 0)
#define CLIENT_READY (1 << 1)
#define CLIENT_SECURE (1 << 2)
#define CLIENT_MUTE (1 << 3)
#define CLIENT_MUTE_DELETED (1 << 4)
#define CLIENT_HANDLE_READ_IN_MUX (1 << 5)
#define CLIENT_HANDLE_WRITE_IN_MUX (1 << 6)
#define CLIENT_HANDLE_IN_MUX (CLIENT_HANDLE_READ_IN_MUX|CLIENT_HANDLE_WRITE_IN_MUX)
#define CLIENT_TASK_TRIGGER_IN_MUX(i) (1 << ((i) + 7))
static void free_server_list ( static void free_server_list (
qse_httpd_t* httpd, qse_httpd_server_t* server); qse_httpd_t* httpd, qse_httpd_server_t* server);
static int perform_client_task ( static int perform_client_task (
@ -316,10 +305,11 @@ static qse_httpd_client_t* new_client (
qse_htrd_setoption (client->htrd, QSE_HTRD_REQUEST | QSE_HTRD_TRAILERS | QSE_HTRD_CANONQPATH); qse_htrd_setoption (client->htrd, QSE_HTRD_REQUEST | QSE_HTRD_TRAILERS | QSE_HTRD_CANONQPATH);
client->status = tmpl->status;
if (httpd->scb->client.accepted == QSE_NULL) if (httpd->scb->client.accepted == QSE_NULL)
client->status |= CLIENT_READY; client->status |= CLIENT_READY;
client->status = tmpl->status;
client->handle = tmpl->handle; client->handle = tmpl->handle;
client->handle2 = tmpl->handle2; client->handle2 = tmpl->handle2;
client->remote_addr = tmpl->remote_addr; client->remote_addr = tmpl->remote_addr;

View File

@ -69,6 +69,18 @@ struct qse_httpd_t
#define MAX_SEND_SIZE 4096 #define MAX_SEND_SIZE 4096
/* client->status */
#define CLIENT_BAD (1 << 0)
#define CLIENT_READY (1 << 1)
#define CLIENT_SECURE (1 << 2)
#define CLIENT_MUTE (1 << 3)
#define CLIENT_MUTE_DELETED (1 << 4)
#define CLIENT_HANDLE_READ_IN_MUX (1 << 5)
#define CLIENT_HANDLE_WRITE_IN_MUX (1 << 6)
#define CLIENT_HANDLE_IN_MUX (CLIENT_HANDLE_READ_IN_MUX|CLIENT_HANDLE_WRITE_IN_MUX)
#define CLIENT_TASK_TRIGGER_IN_MUX(i) (1 << ((i) + 7))
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif