Example #1
0
/**
 * Create a new update VLC struct
 *
 * \param p_this the calling vlc_object
 * \return pointer to new update_t or NULL
 */
update_t *update_New( vlc_object_t *p_this )
{
    update_t *p_update;
    assert( p_this );

    p_update = (update_t *)malloc( sizeof( update_t ) );
    if( !p_update ) return NULL;

    vlc_mutex_init( &p_update->lock );

    p_update->p_libvlc = p_this->p_libvlc;

    p_update->release.psz_url = NULL;
    p_update->release.psz_desc = NULL;

    p_update->p_download = NULL;
    p_update->p_check = NULL;

    p_update->p_pkey = NULL;
    vlc_gcrypt_init();

    return p_update;
}
Example #2
0
File: rtp.c Project: Geal/vlc
/**
 * Probes and initializes.
 */
static int Open (vlc_object_t *obj)
{
    demux_t *demux = (demux_t *)obj;
    int tp; /* transport protocol */

    if (!strcmp (demux->psz_access, "dccp"))
        tp = IPPROTO_DCCP;
    else
    if (!strcmp (demux->psz_access, "rtptcp"))
        tp = IPPROTO_TCP;
    else
    if (!strcmp (demux->psz_access, "rtp"))
        tp = IPPROTO_UDP;
    else
    if (!strcmp (demux->psz_access, "udplite"))
        tp = IPPROTO_UDPLITE;
    else
        return VLC_EGENERIC;

    char *tmp = strdup (demux->psz_location);
    if (tmp == NULL)
        return VLC_ENOMEM;

    char *shost;
    char *dhost = strchr (tmp, '@');
    if (dhost != NULL)
    {
        *(dhost++) = '\0';
        shost = tmp;
    }
    else
    {
        dhost = tmp;
        shost = NULL;
    }

    /* Parses the port numbers */
    int sport = 0, dport = 0;
    if (shost != NULL)
        sport = extract_port (&shost);
    if (dhost != NULL)
        dport = extract_port (&dhost);
    if (dport == 0)
        dport = 5004; /* avt-profile-1 port */

    int rtcp_dport = var_CreateGetInteger (obj, "rtcp-port");

    /* Try to connect */
    int fd = -1, rtcp_fd = -1;

    switch (tp)
    {
        case IPPROTO_UDP:
        case IPPROTO_UDPLITE:
            fd = net_OpenDgram (obj, dhost, dport, shost, sport, tp);
            if (fd == -1)
                break;
            if (rtcp_dport > 0) /* XXX: source port is unknown */
                rtcp_fd = net_OpenDgram (obj, dhost, rtcp_dport, shost, 0, tp);
            break;

         case IPPROTO_DCCP:
#ifndef SOCK_DCCP /* provisional API (FIXME) */
# ifdef __linux__
#  define SOCK_DCCP 6
# endif
#endif
#ifdef SOCK_DCCP
            var_Create (obj, "dccp-service", VLC_VAR_STRING);
            var_SetString (obj, "dccp-service", "RTPV"); /* FIXME: RTPA? */
            fd = net_Connect (obj, dhost, dport, SOCK_DCCP, tp);
#else
            msg_Err (obj, "DCCP support not included");
#endif
            break;

        case IPPROTO_TCP:
            fd = net_Connect (obj, dhost, dport, SOCK_STREAM, tp);
            break;
    }

    free (tmp);
    if (fd == -1)
        return VLC_EGENERIC;
    net_SetCSCov (fd, -1, 12);

    /* Initializes demux */
    demux_sys_t *p_sys = malloc (sizeof (*p_sys));
    if (p_sys == NULL)
    {
        net_Close (fd);
        if (rtcp_fd != -1)
            net_Close (rtcp_fd);
        return VLC_EGENERIC;
    }

    p_sys->chained_demux = NULL;
#ifdef HAVE_SRTP
    p_sys->srtp         = NULL;
#endif
    p_sys->fd           = fd;
    p_sys->rtcp_fd      = rtcp_fd;
    p_sys->max_src      = var_CreateGetInteger (obj, "rtp-max-src");
    p_sys->timeout      = var_CreateGetInteger (obj, "rtp-timeout")
                        * CLOCK_FREQ;
    p_sys->max_dropout  = var_CreateGetInteger (obj, "rtp-max-dropout");
    p_sys->max_misorder = var_CreateGetInteger (obj, "rtp-max-misorder");
    p_sys->thread_ready = false;
    p_sys->autodetect   = true;

    demux->pf_demux   = NULL;
    demux->pf_control = Control;
    demux->p_sys      = p_sys;

    p_sys->session = rtp_session_create (demux);
    if (p_sys->session == NULL)
        goto error;

#ifdef HAVE_SRTP
    char *key = var_CreateGetNonEmptyString (demux, "srtp-key");
    if (key)
    {
        vlc_gcrypt_init ();
        p_sys->srtp = srtp_create (SRTP_ENCR_AES_CM, SRTP_AUTH_HMAC_SHA1, 10,
                                   SRTP_PRF_AES_CM, SRTP_RCC_MODE1);
        if (p_sys->srtp == NULL)
        {
            free (key);
            goto error;
        }

        char *salt = var_CreateGetNonEmptyString (demux, "srtp-salt");
        int val = srtp_setkeystring (p_sys->srtp, key, salt ? salt : "");
        free (salt);
        free (key);
        if (val)
        {
            msg_Err (obj, "bad SRTP key/salt combination (%s)",
                     vlc_strerror_c(val));
            goto error;
        }
    }
#endif

    if (vlc_clone (&p_sys->thread,
                   (tp != IPPROTO_TCP) ? rtp_dgram_thread : rtp_stream_thread,
                   demux, VLC_THREAD_PRIORITY_INPUT))
        goto error;
    p_sys->thread_ready = true;
    return VLC_SUCCESS;

error:
    Close (obj);
    return VLC_EGENERIC;
}
Example #3
0
File: livehttp.c Project: Geal/vlc
/************************************************************************
 * CryptSetup: Initialize encryption
 ************************************************************************/
