]> git.sesse.net Git - vlc/blobdiff - modules/misc/gnutls.c
Add mode parameter to utf8_mkdir, and stop creating configuration
[vlc] / modules / misc / gnutls.c
index 706b75a558a9267a2485a6550f09bd30d2d80fec..e2a1913215c368938ed5e19055226d94ad3f7a04 100644 (file)
@@ -262,9 +262,9 @@ static int gnutls_Error (vlc_object_t *obj, int val)
 
 struct tls_session_sys_t
 {
-    gnutls_session  session;
-    char                          *psz_hostname;
-    vlc_bool_t      b_handshaked;
+    gnutls_session_t session;
+    char            *psz_hostname;
+    vlc_bool_t       b_handshaked;
 };
 
 
@@ -397,15 +397,15 @@ gnutls_HandshakeAndValidate( tls_session_t *session )
     }
 
     /* certificate (host)name verification */
-    const gnutls_datum *data = gnutls_certificate_get_peers( p_sys->session,
-                                                             &(unsigned){0} );
+    const gnutls_datum_t *data;
+    data = gnutls_certificate_get_peers (p_sys->session, &(unsigned){0});
     if( data == NULL )
     {
         msg_Err( session, "Peer certificate not available" );
         return -1;
     }
 
-    gnutls_x509_crt cert;
+    gnutls_x509_crt_t cert;
     val = gnutls_x509_crt_init( &cert );
     if( val )
     {
@@ -463,7 +463,7 @@ static void
 gnutls_SetFD (tls_session_t *p_session, int fd)
 {
     gnutls_transport_set_ptr (p_session->p_sys->session,
-                              (gnutls_transport_ptr)(intptr_t)fd);
+                              (gnutls_transport_ptr_t)(intptr_t)fd);
 }
 
 typedef int (*tls_prio_func) (gnutls_session_t, const int *);
