1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-07-29 21:01:13 +03:00

Merge #217 with a another (incomplete) implementation of the same issue, and format code

This commit is contained in:
bel
2015-10-30 01:25:19 +01:00
parent b9b940577a
commit 407e628b0b
4 changed files with 313 additions and 85 deletions

View File

@ -26,6 +26,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duktape_lib", "duktape_lib\
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_websocket", "ex_websocket\ex_websocket.vcxproj", "{58B93E94-7766-435E-93AE-42A2FB5D99B1}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_websocket", "ex_websocket\ex_websocket.vcxproj", "{58B93E94-7766-435E-93AE-42A2FB5D99B1}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ex_embed_cpp", "ex_embed_cpp\ex_embed_cpp.vcxproj", "{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Mixed Platforms = Debug|Mixed Platforms
@ -152,6 +154,16 @@ Global
{58B93E94-7766-435E-93AE-42A2FB5D99B1}.Release|Win32.ActiveCfg = Release|Win32 {58B93E94-7766-435E-93AE-42A2FB5D99B1}.Release|Win32.ActiveCfg = Release|Win32
{58B93E94-7766-435E-93AE-42A2FB5D99B1}.Release|Win32.Build.0 = Release|Win32 {58B93E94-7766-435E-93AE-42A2FB5D99B1}.Release|Win32.Build.0 = Release|Win32
{58B93E94-7766-435E-93AE-42A2FB5D99B1}.Release|x64.ActiveCfg = Release|Win32 {58B93E94-7766-435E-93AE-42A2FB5D99B1}.Release|x64.ActiveCfg = Release|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Debug|Win32.ActiveCfg = Debug|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Debug|Win32.Build.0 = Debug|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Debug|x64.ActiveCfg = Debug|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Release|Mixed Platforms.Build.0 = Release|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Release|Win32.ActiveCfg = Release|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Release|Win32.Build.0 = Release|Win32
{4308C5EE-45E4-45D8-9D73-6C4E2587AD78}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -187,51 +187,64 @@ class FooHandler : public CivetHandler
return true; return true;
} }
bool
handlePut(CivetServer *server, struct mg_connection *conn)
{
/* Handler may access the request info using mg_get_request_info */
const struct mg_request_info *req_info = mg_get_request_info(conn);
long long rlen, wlen;
long long nlen = 0;
long long tlen = (size_t)req_info->content_length;
char buf[1024];
mg_printf(conn, #define fopen_recursive fopen
"HTTP/1.1 200 OK\r\nContent-Type: "
"text/html\r\nConnection: close\r\n\r\n");
mg_printf(conn, "<html><body>\n"); bool
mg_printf(conn, "<h2>This is the Foo PUT handler!!!</h2>\n"); handlePut(CivetServer *server, struct mg_connection *conn)
mg_printf(conn, {
"<p>The request was:<br><pre>%s %s HTTP/%s</pre></p>\n", /* Handler may access the request info using mg_get_request_info */
req_info->request_method, const struct mg_request_info *req_info = mg_get_request_info(conn);
req_info->uri, long long rlen, wlen;
req_info->http_version); long long nlen = 0;
mg_printf(conn, "<p>Content Length: %li</p>\n", (long)tlen); long long tlen = req_info->content_length;
mg_printf(conn, "<pre>\n"); FILE * f;
char buf[1024];
int fail = 0;
while (nlen < tlen) { _snprintf(buf, sizeof(buf), "D:\\somewhere\\%s\\%s", req_info->remote_user, req_info->local_uri);
rlen = tlen - nlen; buf[sizeof(buf)-1] = 0; /* TODO: check overflow */
if (rlen > sizeof(buf)) { f = fopen_recursive(buf, "wb");
rlen = sizeof(buf);
}
rlen = mg_read(conn, buf, rlen);
if (rlen <= 0) {
break;
}
wlen = mg_write(conn, buf, rlen);
if (rlen != rlen) {
break;
}
nlen += wlen;
}
mg_printf(conn, "\n</pre>\n"); if (!f) {
mg_printf(conn, "</body></html>\n"); fail = 1;
} else {
while (nlen < tlen) {
rlen = tlen - nlen;
if (rlen > sizeof(buf)) {
rlen = sizeof(buf);
}
rlen = mg_read(conn, buf, (size_t)rlen);
if (rlen <= 0) {
fail = 1;
break;
}
wlen = fwrite(buf, 1, (size_t)rlen, f);
if (rlen != rlen) {
fail = 1;
break;
}
nlen += wlen;
}
fclose(f);
}
return true; if (fail) {
} mg_printf(conn,
"HTTP/1.1 409 Conflict\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n");
MessageBeep(MB_ICONERROR);
} else {
mg_printf(conn,
"HTTP/1.1 201 Created\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n");
MessageBeep(MB_OK);
}
return true;
}
}; };
@ -257,7 +270,7 @@ main(int argc, char *argv[])
server.addHandler("/a/b", h_ab); server.addHandler("/a/b", h_ab);
FooHandler h_foo; FooHandler h_foo;
server.addHandler("**.foo$", h_foo); server.addHandler("", h_foo);
printf("Browse files at http://localhost:%s/\n", PORT); printf("Browse files at http://localhost:%s/\n", PORT);
printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI); printf("Run example at http://localhost:%s%s\n", PORT, EXAMPLE_URI);