static int CryptSetup( sout_access_out_t *p_access, char *key_file )
{
    sout_access_out_sys_t *p_sys = p_access->p_sys;
    uint8_t key[16];
    char *keyfile = NULL;

    if( !p_sys->key_uri ) /*No key uri, assume no encryption wanted*/
    {
        msg_Dbg( p_access, "No key uri, no encryption");
        return VLC_SUCCESS;
    }

    if( key_file )
        keyfile = strdup( key_file );
    else
        keyfile = var_InheritString( p_access, SOUT_CFG_PREFIX "key-file" );

    if( unlikely(keyfile == NULL) )
    {
        msg_Err( p_access, "No key-file, no encryption" );
        return VLC_EGENERIC;
    }

    vlc_gcrypt_init();

    /*Setup encryption cipher*/
    gcry_error_t err = gcry_cipher_open( &p_sys->aes_ctx, GCRY_CIPHER_AES,
                                         GCRY_CIPHER_MODE_CBC, 0 );
    if( err )
    {
        msg_Err( p_access, "Openin AES Cipher failed: %s", gpg_strerror(err));
        free( keyfile );
        return VLC_EGENERIC;
    }

    int keyfd = vlc_open( keyfile, O_RDONLY | O_NONBLOCK );
    if( unlikely( keyfd == -1 ) )
    {
        msg_Err( p_access, "Unable to open keyfile %s: %s", keyfile,
                 vlc_strerror_c(errno) );
        free( keyfile );
        gcry_cipher_close( p_sys->aes_ctx );
        return VLC_EGENERIC;
    }
    free( keyfile );

    ssize_t keylen = read( keyfd, key, 16 );

    vlc_close( keyfd );
    if( keylen < 16 )
    {
        msg_Err( p_access, "No key at least 16 octects (you provided %zd), no encryption", keylen );
        gcry_cipher_close( p_sys->aes_ctx );
        return VLC_EGENERIC;
    }

    err = gcry_cipher_setkey( p_sys->aes_ctx, key, 16 );
    if(err)
    {
        msg_Err(p_access, "Setting AES key failed: %s", gpg_strerror(err));
        gcry_cipher_close( p_sys->aes_ctx );
        return VLC_EGENERIC;
    }

    if( p_sys->b_generate_iv )
        vlc_rand_bytes( p_sys->aes_ivs, sizeof(uint8_t)*16);

    return VLC_SUCCESS;
}
Example #4
0
/*****************************************************************************
 * CreateFilter: Create the filter and open the definition file
 *****************************************************************************/
