2017-12-29 06:40:58 +00:00
|
|
|
/*
|
2018-03-03 09:33:49 +00:00
|
|
|
* Copyright (C) 2017 Jianhui Zhao <jianhuizhao329@gmail.com>
|
2017-12-29 06:40:58 +00:00
|
|
|
*
|
2018-03-03 09:33:49 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2017-12-29 06:40:58 +00:00
|
|
|
*
|
2018-03-03 09:33:49 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
|
|
* USA
|
2017-12-29 06:40:58 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <dlfcn.h>
|
2018-01-17 04:50:25 +00:00
|
|
|
#include <errno.h>
|
|
|
|
|
2017-12-29 06:40:58 +00:00
|
|
|
#include "uhttpd.h"
|
|
|
|
#include "uh_ssl.h"
|
2018-01-17 04:50:25 +00:00
|
|
|
#include "log.h"
|
2017-12-29 06:40:58 +00:00
|
|
|
|
|
|
|
static bool _init = false;
|
|
|
|
static struct ustream_ssl_ops *ops;
|
|
|
|
static void *dlh;
|
|
|
|
static void *ctx;
|
|
|
|
|
|
|
|
int uh_ssl_init(struct uh_server *srv, const char *key, const char *crt)
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
srv->ssl = true;
|
|
|
|
|
|
|
|
if (_init)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
dlh = dlopen("libustream-ssl.so", RTLD_LAZY | RTLD_LOCAL);
|
|
|
|
if (!dlh) {
|
|
|
|
uh_log_err("Failed to load ustream-ssl library: %s", dlerror());
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
ops = dlsym(dlh, "ustream_ssl_ops");
|
|
|
|
if (!ops) {
|
|
|
|
uh_log_err("Could not find required symbol 'ustream_ssl_ops' in ustream-ssl library");
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx = ops->context_new(true);
|
|
|
|
if (!ctx) {
|
|
|
|
uh_log_err("Failed to initialize ustream-ssl");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ops->context_set_crt_file(ctx, crt) ||
|
|
|
|
ops->context_set_key_file(ctx, key)) {
|
|
|
|
uh_log_err("Failed to load certificate/key files");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2017-12-31 09:28:27 +00:00
|
|
|
_init = true;
|
|
|
|
|
2017-12-30 03:40:37 +00:00
|
|
|
return 0;
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void uh_ssl_free()
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
if (_init) {
|
|
|
|
_init = false;
|
|
|
|
ops->context_free(ctx);
|
|
|
|
}
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ssl_ustream_read_cb(struct ustream *s, int bytes)
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
struct uh_client *cl = container_of(s, struct uh_client, ssl.stream);
|
2017-12-29 06:40:58 +00:00
|
|
|
|
2017-12-30 03:40:37 +00:00
|
|
|
uh_client_read_cb(cl);
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ssl_ustream_write_cb(struct ustream *s, int bytes)
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
struct uh_client *cl = container_of(s, struct uh_client, ssl.stream);
|
2017-12-29 06:40:58 +00:00
|
|
|
|
2017-12-30 03:40:37 +00:00
|
|
|
if (cl->dispatch.write_cb)
|
|
|
|
cl->dispatch.write_cb(cl);
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ssl_notify_state(struct ustream *s)
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
struct uh_client *cl = container_of(s, struct uh_client, ssl.stream);
|
2017-12-29 06:40:58 +00:00
|
|
|
|
2017-12-30 03:40:37 +00:00
|
|
|
uh_client_notify_state(cl);
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void uh_ssl_client_attach(struct uh_client *cl)
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
cl->us = &cl->ssl.stream;
|
|
|
|
ops->init(&cl->ssl, &cl->sfd.stream, ctx, true);
|
|
|
|
cl->us->notify_read = ssl_ustream_read_cb;
|
|
|
|
cl->us->notify_write = ssl_ustream_write_cb;
|
|
|
|
cl->us->notify_state = ssl_notify_state;
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void uh_ssl_client_detach(struct uh_client *cl)
|
|
|
|
{
|
2017-12-30 03:40:37 +00:00
|
|
|
ustream_free(&cl->ssl.stream);
|
2017-12-29 06:40:58 +00:00
|
|
|
}
|