View File

@ -803,6 +803,9 @@ typedef int socklen_t;
#if defined(NO_SSL_DL) #if defined(NO_SSL_DL)
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#else #else
/* SSL loaded dynamically from DLL. /* SSL loaded dynamically from DLL.
* I put the prototypes here to be independent from OpenSSL source * I put the prototypes here to be independent from OpenSSL source
@ -811,7 +814,12 @@ typedef int socklen_t;
typedef struct ssl_st SSL; typedef struct ssl_st SSL;
typedef struct ssl_method_st SSL_METHOD; typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_ctx_st SSL_CTX; typedef struct ssl_ctx_st SSL_CTX;
typedef struct x5099_store_ctx_st X509_STORE_CTX; typedef struct x509_store_ctx_st X509_STORE_CTX;
#define SSL_VERIFY_NONE (0)
#define SSL_VERIFY_PEER (1)
#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT (2)
#define SSL_VERIFY_CLIENT_ONCE (4)
struct ssl_func { struct ssl_func {
const char *name; /* SSL function name */ const char *name; /* SSL function name */
@ -841,14 +849,21 @@ struct ssl_func {
(*(int (*)(SSL_CTX *, const char *))ssl_sw[16].ptr) (*(int (*)(SSL_CTX *, const char *))ssl_sw[16].ptr)
#define SSLv23_client_method (*(SSL_METHOD * (*)(void))ssl_sw[17].ptr) #define SSLv23_client_method (*(SSL_METHOD * (*)(void))ssl_sw[17].ptr)
#define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr) #define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr)
#define SSL_CTX_set_verify (*(void (*)(SSL_CTX *, int, int))ssl_sw[19].ptr) #define SSL_CTX_set_verify \
(*(void (*)(SSL_CTX *, \
int, \
int (*verify_callback)(int, X509_STORE_CTX *)))ssl_sw[19].ptr)
#define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr) #define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr)
#define SSL_CTX_load_verify_locations \ #define SSL_CTX_load_verify_locations \
(*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[21].ptr) (*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[21].ptr)
#define SSL_CTX_set_default_verify_paths \ #define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))ssl_sw[22].ptr)
(*(int (*)(SSL_CTX *))ssl_sw[22].ptr)
#define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[23].ptr) #define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[23].ptr)
#define SSL_get_peer_certificate (*(X509 * (*)(SSL *))ssl_sw[24].ptr)
#define SSL_get_version (*(const char *(*)(SSL *))ssl_sw[25].ptr)
#define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *))ssl_sw[26].ptr)
#define SSL_CIPHER_get_name \
(*(const char *(*)(const SSL_CIPHER *))ssl_sw[27].ptr)
#define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))ssl_sw[28].ptr)
#define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr) #define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr)
#define CRYPTO_set_locking_callback \ #define CRYPTO_set_locking_callback \
(*(void (*)(void (*)(int, int, const char *, int)))crypto_sw[1].ptr) (*(void (*)(void (*)(int, int, const char *, int)))crypto_sw[1].ptr)
@ -885,6 +900,11 @@ static struct ssl_func ssl_sw[] = {{"SSL_free", NULL},
{"SSL_CTX_load_verify_locations", NULL}, {"SSL_CTX_load_verify_locations", NULL},
{"SSL_CTX_set_default_verify_paths", NULL}, {"SSL_CTX_set_default_verify_paths", NULL},
{"SSL_CTX_set_verify_depth", NULL}, {"SSL_CTX_set_verify_depth", NULL},
{"SSL_get_peer_certificate", NULL},
{"SSL_get_version", NULL},
{"SSL_get_current_cipher", NULL},
{"SSL_CIPHER_get_name", NULL},
{"SSL_CTX_check_private_key", NULL},
{NULL, NULL}}; {NULL, NULL}};
/* Similar array as ssl_sw. These functions could be located in different /* Similar array as ssl_sw. These functions could be located in different
@ -980,7 +1000,7 @@ enum {
REWRITE, REWRITE,
HIDE_FILES, HIDE_FILES,
REQUEST_TIMEOUT, REQUEST_TIMEOUT,
SSL_VERIFY_PEER, SSL_DO_VERIFY_PEER,
SSL_CA_PATH, SSL_CA_PATH,
SSL_CA_FILE, SSL_CA_FILE,
SSL_VERIFY_DEPTH, SSL_VERIFY_DEPTH,
@ -1045,12 +1065,12 @@ static struct mg_option config_options[] = {
{"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL}, {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL},
{"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL}, {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL},
{"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"}, {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
{"ssl_verify_peer", CONFIG_TYPE_BOOLEAN, "no"}, {"ssl_verify_peer", CONFIG_TYPE_BOOLEAN, "no"},
{"ssl_ca_path", CONFIG_TYPE_DIRECTORY, NULL}, {"ssl_ca_path", CONFIG_TYPE_DIRECTORY, NULL},
{"ssl_ca_file", CONFIG_TYPE_FILE, NULL}, {"ssl_ca_file", CONFIG_TYPE_FILE, NULL},
{"ssl_verify_depth", CONFIG_TYPE_NUMBER, "9"}, {"ssl_verify_depth", CONFIG_TYPE_NUMBER, "9"},
{"ssl_default_verify_paths", CONFIG_TYPE_BOOLEAN, "yes"}, {"ssl_default_verify_paths", CONFIG_TYPE_BOOLEAN, "yes"},
{"ssl_forward_secrecy", CONFIG_TYPE_BOOLEAN, "yes"}, {"ssl_forward_secrecy", CONFIG_TYPE_BOOLEAN, "yes"},
#if defined(USE_WEBSOCKET) #if defined(USE_WEBSOCKET)
{"websocket_timeout_ms", CONFIG_TYPE_NUMBER, "30000"}, {"websocket_timeout_ms", CONFIG_TYPE_NUMBER, "30000"},
#endif #endif
@ -8199,7 +8219,7 @@ mg_websocket_client_write(struct mg_connection *conn,
lcg = lcg * 6364136223846793005 + 1442695040888963407; lcg = lcg * 6364136223846793005 + 1442695040888963407;
} }
masking_key = (uint32_t)lfsr ^ (uint32_t)lcg ^ now.tv_nsec; masking_key = (uint32_t)lfsr ^ (uint32_t)lcg ^ (uint32_t)now.tv_nsec;
if (masked_data == NULL) { if (masked_data == NULL) {
/* Return -1 in an error case */ /* Return -1 in an error case */
@ -9400,6 +9420,7 @@ close_all_listening_sockets(struct mg_context *ctx)
ctx->listening_ports = NULL; ctx->listening_ports = NULL;
} }
/* Valid listening port specification is: [ip_address:]port[s] /* Valid listening port specification is: [ip_address:]port[s]
* Examples for IPv4: 80, 443s, 127.0.0.1:3128, 1.2.3.4:8080s * Examples for IPv4: 80, 443s, 127.0.0.1:3128, 1.2.3.4:8080s
* Examples for IPv6: [::]:80, [::1]:80, * Examples for IPv6: [::]:80, [::1]:80,
@ -9456,6 +9477,7 @@ parse_port_string(const struct vec *vec, struct socket *so)
&& (ch == '\0' || ch == 's' || ch == 'r' || ch == ','); && (ch == '\0' || ch == 's' || ch == 'r' || ch == ',');
} }
static int static int
set_ports_option(struct mg_context *ctx) set_ports_option(struct mg_context *ctx)
{ {
@ -9667,6 +9689,7 @@ set_ports_option(struct mg_context *ctx)
return portsOk; return portsOk;
} }
static const char * static const char *
header_val(const struct mg_connection *conn, const char *header) header_val(const struct mg_connection *conn, const char *header)
{ {
@ -9679,6 +9702,7 @@ header_val(const struct mg_connection *conn, const char *header)
} }
} }
static void static void
log_access(const struct mg_connection *conn) log_access(const struct mg_connection *conn)
{ {
@ -9748,6 +9772,7 @@ log_access(const struct mg_connection *conn)
} }
} }
/* Verify given socket address against the ACL. /* Verify given socket address against the ACL.
* Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed. */ * Return -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed. */
static int static int
@ -9783,6 +9808,7 @@ check_acl(struct mg_context *ctx, uint32_t remote_ip)
return -1; return -1;
} }
#if !defined(_WIN32) #if !defined(_WIN32)
static int static int
set_uid_option(struct mg_context *ctx) set_uid_option(struct mg_context *ctx)
@ -9825,6 +9851,7 @@ set_uid_option(struct mg_context *ctx)
} }
#endif /* !_WIN32 */ #endif /* !_WIN32 */
static void static void
tls_dtor(void *key) tls_dtor(void *key)
{ {
@ -9840,6 +9867,7 @@ tls_dtor(void *key)
pthread_setspecific(sTlsKey, NULL); pthread_setspecific(sTlsKey, NULL);
} }
#if !defined(NO_SSL) #if !defined(NO_SSL)
/* Must be set if sizeof(pthread_t) > sizeof(unsigned long) */ /* Must be set if sizeof(pthread_t) > sizeof(unsigned long) */
@ -9886,19 +9914,37 @@ ssl_id_callback(void)
static pthread_mutex_t *ssl_mutexes; static pthread_mutex_t *ssl_mutexes;
static int static int
sslize(struct mg_connection *conn, SSL_CTX *s, int (*func)(SSL *)) sslize(struct mg_connection *conn, SSL_CTX *s, int (*func)(SSL *))
{ {
int ret, err;
if (!conn) { if (!conn) {
return 0; return 0;
} }
conn->ssl = SSL_new(s); conn->ssl = SSL_new(s);
return (conn->ssl != NULL) if (conn->ssl == NULL) {
&& SSL_set_fd(conn->ssl, conn->client.sock) == 1 return 0;
&& func(conn->ssl) == 1; }
ret = SSL_set_fd(conn->ssl, conn->client.sock);
if (ret != 1) {
err = SSL_get_error(conn->ssl, ret);
return 0;
}
ret = func(conn->ssl);
if (ret != 1) {
err = SSL_get_error(conn->ssl, ret);
return 0;
}
return 1;
} }
/* Return OpenSSL error message (from CRYPTO lib) */ /* Return OpenSSL error message (from CRYPTO lib) */
static const char * static const char *
ssl_error(void) ssl_error(void)
@ -9908,6 +9954,7 @@ ssl_error(void)
return err == 0 ? "" : ERR_error_string(err, NULL); return err == 0 ? "" : ERR_error_string(err, NULL);
} }
static void static void
ssl_locking_callback(int mode, int mutex_num, const char *file, int line) ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
{ {
@ -9922,6 +9969,7 @@ ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
} }
} }
#if !defined(NO_SSL_DL) #if !defined(NO_SSL_DL)
static void * static void *
load_dll(struct mg_context *ctx, const char *dll_name, struct ssl_func *sw) load_dll(struct mg_context *ctx, const char *dll_name, struct ssl_func *sw)
@ -9969,12 +10017,14 @@ static void *cryptolib_dll_handle; /* Store the crypto library handle. */
#endif /* NO_SSL_DL */ #endif /* NO_SSL_DL */
#if defined(SSL_ALREADY_INITIALIZED) #if defined(SSL_ALREADY_INITIALIZED)
static int cryptolib_users = 1; /* Reference counter for crypto library. */ static int cryptolib_users = 1; /* Reference counter for crypto library. */
#else #else
static int cryptolib_users = 0; /* Reference counter for crypto library. */ static int cryptolib_users = 0; /* Reference counter for crypto library. */
#endif #endif
static int static int
initialize_ssl(struct mg_context *ctx) initialize_ssl(struct mg_context *ctx)
{ {
@ -10020,6 +10070,30 @@ initialize_ssl(struct mg_context *ctx)
return 1; return 1;
} }
int
verify_ssl_client(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
int ret = preverify_ok;
/* TODO: check if this function is required at all
TODO: store rejected connection attempts
char buf[256];
struct X509 *err_cert;
int err, depth;
SSL *ssl;
*/
/* Ignore pre-verification - only accept clients we know locally */
(void)preverify_ok;
/*
err_cert = X509_STORE_CTX_get_current_cert(x509_st);
err = X509_STORE_CTX_get_error(x509_st);
depth = X509_STORE_CTX_get_error_depth(x509_st);
*/
return ret;
}
/* Dynamically load SSL library. Set up ctx->ssl_ctx pointer. */ /* Dynamically load SSL library. Set up ctx->ssl_ctx pointer. */
static int static int
set_ssl_option(struct mg_context *ctx) set_ssl_option(struct mg_context *ctx)
@ -10027,8 +10101,8 @@ set_ssl_option(struct mg_context *ctx)
const char *pem; const char *pem;
int callback_ret; int callback_ret;
int should_verify_peer; int should_verify_peer;
const char* ca_path; const char *ca_path;
const char* ca_file; const char *ca_file;
int use_default_verify_paths; int use_default_verify_paths;
int verify_depth; int verify_depth;
@ -10077,54 +10151,101 @@ set_ssl_option(struct mg_context *ctx)
mg_cry(fc(ctx), "SSL callback returned error: %i", callback_ret); mg_cry(fc(ctx), "SSL callback returned error: %i", callback_ret);
return 0; return 0;
} }
if (callback_ret == 0) { if (callback_ret > 0) {
if (pem != NULL) { if (pem != NULL) {
if ((SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem, 1) == 0) (void)SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem);
|| (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem, 1) == 0)) {
mg_cry(fc(ctx),
"%s: cannot open %s: %s",
__func__,
pem,
ssl_error());
return 0;
}
} }
return 1;
} }
if (pem != NULL) { if (pem != NULL) {
(void)SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem); if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem, 1) == 0) {
mg_cry(fc(ctx),
"%s: cannot open certificate file %s: %s",
__func__,
pem,
ssl_error());
return 0;
}
/* could use SSL_CTX_set_default_passwd_cb_userdata */
if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem, 1) == 0) {
mg_cry(fc(ctx),
"%s: cannot open private key file %s: %s",
__func__,
pem,
ssl_error());
return 0;
}
if (SSL_CTX_check_private_key(ctx->ssl_ctx) == 0) {
mg_cry(fc(ctx),
"%s: certificate and private key do not match: %s",
__func__,
pem);
return 0;
}
if (SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem) == 0) {
mg_cry(fc(ctx),
"%s: cannot use certificate chain file %s: %s",
__func__,
pem,
ssl_error());
return 0;
}
} }
should_verify_peer = (ctx->config[SSL_VERIFY_PEER] != NULL) should_verify_peer =
&& (mg_strcasecmp(ctx->config[SSL_VERIFY_PEER], "yes") == 0); (ctx->config[SSL_DO_VERIFY_PEER] != NULL)
&& (mg_strcasecmp(ctx->config[SSL_DO_VERIFY_PEER], "yes") == 0);
use_default_verify_paths = (ctx->config[SSL_DEFAULT_VERIFY_PATHS] != NULL) use_default_verify_paths =
&& (mg_strcasecmp(ctx->config[SSL_DEFAULT_VERIFY_PATHS], "yes") == 0); (ctx->config[SSL_DEFAULT_VERIFY_PATHS] != NULL)
&& (mg_strcasecmp(ctx->config[SSL_DEFAULT_VERIFY_PATHS], "yes") == 0);
if (should_verify_peer) { if (should_verify_peer) {
ca_path = ctx->config[SSL_CA_PATH]; ca_path = ctx->config[SSL_CA_PATH];
ca_file = ctx->config[SSL_CA_FILE]; ca_file = ctx->config[SSL_CA_FILE];
if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, ca_file, ca_path) != 1) { if (SSL_CTX_load_verify_locations(ctx->ssl_ctx, ca_file, ca_path)
mg_cry(fc(ctx), "SSL_CTX_load_verify_locations error: %s " != 1) {
"ssl_verify_peer requires setting " mg_cry(
"either ssl_ca_path or ssl_ca_file. Is any of them present in " fc(ctx),
"the .conf file?", ssl_error()); "SSL_CTX_load_verify_locations error: %s "
"ssl_verify_peer requires setting "
"either ssl_ca_path or ssl_ca_file. Is any of them present in "
"the .conf file?",
ssl_error());
return 0; return 0;
} }
SSL_CTX_set_verify(ctx->ssl_ctx, 3, 0); SSL_CTX_set_verify(ctx->ssl_ctx, 3, 0);
if (use_default_verify_paths if (use_default_verify_paths
&& SSL_CTX_set_default_verify_paths(ctx->ssl_ctx) != 1) { && SSL_CTX_set_default_verify_paths(ctx->ssl_ctx) != 1) {
mg_cry(fc(ctx), "SSL_CTX_set_default_verify_paths error: %s", ssl_error()); mg_cry(fc(ctx),
"SSL_CTX_set_default_verify_paths error: %s",
ssl_error());
return 0; return 0;
} }
if (ctx->config[SSL_VERIFY_DEPTH]){ if (ctx->config[SSL_VERIFY_DEPTH]) {
verify_depth = atoi(ctx->config[SSL_VERIFY_DEPTH]); verify_depth = atoi(ctx->config[SSL_VERIFY_DEPTH]);
SSL_CTX_set_verify_depth(ctx->ssl_ctx, verify_depth); SSL_CTX_set_verify_depth(ctx->ssl_ctx, verify_depth);
} }
} }
/* TODO: could set use SSL_CTX_set_cipher_list if set*/
/* TODO: could use client certificates here */
#if 0
SSL_CTX_set_verify(ctx->ssl_ctx,
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
NULL);
SSL_CTX_load_verify_locations(ctx->ssl_ctx, "D:\\civetweb\\civetweb\\resources\\cert\\client.pem", NULL);
#endif
return 1; return 1;
} }
@ -10355,6 +10476,7 @@ mg_close_connection(struct mg_connection *conn)
mg_free(conn); mg_free(conn);
} }
struct mg_connection * struct mg_connection *
mg_connect_client(const char *host, mg_connect_client(const char *host,
int port, int port,
@ -10429,7 +10551,9 @@ mg_connect_client(const char *host,
SSL_CTX_set_verify call is needed to switch off server SSL_CTX_set_verify call is needed to switch off server
* certificate checking, which is off by default in OpenSSL and on * certificate checking, which is off by default in OpenSSL and on
* in yaSSL. */ * in yaSSL. */
SSL_CTX_set_verify(conn->client_ssl_ctx, 0, 0); SSL_CTX_set_verify(conn->client_ssl_ctx, SSL_VERIFY_NONE, NULL);
// TODO: SSL_CTX_set_verify(conn->client_ssl_ctx, SSL_VERIFY_PEER,
// verify_ssl_server);
sslize(conn, conn->client_ssl_ctx, SSL_connect); sslize(conn, conn->client_ssl_ctx, SSL_connect);
} }
#endif #endif
@ -11162,6 +11286,8 @@ worker_thread_run(void *thread_func_param)
|| sslize(conn, conn->ctx->ssl_ctx, SSL_accept) || sslize(conn, conn->ctx->ssl_ctx, SSL_accept)
#endif #endif
) { ) {
process_new_connection(conn); process_new_connection(conn);
} }