static int CreateFilter ( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;

    filter_sys_t *p_sys = malloc( sizeof (*p_sys) );
    if( unlikely(p_sys == NULL) )
        return VLC_ENOMEM;

    /* Populating struct */
    vlc_mutex_init( &p_sys->lock );
    p_sys->b_need_update = false;
    p_sys->psz_host = var_InheritString( p_this, RMTOSD_CFG "host" );
    p_sys->psz_passwd = var_InheritString( p_this, RMTOSD_CFG "password" );
    p_sys->i_alpha = var_InheritInteger( p_this, RMTOSD_CFG "alpha" );
    p_sys->p_pic = NULL;
    p_sys->i_socket = -1;

    memset( p_sys->ar_color_table_yuv, 255,
            sizeof( p_sys->ar_color_table_yuv ) );

    if( p_sys->psz_host == NULL )
    {
        msg_Err( p_filter, "unable to get vnc host" );
        goto error;
    }

    if( p_sys->psz_passwd == NULL )
    {
        msg_Err( p_filter, "unable to get vnc password" );
        goto error;
    }

    p_filter->p_sys = p_sys;

    vlc_gcrypt_init();

    /* create the vnc worker thread */
    if( vlc_clone( &p_sys->worker_thread,
                   vnc_worker_thread, p_filter, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot spawn vnc message reader thread" );
        goto error;
    }

    /* Attach subpicture source callback */
    p_filter->pf_sub_source = Filter;

    es_format_Init( &p_filter->fmt_out, SPU_ES, VLC_CODEC_SPU );
    p_filter->fmt_out.i_priority = ES_PRIORITY_SELECTABLE_MIN;

    if( var_InheritBool( p_this, RMTOSD_CFG "mouse-events" ) )
        p_filter->pf_sub_mouse = MouseEvent;

    p_sys->b_vnc_key_events = var_InheritBool( p_this,
                                               RMTOSD_CFG "key-events" );
    if( p_sys->b_vnc_key_events )
        var_AddCallback( p_filter->p_libvlc, "key-pressed", KeyEvent, p_this );

    msg_Dbg( p_filter, "osdvnc filter started" );

    return VLC_SUCCESS;

error:
    msg_Err( p_filter, "osdvnc filter discarded" );

    vlc_mutex_destroy( &p_sys->lock );
    free( p_sys->psz_host );
    free( p_sys->psz_passwd );
    free( p_sys );

    return VLC_EGENERIC;
}
Example #5
0
/* decrypts the RSA encrypted text read from the XML file,
 * and saves the AES key and the other needed info
 * uses libgcrypt for decryption
 */
int AESKey::decryptRSA( string s_cipher_text_b64 )
{
    RSAKey rsa_key( this->p_demux );
    unsigned char *ps_cipher_text = NULL;
    unsigned char *ps_plain_text = NULL;
    gcry_mpi_t cipher_text_mpi = NULL;
    gcry_sexp_t cipher_text_sexp = NULL;
    gcry_sexp_t plain_text_sexp = NULL;
    gcry_mpi_t plain_text_mpi = NULL;
    gcry_sexp_t tmp_sexp = NULL;
    gcry_error_t err;
    size_t length;
    int i_ret = VLC_EGENERIC;

    /* get RSA private key file path */
    if( rsa_key.setPath() )
        goto end;

    /* read private key from file */
    if( rsa_key.readPEM() )
        goto end;

    /* remove spaces and newlines from encoded cipher text
     * (usually added for indentation in XML files)
     * */
    try
    {
        s_cipher_text_b64.erase( remove_if( s_cipher_text_b64.begin(), s_cipher_text_b64.end(), static_cast<int(*)(int)>(isspace) ),
                                 s_cipher_text_b64.end() );
    }
    catch( ... )
    {
        msg_Err( this->p_demux, "error while handling string" );
        goto end;
    }

    /* decode cipher from BASE64 to binary */
    if( ! ( length = vlc_b64_decode_binary( &ps_cipher_text, s_cipher_text_b64.c_str() ) ) )
    {
        msg_Err( this->p_demux, "could not decode cipher from Base64" );
        goto end;
    }

    /* initialize libgcrypt */
    vlc_gcrypt_init ();

    /* create S-expression for ciphertext */
    if( ( err = gcry_mpi_scan( &cipher_text_mpi, GCRYMPI_FMT_USG, ps_cipher_text, 256, NULL ) ) )
    {
        msg_Err( this->p_demux, "could not scan MPI from cipher text: %s", gcry_strerror( err ) );
        goto end;
    }
    if( ( err = gcry_sexp_build( &cipher_text_sexp, NULL, "(enc-val(flags oaep)(rsa(a %m)))", cipher_text_mpi ) ) )
    {
        msg_Err( this->p_demux, "could not build S-expression for cipher text: %s", gcry_strerror( err ) );
        goto end;
    }

    /* decrypt */
    if( ( err = gcry_pk_decrypt( &plain_text_sexp, cipher_text_sexp, rsa_key.priv_key ) ) )
    {
        msg_Err( this->p_demux, "error while decrypting RSA encrypted info: %s", gcry_strerror( err ) );
        goto end;
    }

    /* extract plain-text from S-expression */
    if( ! ( tmp_sexp = gcry_sexp_find_token( plain_text_sexp, "value", 0 ) ) )
        /* when using padding flags, the decrypted S-expression is of the form
         * "(value <plaintext>)", where <plaintext> is an MPI */
    {
        msg_Err( this->p_demux, "decrypted text is in an unexpected form; decryption may have failed" );
        goto end;
    }
    /* we could have used the gcry_sexp_nth_data to get the data directly,
     * but as that function is newly introduced (libgcrypt v1.6),
     * we prefer compatibility, even though that means passing the data through an MPI first */
    if( ! ( plain_text_mpi = gcry_sexp_nth_mpi( tmp_sexp, 1, GCRYMPI_FMT_USG ) ) )
    {
        msg_Err( this->p_demux, "could not extract MPI from decrypted S-expression" );
        goto end;
    }

    if( ( err = gcry_mpi_aprint( GCRYMPI_FMT_USG, &ps_plain_text, &length, plain_text_mpi ) ) )
    {
        msg_Err( this->p_demux, "error while extracting plain text from MPI: %s", gcry_strerror( err ) );
        goto end;
    }

    /* interpret the plaintext data */
    switch( length )
    {
        case 138:   /* SMPTE    DCP */
            if( this->extractInfo( ps_plain_text, true ) )
                goto end;
            break;
        case 134:   /* Interop  DCP */
            if( this->extractInfo( ps_plain_text, false ) )
                goto end;
            break;
        case -1:
            msg_Err( this->p_demux, "could not decrypt" );
            goto end;
        default:
            msg_Err( this->p_demux, "CipherValue field length does not match SMPTE nor Interop standards" );
            goto end;
    }

    i_ret = VLC_SUCCESS;

end:
    free( ps_cipher_text );
    gcry_mpi_release( cipher_text_mpi );
    gcry_sexp_release( cipher_text_sexp );
    gcry_sexp_release( plain_text_sexp );
    gcry_mpi_release( plain_text_mpi );
    gcry_sexp_release( tmp_sexp );
    gcry_free( ps_plain_text );
    return i_ret;
}
/*****************************************************************************
 * CreateFilter: Create the filter and open the definition file
 *****************************************************************************/
static int CreateFilter ( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = NULL;

    msg_Dbg( p_filter, "Creating vnc osd filter..." );

    p_filter->p_sys = p_sys = calloc( 1, sizeof(*p_sys) );
    if( !p_filter->p_sys )
        return VLC_ENOMEM;

    /* Populating struct */
    vlc_mutex_init( &p_sys->lock );
    p_sys->b_continue = true;
    p_sys->i_socket = -1;
    p_sys->p_pic = NULL;

    p_sys->psz_host = var_CreateGetString( p_this, RMTOSD_CFG "host" );
    if( EMPTY_STR(p_sys->psz_host) )
    {
        msg_Err( p_filter, "unable to get vnc host" );
        goto error;
    }

    p_sys->psz_passwd = var_CreateGetString( p_this, RMTOSD_CFG "password" );
    if( !p_sys->psz_passwd )
    {
        msg_Err( p_filter, "unable to get vnc password" );
        goto error;
    }

    p_sys->i_port = var_CreateGetIntegerCommand( p_this, RMTOSD_CFG "port" );

    p_sys->i_alpha = var_CreateGetIntegerCommand( p_this, RMTOSD_CFG "alpha" );

    /* in milliseconds, 0 disables polling, should not be lower than 100 */
    p_sys->i_vnc_poll_interval  = var_CreateGetIntegerCommand( p_this,
                                                       RMTOSD_CFG "update" );
    if ( p_sys->i_vnc_poll_interval < 100)
    {
       p_sys->i_vnc_poll_interval = 100;
    }

    for ( int i = 0; i < 256; i++ )
    {
        p_sys->ar_color_table_yuv[i][0] = 255;
        p_sys->ar_color_table_yuv[i][1] = 255;
        p_sys->ar_color_table_yuv[i][2] = 255;
        p_sys->ar_color_table_yuv[i][3] = 255;
    }

    p_sys->b_vnc_poll = var_CreateGetBoolCommand( p_this,
                                            RMTOSD_CFG "vnc-polling" );
    p_sys->b_vnc_mouse_events = var_CreateGetBoolCommand( p_this,
                                            RMTOSD_CFG "mouse-events" );
    p_sys->b_vnc_key_events = var_CreateGetBoolCommand( p_this,
                                            RMTOSD_CFG "key-events" );

    /* Keep track of OSD Events */
    p_sys->b_need_update  = false;

    /* Attach subpicture source callback */
    p_filter->pf_sub_source = Filter;
    p_filter->pf_sub_mouse  = MouseEvent;

    var_AddCallback( p_filter->p_libvlc, "key-pressed", KeyEvent, p_this );

    es_format_Init( &p_filter->fmt_out, SPU_ES, VLC_CODEC_SPU );
    p_filter->fmt_out.i_priority = 0;

    vlc_gcrypt_init();

    /* create the vnc worker thread */
    if( vlc_clone( &p_sys->worker_thread,
                   vnc_worker_thread, p_filter, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot spawn vnc message reader thread" );
        goto error;
    }

    msg_Dbg( p_filter, "osdvnc filter started" );

    return VLC_SUCCESS;

error:
    msg_Err( p_filter, "osdvnc filter discarded" );

    stop_osdvnc( p_filter );

    vlc_mutex_destroy( &p_sys->lock );
    free( p_sys->psz_host );
    free( p_sys->psz_passwd );
    free( p_sys );

    return VLC_EGENERIC;
}