Commit 19e7f0ed authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

tls: add ALPN parameters

parent 7c478d55
...@@ -43,9 +43,12 @@ struct vlc_tls ...@@ -43,9 +43,12 @@ struct vlc_tls
}; };
VLC_API vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *, int fd, VLC_API vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *, int fd,
const char *host, const char *service); const char *host, const char *service,
vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *, int fd, const char *host); const char *const *alpn, char **alp);
int vlc_tls_SessionHandshake (vlc_tls_t *, const char *host, const char *serv); vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *, int fd, const char *host,
const char *const *alpn);
int vlc_tls_SessionHandshake (vlc_tls_t *, const char *host, const char *serv,
char **restrict alp);
VLC_API void vlc_tls_SessionDelete (vlc_tls_t *); VLC_API void vlc_tls_SessionDelete (vlc_tls_t *);
/* NOTE: It is assumed that a->sock.p_sys = a */ /* NOTE: It is assumed that a->sock.p_sys = a */
......
...@@ -286,7 +286,8 @@ static int createCmdTLS( vlc_object_t *p_access, access_sys_t *p_sys, int fd, ...@@ -286,7 +286,8 @@ static int createCmdTLS( vlc_object_t *p_access, access_sys_t *p_sys, int fd,
/* TLS/SSL handshake */ /* TLS/SSL handshake */
p_sys->cmd.p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, fd, p_sys->cmd.p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, fd,
p_sys->url.psz_host, p_sys->url.psz_host,
psz_session_name ); psz_session_name,
NULL, NULL );
if( p_sys->cmd.p_tls == NULL ) if( p_sys->cmd.p_tls == NULL )
{ {
msg_Err( p_access, "cannot establish FTP/TLS session on command channel" ); msg_Err( p_access, "cannot establish FTP/TLS session on command channel" );
...@@ -1028,7 +1029,8 @@ static int ftp_StartStream( vlc_object_t *p_access, access_sys_t *p_sys, ...@@ -1028,7 +1029,8 @@ static int ftp_StartStream( vlc_object_t *p_access, access_sys_t *p_sys,
p_sys->data.p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, p_sys->data.p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds,
p_sys->data.fd, p_sys->url.psz_host, p_sys->data.fd, p_sys->url.psz_host,
( p_sys->tlsmode == EXPLICIT ) ? "ftpes-data" ( p_sys->tlsmode == EXPLICIT ) ? "ftpes-data"
: "ftps-data" ); : "ftps-data",
NULL, NULL );
if( p_sys->data.p_tls == NULL ) if( p_sys->data.p_tls == NULL )
{ {
msg_Err( p_access, "cannot establish FTP/TLS session for data" \ msg_Err( p_access, "cannot establish FTP/TLS session for data" \
......
...@@ -1109,7 +1109,7 @@ static int Connect( access_t *p_access, uint64_t i_tell ) ...@@ -1109,7 +1109,7 @@ static int Connect( access_t *p_access, uint64_t i_tell )
/* TLS/SSL handshake */ /* TLS/SSL handshake */
p_sys->p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, p_sys->fd, p_sys->p_tls = vlc_tls_ClientSessionCreate( p_sys->p_creds, p_sys->fd,
p_sys->url.psz_host, "https" ); p_sys->url.psz_host, "https", NULL, NULL );
if( p_sys->p_tls == NULL ) if( p_sys->p_tls == NULL )
{ {
msg_Err( p_access, "cannot establish HTTP/TLS session" ); msg_Err( p_access, "cannot establish HTTP/TLS session" );
......
...@@ -1670,7 +1670,8 @@ static void httpd_ClientSend(httpd_client_t *cl) ...@@ -1670,7 +1670,8 @@ static void httpd_ClientSend(httpd_client_t *cl)
static void httpd_ClientTlsHandshake(httpd_client_t *cl) static void httpd_ClientTlsHandshake(httpd_client_t *cl)
{ {
switch(vlc_tls_SessionHandshake(cl->p_tls, NULL, NULL)) { switch (vlc_tls_SessionHandshake(cl->p_tls, NULL, NULL, NULL))
{
case -1: cl->i_state = HTTPD_CLIENT_DEAD; break; case -1: cl->i_state = HTTPD_CLIENT_DEAD; break;
case 0: cl->i_state = HTTPD_CLIENT_RECEIVING; break; case 0: cl->i_state = HTTPD_CLIENT_RECEIVING; break;
case 1: cl->i_state = HTTPD_CLIENT_TLS_HS_IN; break; case 1: cl->i_state = HTTPD_CLIENT_TLS_HS_IN; break;
...@@ -2047,7 +2048,7 @@ static void httpdLoop(httpd_host_t *host) ...@@ -2047,7 +2048,7 @@ static void httpdLoop(httpd_host_t *host)
vlc_tls_t *p_tls; vlc_tls_t *p_tls;
if (host->p_tls) if (host->p_tls)
p_tls = vlc_tls_SessionCreate(host->p_tls, fd, NULL); p_tls = vlc_tls_SessionCreate(host->p_tls, fd, NULL, NULL);
else else
p_tls = NULL; p_tls = NULL;
......
...@@ -146,11 +146,11 @@ void vlc_tls_Delete (vlc_tls_creds_t *crd) ...@@ -146,11 +146,11 @@ void vlc_tls_Delete (vlc_tls_creds_t *crd)
/*** TLS session ***/ /*** TLS session ***/
vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd, vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
const char *host) const char *host, const char *const *alpn)
{ {
vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session), vlc_tls_t *session = vlc_custom_create (crd, sizeof (*session),
"tls session"); "tls session");
int val = crd->open (crd, session, fd, host, NULL); int val = crd->open (crd, session, fd, host, alpn);
if (val == VLC_SUCCESS) if (val == VLC_SUCCESS)
return session; return session;
vlc_object_release (session); vlc_object_release (session);
...@@ -158,11 +158,11 @@ vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd, ...@@ -158,11 +158,11 @@ vlc_tls_t *vlc_tls_SessionCreate (vlc_tls_creds_t *crd, int fd,
} }
int vlc_tls_SessionHandshake (vlc_tls_t *session, const char *host, int vlc_tls_SessionHandshake (vlc_tls_t *session, const char *host,
const char *service) const char *service, char **restrict alp)
{ {
vlc_tls_creds_t *crd = (vlc_tls_creds_t *)(session->p_parent); vlc_tls_creds_t *crd = (vlc_tls_creds_t *)(session->p_parent);
return crd->handshake (session, host, service, NULL); return crd->handshake (session, host, service, alp);
} }
void vlc_tls_SessionDelete (vlc_tls_t *session) void vlc_tls_SessionDelete (vlc_tls_t *session)
...@@ -180,13 +180,20 @@ void vlc_tls_SessionDelete (vlc_tls_t *session) ...@@ -180,13 +180,20 @@ void vlc_tls_SessionDelete (vlc_tls_t *session)
* @param fd socket through which to establish the secure channel * @param fd socket through which to establish the secure channel
* @param hostname expected server name, used both as Server Name Indication * @param hostname expected server name, used both as Server Name Indication
* and as expected Common Name of the peer certificate * and as expected Common Name of the peer certificate
* @param service unique identifier for the service to connect to
* (only used locally for certificates database)
* @param alpn NULL-terminated list of Application Layer Protocols
* to negotiate, or NULL to not negotiate protocols
* @param alp storage space for the negotiated Application Layer
* Protocol or NULL if negotiation was not performed[OUT]
* *
* @return NULL on error. * @return NULL on error.
**/ **/
vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd, vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
const char *host, const char *service) const char *host, const char *service,
const char *const *alpn, char **alp)
{ {
vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, host); vlc_tls_t *session = vlc_tls_SessionCreate (crd, fd, host, alpn);
if (session == NULL) if (session == NULL)
return NULL; return NULL;
...@@ -197,8 +204,14 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd, ...@@ -197,8 +204,14 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
ufd[0].fd = fd; ufd[0].fd = fd;
int val; int val;
while ((val = vlc_tls_SessionHandshake (session, host, service)) > 0) while ((val = vlc_tls_SessionHandshake (session, host, service, alp)) != 0)
{ {
if (val < 0)
{
msg_Err (session, "TLS client session handshake error");
goto error;
}
mtime_t now = mdate (); mtime_t now = mdate ();
if (now > deadline) if (now > deadline)
now = deadline; now = deadline;
...@@ -209,16 +222,11 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd, ...@@ -209,16 +222,11 @@ vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd,
if (poll (ufd, 1, (deadline - now) / 1000) == 0) if (poll (ufd, 1, (deadline - now) / 1000) == 0)
{ {
msg_Err (session, "TLS client session handshake timeout"); msg_Err (session, "TLS client session handshake timeout");
val = -1; goto error;
break;
} }
} }
if (val != 0)
{
msg_Err (session, "TLS client session handshake error");
vlc_tls_SessionDelete (session);
session = NULL;
}
return session; return session;
error:
vlc_tls_SessionDelete (session);
return NULL;
} }
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