View File

@ -2279,6 +2279,83 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdline, int show)
HWND hWnd; HWND hWnd;
MSG msg; MSG msg;
int i;
int dataLen = 4;
char data[256] = {0};
char masked_data[256] = {0};
uint32_t masking_key = 0x01020304;
for (i = 0; i < dataLen - 3; i += 4) {
*(uint32_t *)(void *)(masked_data + i) =
*(uint32_t *)(void *)(data + i) ^ masking_key;
}
if (i != dataLen) {
/* convert 1-3 remaining bytes */
i -= 4;
while (i < dataLen) {
*(uint8_t *)(void *)(masked_data + i) =
*(uint8_t *)(void *)(data + i)
^ *(((uint8_t *)&masking_key) + (i % 4));
i++;
}
}
#if 0
/* http://lomont.org/Math/Papers/2008/Lomont_PRNG_2008.pdf */
/* initialize state to random bits
*/
static unsigned long state[16];
/* init should also reset this to 0 */
static unsigned int index = 0;
/* return 32 bit random number
*/
unsigned long WELLRN G512(void)
{
unsigned long a, b, c, d;
a = state[index];
c = state[(index + 13) & 15];
b = a ^ c ^ (a << 16) ^ (c << 15);
c = state[(index + 9) & 15];
c ^= (c >> 11);
a = state[index] = b ^ c;
d = a ^ ((a << 5) & 0xDA442D24 UL);
index = (index + 15) & 15;
a = state[index];
state[index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28);
return state[index];
}
uint32_t x, y, z, w;
uint32_t xorshift128(void)
{
uint32_t t = x ^ (x << 11);
x = y;
y = z;
z = w;
return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}
static uint64_t lfsr = 1;
static uint64_t lcg = 0;
uint64_t r = 0;
do {
lfsr = (lfsr >> 1)
| ((((lfsr >> 0) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1)
<< 63);
lcg = lcg * 6364136223846793005 + 1442695040888963407;
++r;
} while (lcg != 0);
fprintf(stdout, "lfsr = %I64u, lcg = %i64u, r = %i64u\n", lfsr, lcg, r);
#endif
(void)hInst; (void)hInst;
(void)hPrev; (void)hPrev;
(void)cmdline; (void)cmdline;