@@ -572,12 +572,12 @@ gnutls_SessionPrioritize (vlc_object_t *obj, gnutls_session_t session)
 
 static int
 gnutls_Addx509File( vlc_object_t *p_this,
-                    gnutls_certificate_credentials cred,
+                    gnutls_certificate_credentials_t cred,
                     const char *psz_path, vlc_bool_t b_priv );
 
 static int
 gnutls_Addx509Directory( vlc_object_t *p_this,
-                         gnutls_certificate_credentials cred,
+                         gnutls_certificate_credentials_t cred,
                          const char *psz_dirname,
                          vlc_bool_t b_priv )
 {
@@ -589,8 +589,16 @@ gnutls_Addx509Directory( vlc_object_t *p_this,
     dir = utf8_opendir( psz_dirname );
     if( dir == NULL )
     {
-        msg_Warn( p_this, "cannot open directory (%s): %m", psz_dirname );
-        return VLC_EGENERIC;
+        if (errno != ENOENT)
+        {
+            msg_Err (p_this, "cannot open directory (%s): %m", psz_dirname);
+            return VLC_EGENERIC;
+        }
+
+        msg_Dbg (p_this, "creating empty certificate directory: %s",
+                 psz_dirname);
+        utf8_mkdir (psz_dirname, b_priv ? 0700 : 0755);
+        return VLC_SUCCESS;
     }
 #ifdef S_ISLNK
     else
@@ -683,8 +691,8 @@ gnutls_Addx509File( vlc_object_t *p_this,
 /** TLS client session data */
 typedef struct tls_client_sys_t
 {
-    struct tls_session_sys_t       session;
-    gnutls_certificate_credentials x509_cred;
+    struct tls_session_sys_t         session;
+    gnutls_certificate_credentials_t x509_cred;
 } tls_client_sys_t;
 
 
@@ -718,9 +726,9 @@ static int OpenClient (vlc_object_t *obj)
     const char *homedir = obj->p_libvlc->psz_datadir,
                *datadir = config_GetDataDir ();
     size_t l1 = strlen (homedir), l2 = strlen (datadir);
-    char path[((l1 > l2) ? l1 : l2) + sizeof ("/ssl/private")];
+    char path[((l1 > l2) ? l1 : l2) + sizeof ("/ca-certificates.crt")];
+    //                              > sizeof ("/ssl/private")
     //                              > sizeof ("/ssl/certs")
-    //                              > sizeof ("/ca-certificates.crt")
 
     i_val = gnutls_certificate_allocate_credentials (&p_sys->x509_cred);
     if (i_val != 0)
@@ -730,6 +738,9 @@ static int OpenClient (vlc_object_t *obj)
         goto error;
     }
 
+    sprintf (path, "%s/ssl", homedir);
+    utf8_mkdir (path);
+
     if (var_CreateGetBool (obj, "tls-check-cert"))
     {
         sprintf (path, "%s/ssl/certs", homedir);
@@ -813,15 +824,15 @@ static void CloseClient (vlc_object_t *obj)
  */
 struct tls_server_sys_t
 {
-    gnutls_certificate_credentials  x509_cred;
-    gnutls_dh_params                dh_params;
+    gnutls_certificate_credentials_t x509_cred;
+    gnutls_dh_params_t               dh_params;
 
     struct saved_session_t          *p_cache;
     struct saved_session_t          *p_store;
-    int                             i_cache_size;
-    vlc_mutex_t                     cache_lock;
+    int                              i_cache_size;
+    vlc_mutex_t                      cache_lock;
 
-    int                             (*pf_handshake)( tls_session_t * );
+    int                            (*pf_handshake) (tls_session_t *);
 };
 
 
@@ -869,7 +880,7 @@ static int cb_store( void *p_server, gnutls_datum key, gnutls_datum data )
 
 static gnutls_datum cb_fetch( void *p_server, gnutls_datum key )
 {
-    static const gnutls_datum err_datum = { NULL, 0 };
+    static const gnutls_datum_t err_datum = { NULL, 0 };
     tls_server_sys_t *p_sys = ((tls_server_t *)p_server)->p_sys;
     saved_session_t *p_session, *p_end;
 
@@ -883,7 +894,7 @@ static gnutls_datum cb_fetch( void *p_server, gnutls_datum key )
         if( ( p_session->i_idlen == key.size )
          && !memcmp( p_session->id, key.data, key.size ) )
         {
-            gnutls_datum data;
+            gnutls_datum_t data;
 
             data.size = p_session->i_datalen;
 
@@ -964,7 +975,7 @@ gnutls_ServerSessionPrepare( tls_server_t *p_server )
 {
     tls_session_t *p_session;
     tls_server_sys_t *p_server_sys;
-    gnutls_session session;
+    gnutls_session_t session;
     int i_val;
 
     p_session = vlc_object_create( p_server, sizeof (struct tls_session_t) );
@@ -1021,7 +1032,7 @@ gnutls_ServerSessionPrepare( tls_server_t *p_server )
     gnutls_dh_set_prime_bits (session, i_val);
 
     /* Session resumption support */
-    i_val = config_GetInt (p_server, "gnutls-cache-expiration");
+    i_val = config_GetInt (p_server, "gnutls-cache-timeout");
     gnutls_db_set_cache_expiration (session, i_val);
     gnutls_db_set_retrieve_function( session, cb_fetch );
     gnutls_db_set_remove_function( session, cb_delete );
@@ -1158,9 +1169,9 @@ static int OpenServer (vlc_object_t *obj)
     val = gnutls_certificate_set_x509_key_file (p_sys->x509_cred,
                                                 psz_local_cert, psz_local_key,
                                                 GNUTLS_X509_FMT_PEM );
-    LocaleFree (psz_key_path);
+    LocaleFree (psz_local_key);
     free (psz_key_path);
-    LocaleFree (psz_cert_path);
+    LocaleFree (psz_local_cert);
     free (psz_cert_path);
 
     if( val < 0 )
@@ -1178,13 +1189,38 @@ static int OpenServer (vlc_object_t *obj)
     val = gnutls_dh_params_init( &p_sys->dh_params );
     if( val >= 0 )
     {
-        msg_Dbg( p_server, "computing Diffie Hellman ciphers parameters" );
+        msg_Dbg( p_server, "computing DHE ciphers parameters" );
         val = gnutls_dh_params_generate2 (p_sys->dh_params,
                                           config_GetInt (obj, "gnutls-dh-bits"));
+
+        /* Write the DH parameter to cache */
+        const char *cachedir = p_server->p_libvlc->psz_cachedir;
+        char cachefile[strlen (cachedir) + sizeof ("/dh_params.pem")];
+        sprintf (cachefile, "%s/dh_params.pem", cachedir);
+
+        FILE *cache = utf8_fopen (cachefile, "wb");
+        if (cache != NULL)
+        {
+            size_t len = 0;
+            gnutls_dh_params_export_pkcs3 (p_sys->dh_params,
+                                           GNUTLS_X509_FMT_PEM, NULL, &len);
+            msg_Dbg (p_server, "caching DHE parameters (%u bytes) to %s",
+                     (unsigned)len, cachefile);
+
+            unsigned char buf[len];
+            gnutls_dh_params_export_pkcs3 (p_sys->dh_params,
+                                           GNUTLS_X509_FMT_PEM, buf, &len);
+            if (fwrite (buf, 1, len, cache) != len)
+                msg_Warn (p_server, "cannot write to %s: %m", cachefile);
+            fclose (cache);
+        }
+        else
+            msg_Warn (p_server, "cannot open to %s: %m", cachefile);
+
     }
     if( val < 0 )
     {
-        msg_Err( p_server, "cannot initialize DH cipher suites: %s",
+        msg_Err( p_server, "cannot initialize DHE cipher suites: %s",
                  gnutls_strerror( val ) );
         gnutls_certificate_free_credentials( p_sys->x509_cred );
         goto error;