Commit 73a0a9f9 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Factor HTTP/TLS server code into httpd core

parent 86614c50
...@@ -100,7 +100,7 @@ struct httpd_message_t ...@@ -100,7 +100,7 @@ struct httpd_message_t
/* create a new host */ /* create a new host */
VLC_API httpd_host_t * httpd_HostNew( vlc_object_t *, const char *psz_host, int i_port ) VLC_USED; VLC_API httpd_host_t * httpd_HostNew( vlc_object_t *, const char *psz_host, int i_port ) VLC_USED;
VLC_API httpd_host_t * httpd_TLSHostNew( vlc_object_t *, const char *, int, const char *, const char *, const char *, const char * ) VLC_USED; VLC_API httpd_host_t * httpd_TLSHostNew( vlc_object_t *, const char *, int ) VLC_USED;
/* delete a host */ /* delete a host */
VLC_API void httpd_HostDelete( httpd_host_t * ); VLC_API void httpd_HostDelete( httpd_host_t * );
......
...@@ -71,22 +71,6 @@ static void Close( vlc_object_t * ); ...@@ -71,22 +71,6 @@ static void Close( vlc_object_t * );
#define MIME_TEXT N_("Mime") #define MIME_TEXT N_("Mime")
#define MIME_LONGTEXT N_("MIME returned by the server (autodetected " \ #define MIME_LONGTEXT N_("MIME returned by the server (autodetected " \
"if not specified)." ) "if not specified)." )
#define CERT_TEXT N_( "Certificate file" )
#define CERT_LONGTEXT N_( "Path to the x509 PEM certificate file that will "\
"be used for HTTPS." )
#define KEY_TEXT N_( "Private key file" )
#define KEY_LONGTEXT N_( "Path to the x509 PEM private key file that will " \
"be used for HTTPS. Leave " \
"empty if you don't have one." )
#define CA_TEXT N_( "Root CA file" )
#define CA_LONGTEXT N_( "Path to the x509 PEM trusted root CA certificates " \
"(certificate authority) file that will be used for " \
"HTTPS. Leave empty if you " \
"don't have one." )
#define CRL_TEXT N_( "CRL file" )
#define CRL_LONGTEXT N_( "Path to the x509 PEM Certificates Revocation List " \
"file that will be used for SSL. Leave " \
"empty if you don't have one." )
#define BONJOUR_TEXT N_( "Advertise with Bonjour") #define BONJOUR_TEXT N_( "Advertise with Bonjour")
#define BONJOUR_LONGTEXT N_( "Advertise the stream with the Bonjour protocol." ) #define BONJOUR_LONGTEXT N_( "Advertise the stream with the Bonjour protocol." )
...@@ -104,14 +88,6 @@ vlc_module_begin () ...@@ -104,14 +88,6 @@ vlc_module_begin ()
PASS_TEXT, PASS_LONGTEXT, true ) PASS_TEXT, PASS_LONGTEXT, true )
add_string( SOUT_CFG_PREFIX "mime", "", add_string( SOUT_CFG_PREFIX "mime", "",
MIME_TEXT, MIME_LONGTEXT, true ) MIME_TEXT, MIME_LONGTEXT, true )
add_loadfile( SOUT_CFG_PREFIX "cert", "vlc.pem",
CERT_TEXT, CERT_LONGTEXT, true )
add_loadfile( SOUT_CFG_PREFIX "key", NULL,
KEY_TEXT, KEY_LONGTEXT, true )
add_loadfile( SOUT_CFG_PREFIX "ca", NULL,
CA_TEXT, CA_LONGTEXT, true )
add_loadfile( SOUT_CFG_PREFIX "crl", NULL,
CRL_TEXT, CRL_LONGTEXT, true )
#if 0 //def HAVE_AVAHI_CLIENT #if 0 //def HAVE_AVAHI_CLIENT
add_bool( SOUT_CFG_PREFIX "bonjour", false, add_bool( SOUT_CFG_PREFIX "bonjour", false,
BONJOUR_TEXT, BONJOUR_LONGTEXT, true); BONJOUR_TEXT, BONJOUR_LONGTEXT, true);
...@@ -166,8 +142,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -166,8 +142,6 @@ static int Open( vlc_object_t *p_this )
char *psz_user; char *psz_user;
char *psz_pwd; char *psz_pwd;
char *psz_mime; char *psz_mime;
char *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL,
*psz_crl = NULL;
if( !( p_sys = p_access->p_sys = if( !( p_sys = p_access->p_sys =
malloc( sizeof( sout_access_out_sys_t ) ) ) ) malloc( sizeof( sout_access_out_sys_t ) ) ) )
...@@ -211,32 +185,22 @@ static int Open( vlc_object_t *p_this ) ...@@ -211,32 +185,22 @@ static int Open( vlc_object_t *p_this )
psz_parser = psz_bind_addr; psz_parser = psz_bind_addr;
} }
/* SSL support */ /* TLS support */
if( p_access->psz_access && !strcmp( p_access->psz_access, "https" ) ) if( p_access->psz_access && !strcmp( p_access->psz_access, "https" ) )
{ {
psz_cert = var_CreateGetNonEmptyString( p_this, SOUT_CFG_PREFIX"cert" );
psz_key = var_CreateGetNonEmptyString( p_this, SOUT_CFG_PREFIX"key" );
psz_ca = var_CreateGetNonEmptyString( p_this, SOUT_CFG_PREFIX"ca" );
psz_crl = var_CreateGetNonEmptyString( p_this, SOUT_CFG_PREFIX"crl" );
if( i_bind_port <= 0 ) if( i_bind_port <= 0 )
i_bind_port = DEFAULT_SSL_PORT; i_bind_port = DEFAULT_SSL_PORT;
p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access),
psz_bind_addr, i_bind_port );
} }
else else
{ {
if( i_bind_port <= 0 ) if( i_bind_port <= 0 )
i_bind_port = DEFAULT_PORT; i_bind_port = DEFAULT_PORT;
p_sys->p_httpd_host = httpd_HostNew( VLC_OBJECT(p_access),
psz_bind_addr, i_bind_port );
} }
p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access),
psz_bind_addr, i_bind_port,
psz_cert, psz_key, psz_ca,
psz_crl );
free( psz_cert );
free( psz_key );
free( psz_ca );
free( psz_crl );
if( p_sys->p_httpd_host == NULL ) if( p_sys->p_httpd_host == NULL )
{ {
msg_Err( p_access, "cannot listen on %s port %d", msg_Err( p_access, "cannot listen on %s port %d",
......
...@@ -70,18 +70,10 @@ static int vlclua_httpd_tls_host_new( lua_State *L ) ...@@ -70,18 +70,10 @@ static int vlclua_httpd_tls_host_new( lua_State *L )
vlc_object_t *p_this = vlclua_get_this( L ); vlc_object_t *p_this = vlclua_get_this( L );
const char *psz_host = luaL_checkstring( L, 1 ); const char *psz_host = luaL_checkstring( L, 1 );
int i_port = luaL_checkint( L, 2 ); int i_port = luaL_checkint( L, 2 );
const char *psz_cert = luaL_optstring( L, 3, NULL ); httpd_host_t *p_host = httpd_HostNew( p_this, psz_host, i_port );
const char *psz_key = luaL_optstring( L, 4, NULL );
const char *psz_ca = luaL_optstring( L, 5, NULL );
const char *psz_crl = luaL_optstring( L, 6, NULL );
httpd_host_t *p_host = httpd_TLSHostNew( p_this, psz_host, i_port,
psz_cert, psz_key,
psz_ca, psz_crl );
if( !p_host ) if( !p_host )
return luaL_error( L, "Failed to create HTTP TLS host \"%s:%d\" " return luaL_error( L, "Failed to create HTTP host \"%s:%d\" ",
"(cert: \"%s\", key: \"%s\", ca: \"%s\", " psz_host, i_port );
"crl: \"%s\").", psz_host, i_port,
psz_cert, psz_key, psz_ca, psz_crl );
httpd_host_t **pp_host = lua_newuserdata( L, sizeof( httpd_host_t * ) ); httpd_host_t **pp_host = lua_newuserdata( L, sizeof( httpd_host_t * ) );
*pp_host = p_host; *pp_host = p_host;
......
...@@ -889,6 +889,24 @@ static const char *const ppsz_clock_descriptions[] = ...@@ -889,6 +889,24 @@ static const char *const ppsz_clock_descriptions[] =
#define TIMEOUT_LONGTEXT N_( \ #define TIMEOUT_LONGTEXT N_( \
"Default TCP connection timeout (in milliseconds). " ) "Default TCP connection timeout (in milliseconds). " )
#define HTTP_CERT_TEXT N_("HTTP/TLS server certificate")
#define CERT_LONGTEXT N_( \
"This X.509 certicate file (PEM format) is used for server-side TLS." )
#define HTTP_KEY_TEXT N_("HTTP/TLS server private key")
#define KEY_LONGTEXT N_( \
"This private key file (PEM format) is used for server-side TLS.")
#define HTTP_CA_TEXT N_("HTTP/TLS Certificate Authority")
#define CA_LONGTEXT N_( \
"This X.509 certificate file (PEM format) can optionally be used " \
"to authenticate remote clients in TLS sessions.")
#define HTTP_CRL_TEXT N_("HTTP/TLS Certificate Revocation List")
#define CRL_LONGTEXT N_( \
"This file countains an optional CRL to prevent remove clients " \
"from using revoked certificates in TLS sessions.")
#define SOCKS_SERVER_TEXT N_("SOCKS server") #define SOCKS_SERVER_TEXT N_("SOCKS server")
#define SOCKS_SERVER_LONGTEXT N_( \ #define SOCKS_SERVER_LONGTEXT N_( \
"SOCKS proxy server to use. This must be of the form " \ "SOCKS proxy server to use. This must be of the form " \
...@@ -1881,6 +1899,15 @@ vlc_module_begin () ...@@ -1881,6 +1899,15 @@ vlc_module_begin ()
add_integer( "ipv4-timeout", 5 * 1000, TIMEOUT_TEXT, add_integer( "ipv4-timeout", 5 * 1000, TIMEOUT_TEXT,
TIMEOUT_LONGTEXT, true ) TIMEOUT_LONGTEXT, true )
add_loadfile( "http-cert", NULL, HTTP_CERT_TEXT, CERT_LONGTEXT, true )
add_deprecated_alias( "sout-http-cert" ) /* since 1.2.0 */
add_loadfile( "http-key", NULL, HTTP_KEY_TEXT, KEY_LONGTEXT, true )
add_deprecated_alias( "sout-http-key" ) /* since 1.2.0 */
add_loadfile( "http-ca", NULL, HTTP_CA_TEXT, CA_LONGTEXT, true )
add_deprecated_alias( "sout-http-ca" ) /* since 1.2.0 */
add_loadfile( "http-crl", NULL, HTTP_CRL_TEXT, CRL_LONGTEXT, true )
add_deprecated_alias( "sout-http-crl" ) /* since 1.2.0 */
set_section( N_( "Socks proxy") , NULL ) set_section( N_( "Socks proxy") , NULL )
add_string( "socks", NULL, add_string( "socks", NULL,
SOCKS_SERVER_TEXT, SOCKS_SERVER_LONGTEXT, true ) SOCKS_SERVER_TEXT, SOCKS_SERVER_LONGTEXT, true )
......
...@@ -95,7 +95,14 @@ void httpd_HostDelete (httpd_host_t *h) ...@@ -95,7 +95,14 @@ void httpd_HostDelete (httpd_host_t *h)
httpd_host_t *httpd_HostNew (vlc_object_t *obj, const char *host, int port) httpd_host_t *httpd_HostNew (vlc_object_t *obj, const char *host, int port)
{ {
return httpd_TLSHostNew (obj, host, port, NULL, NULL, NULL, NULL); (void) host; (void) port;
msg_Err (obj, "VLC httpd support not compiled-in!");
return NULL;
}
httpd_host_t *httpd_TLSHostNew (vlc_object_t *obj, const char *host, int port)
{
return httpd_HostNew (obj, host, port);
} }
void httpd_MsgAdd (httpd_message_t *m, const char *name, const char *fmt, ...) void httpd_MsgAdd (httpd_message_t *m, const char *name, const char *fmt, ...)
...@@ -157,16 +164,6 @@ int httpd_StreamSend (httpd_stream_t *stream, uint8_t *data, int count) ...@@ -157,16 +164,6 @@ int httpd_StreamSend (httpd_stream_t *stream, uint8_t *data, int count)
assert (0); assert (0);
} }
httpd_host_t *httpd_TLSHostNew (vlc_object_t *obj, const char *host, int port,
const char *cert, const char *key,
const char *ca, const char *crl)
{
(void) host; (void) port;
(void) cert; (void) key; (void) ca; (void) crl;
msg_Err (obj, "VLC httpd support not compiled-in!");
return NULL;
}
int httpd_UrlCatch (httpd_url_t *url, int request, httpd_callback_t cb, int httpd_UrlCatch (httpd_url_t *url, int request, httpd_callback_t cb,
httpd_callback_sys_t *data) httpd_callback_sys_t *data)
{ {
......
...@@ -964,25 +964,78 @@ void httpd_StreamDelete( httpd_stream_t *stream ) ...@@ -964,25 +964,78 @@ void httpd_StreamDelete( httpd_stream_t *stream )
* Low level * Low level
*****************************************************************************/ *****************************************************************************/
static void* httpd_HostThread( void * ); static void* httpd_HostThread( void * );
static httpd_host_t *httpd_HostCreate( vlc_object_t *, const char *, int,
vlc_tls_creds_t * );
/* create a new host */ /* create a new host */
httpd_host_t *httpd_HostNew( vlc_object_t *p_this, const char *psz_host, httpd_host_t *httpd_HostNew( vlc_object_t *p_this, const char *psz_host,
int i_port ) int i_port )
{ {
return httpd_TLSHostNew( p_this, psz_host, i_port, NULL, NULL, NULL, NULL return httpd_HostCreate( p_this, psz_host, i_port, NULL );
); }
httpd_host_t *httpd_TLSHostNew( vlc_object_t *obj, const char *host, int port )
{
char *cert = var_InheritString( obj, "http-cert" );
if( cert == NULL )
{
msg_Err( obj, "HTTP/TLS certificate not specified!" );
return NULL;
}
char *key = var_InheritString( obj, "http-key" );
vlc_tls_creds_t *tls = vlc_tls_ServerCreate( obj, cert, key );
if( tls == NULL )
{
msg_Err( obj, "HTTP/TLS certificate error (%s and %s)",
cert, (key != NULL) ? key : cert );
free( key );
free( cert );
return NULL;
}
free( key );
free( cert );
char *ca = var_InheritString( obj, "http-ca" );
if( ca != NULL )
{
if( vlc_tls_ServerAddCA( tls, ca ) )
{
msg_Err( obj, "HTTP/TLS CA error (%s)", ca );
free( ca );
goto error;
}
free( ca );
}
char *crl = var_InheritString( obj, "http-crl" );
if( crl != NULL )
{
if( vlc_tls_ServerAddCRL( tls, crl ) )
{
msg_Err( obj, "TLS CRL error (%s)", crl );
free( crl );
goto error;
}
free( crl );
}
return httpd_HostCreate( obj, host, port, tls );
error:
vlc_tls_ServerDelete( tls );
return NULL;
} }
static vlc_mutex_t httpd_mutex = VLC_STATIC_MUTEX; static vlc_mutex_t httpd_mutex = VLC_STATIC_MUTEX;
httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname, static httpd_host_t *httpd_HostCreate( vlc_object_t *p_this,
int i_port, const char *psz_hostname, int i_port,
const char *psz_cert, const char *psz_key, vlc_tls_creds_t *p_tls )
const char *psz_ca, const char *psz_crl )
{ {
httpd_t *httpd; httpd_t *httpd;
httpd_host_t *host; httpd_host_t *host;
vlc_tls_creds_t *p_tls;
char *psz_host; char *psz_host;
int i; int i;
...@@ -1021,7 +1074,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname, ...@@ -1021,7 +1074,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
host = httpd->host[i]; host = httpd->host[i];
/* cannot mix TLS and non-TLS hosts */ /* cannot mix TLS and non-TLS hosts */
if( ( ( httpd->host[i]->p_tls != NULL ) != ( psz_cert != NULL ) ) if( ( ( httpd->host[i]->p_tls != NULL ) != ( p_tls != NULL ) )
|| ( host->i_port != i_port ) || ( host->i_port != i_port )
|| strcmp( host->psz_hostname, psz_hostname ) ) || strcmp( host->psz_hostname, psz_hostname ) )
continue; continue;
...@@ -1035,36 +1088,13 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname, ...@@ -1035,36 +1088,13 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
vlc_mutex_unlock( &host->lock ); vlc_mutex_unlock( &host->lock );
vlc_mutex_unlock( &httpd_mutex ); vlc_mutex_unlock( &httpd_mutex );
if( p_tls != NULL )
vlc_tls_ServerDelete( p_tls );
return host; return host;
} }
host = NULL; host = NULL;
/* determine TLS configuration */
if ( psz_cert != NULL )
{
p_tls = vlc_tls_ServerCreate( p_this, psz_cert, psz_key );
if ( p_tls == NULL )
{
msg_Err( p_this, "TLS initialization error" );
goto error;
}
if ( ( psz_ca != NULL) && vlc_tls_ServerAddCA( p_tls, psz_ca ) )
{
msg_Err( p_this, "TLS CA error" );
goto error;
}
if ( ( psz_crl != NULL) && vlc_tls_ServerAddCRL( p_tls, psz_crl ) )
{
msg_Err( p_this, "TLS CRL error" );
goto error;
}
}
else
p_tls = NULL;
/* create the new host */ /* create the new host */
host = (httpd_host_t *)vlc_custom_create( p_this, sizeof (*host), host = (httpd_host_t *)vlc_custom_create( p_this, sizeof (*host),
"http host" ); "http host" );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment