⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 update.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * update.c: VLC update checking and downloading ***************************************************************************** * Copyright © 2005-2008 the VideoLAN team * $Id: 96a3948992f7fdfe5aed37b0fe3d8565272d2237 $ * * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org> *          Rémi Duraffort <ivoire at via.ecp.fr>            Rafaël Carré <funman@videolanorg> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either release 2 of the License, or * (at your option) any later release. * * 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//** *   \file *   This file contains functions related to VLC update management *//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_update.h>#ifdef UPDATE_CHECK#include <assert.h>#include <vlc_pgpkey.h>#include <vlc_stream.h>#include <vlc_strings.h>#include <vlc_charset.h>#include <vlc_interface.h>#include <gcrypt.h>#include <vlc_gcrypt.h>#include "update.h"#include "../libvlc.h"/***************************************************************************** * Misc defines *****************************************************************************//* * Here is the format of these "status files" : * First line is the last version: "X.Y.Ze" where: *      * X is the major number *      * Y is the minor number *      * Z is the revision number *      * e is an OPTIONAL extra letter *      * AKA "0.8.6d" or "0.9.0" * Second line is an url of the binary for this last version * Remaining text is a required description of the update */#if defined( UNDER_CE )#   define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-ce"#elif defined( WIN32 )#   define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-win-x86"#elif defined( __APPLE__ )#   if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )#       define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-mac-ppc"#   else#       define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-mac-x86"#   endif#elif defined( SYS_BEOS )#       define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-beos-x86"#else#   define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status"#endif/***************************************************************************** * Local Prototypes *****************************************************************************/static void EmptyRelease( update_t *p_update );static bool GetUpdateFile( update_t *p_update );static char * size_str( long int l_size );/***************************************************************************** * OpenPGP functions *****************************************************************************/#define packet_type( c ) ( ( c & 0x3c ) >> 2 )      /* 0x3C = 00111100 */#define packet_header_len( c ) ( ( c & 0x03 ) + 1 ) /* number of bytes in a packet header */static inline int scalar_number( uint8_t *p, int header_len ){    assert( header_len == 1 || header_len == 2 || header_len == 4 );    if( header_len == 1 )        return( p[0] );    else if( header_len == 2 )        return( (p[0] << 8) + p[1] );    else if( header_len == 4 )        return( (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3] );    abort(); /* to shut up GCC warning */}/* number of data bytes in a MPI */#define mpi_len( mpi ) ( ( scalar_number( mpi, 2 ) + 7 ) / 8 )/* * fill a public_key_packet_t structure from public key packet data * verify that it is a version 4 public key packet, using DSA */static int parse_public_key_packet( public_key_packet_t *p_key, uint8_t *p_buf,                                    size_t i_packet_len ){    if( i_packet_len > 418 || i_packet_len < 6 )        return VLC_EGENERIC;    size_t i_read = 0;    p_key->version   = *p_buf++; i_read++;    if( p_key->version != 4 )        return VLC_EGENERIC;    /* XXX: warn when timestamp is > date ? */    memcpy( p_key->timestamp, p_buf, 4 ); p_buf += 4; i_read += 4;    p_key->algo      = *p_buf++; i_read++;    if( p_key->algo != PUBLIC_KEY_ALGO_DSA )        return VLC_EGENERIC;    /* read p */    if( i_read + 2 > i_packet_len )        return VLC_EGENERIC;    int i_p_len = mpi_len( p_buf );    if( i_p_len > 128 || i_read + 2 + i_p_len > i_packet_len )        return VLC_EGENERIC;    memcpy( p_key->p, p_buf, 2+i_p_len );    p_buf += 2+i_p_len; i_read += 2+i_p_len;    /* read q */    if( i_read + 2 > i_packet_len )        return VLC_EGENERIC;    int i_q_len = mpi_len( p_buf );    if( i_q_len > 20 || i_read+2+i_q_len > i_packet_len )        return VLC_EGENERIC;    memcpy( p_key->q, p_buf, 2+i_q_len );    p_buf += 2+i_q_len; i_read += 2+i_q_len;    /* read g */    if( i_read + 2 > i_packet_len )        return VLC_EGENERIC;    int i_g_len = mpi_len( p_buf );    if( i_g_len > 128 || i_read+2+i_g_len > i_packet_len )        return VLC_EGENERIC;    memcpy( p_key->g, p_buf, 2+i_g_len );    p_buf += 2+i_g_len; i_read += 2+i_g_len;    /* read y */    if( i_read + 2 > i_packet_len )        return VLC_EGENERIC;    int i_y_len = mpi_len( p_buf );    if( i_y_len > 128 || i_read+2+i_y_len > i_packet_len )        return VLC_EGENERIC;    memcpy( p_key->y, p_buf, 2+i_y_len );    i_read += 2+i_y_len;    if( i_read != i_packet_len ) /* some extra data eh ? */        return VLC_EGENERIC;    return VLC_SUCCESS;}static size_t parse_signature_v3_packet( signature_packet_t *p_sig,                                      uint8_t *p_buf, size_t i_sig_len ){    size_t i_read = 1; /* we already read the version byte */    if( i_sig_len < 19 ) /* signature is at least 19 bytes + the 2 MPIs */        return 0;    p_sig->specific.v3.hashed_data_len = *p_buf++; i_read++;    if( p_sig->specific.v3.hashed_data_len != 5 )        return 0;    p_sig->type = *p_buf++; i_read++;    memcpy( p_sig->specific.v3.timestamp, p_buf, 4 );    p_buf += 4; i_read += 4;    memcpy( p_sig->issuer_longid, p_buf, 8 );    p_buf += 8; i_read += 8;    p_sig->public_key_algo = *p_buf++; i_read++;    p_sig->digest_algo = *p_buf++; i_read++;    p_sig->hash_verification[0] = *p_buf++; i_read++;    p_sig->hash_verification[1] = *p_buf++; i_read++;    assert( i_read == 19 );    return i_read;}/* * fill a signature_packet_v4_t from signature packet data * verify that it was used with a DSA public key, using SHA-1 digest */static size_t parse_signature_v4_packet( signature_packet_t *p_sig,                                      uint8_t *p_buf, size_t i_sig_len ){    size_t i_read = 1; /* we already read the version byte */    if( i_sig_len < 10 ) /* signature is at least 10 bytes + the 2 MPIs */        return 0;    p_sig->type = *p_buf++; i_read++;    p_sig->public_key_algo = *p_buf++; i_read++;    p_sig->digest_algo = *p_buf++; i_read++;    memcpy( p_sig->specific.v4.hashed_data_len, p_buf, 2 );    p_buf += 2; i_read += 2;    size_t i_hashed_data_len =        scalar_number( p_sig->specific.v4.hashed_data_len, 2 );    i_read += i_hashed_data_len;    if( i_read + 4 > i_sig_len )        return 0;    p_sig->specific.v4.hashed_data = (uint8_t*) malloc( i_hashed_data_len );    if( !p_sig->specific.v4.hashed_data )        return 0;    memcpy( p_sig->specific.v4.hashed_data, p_buf, i_hashed_data_len );    p_buf += i_hashed_data_len;    memcpy( p_sig->specific.v4.unhashed_data_len, p_buf, 2 );    p_buf += 2; i_read += 2;    size_t i_unhashed_data_len =        scalar_number( p_sig->specific.v4.unhashed_data_len, 2 );    i_read += i_unhashed_data_len;    if( i_read + 2 > i_sig_len )        return 0;    p_sig->specific.v4.unhashed_data = (uint8_t*) malloc( i_unhashed_data_len );    if( !p_sig->specific.v4.unhashed_data )        return 0;    memcpy( p_sig->specific.v4.unhashed_data, p_buf, i_unhashed_data_len );    p_buf += i_unhashed_data_len;    memcpy( p_sig->hash_verification, p_buf, 2 );    p_buf += 2; i_read += 2;    uint8_t *p, *max_pos;    p = p_sig->specific.v4.unhashed_data;    max_pos = p + scalar_number( p_sig->specific.v4.unhashed_data_len, 2 );    for( ;; )    {        if( p > max_pos )            return 0;        size_t i_subpacket_len;        if( *p < 192 )        {            if( p + 1 > max_pos )                return 0;            i_subpacket_len = *p++;        }        else if( *p < 255 )        {            if( p + 2 > max_pos )                return 0;            i_subpacket_len = (*p++ - 192) << 8;            i_subpacket_len += *p++ + 192;        }        else        {            if( p + 4 > max_pos )                return 0;            i_subpacket_len = *++p << 24;            i_subpacket_len += *++p << 16;            i_subpacket_len += *++p << 8;            i_subpacket_len += *++p;        }        if( *p == ISSUER_SUBPACKET )        {            if( p + 9 > max_pos )                return 0;            memcpy( &p_sig->issuer_longid, p+1, 8 );            return i_read;        }        p += i_subpacket_len;    }}static int parse_signature_packet( signature_packet_t *p_sig,                                   uint8_t *p_buf, size_t i_sig_len ){    if( !i_sig_len ) /* 1st sanity check, we need at least the version */        return VLC_EGENERIC;    p_sig->version = *p_buf++;    size_t i_read;    switch( p_sig->version )    {        case 3:            i_read = parse_signature_v3_packet( p_sig, p_buf, i_sig_len );            break;        case 4:            p_sig->specific.v4.hashed_data = NULL;            p_sig->specific.v4.unhashed_data = NULL;            i_read = parse_signature_v4_packet( p_sig, p_buf, i_sig_len );            break;        default:            return VLC_EGENERIC;    }    if( i_read == 0 ) /* signature packet parsing has failed */        goto error;    if( p_sig->public_key_algo != PUBLIC_KEY_ALGO_DSA )        goto error;    if( p_sig->digest_algo != DIGEST_ALGO_SHA1 )        goto error;    switch( p_sig->type )    {        case BINARY_SIGNATURE:        case TEXT_SIGNATURE:        case GENERIC_KEY_SIGNATURE:        case PERSONA_KEY_SIGNATURE:        case CASUAL_KEY_SIGNATURE:        case POSITIVE_KEY_SIGNATURE:            break;        default:            goto error;    }    p_buf--; /* rewind to the version byte */    p_buf += i_read;    if( i_read + 2 > i_sig_len )        goto error;    size_t i_r_len = mpi_len( p_buf ); i_read += 2;    if( i_read + i_r_len > i_sig_len || i_r_len > 20 )        goto error;    memcpy( p_sig->r, p_buf, 2 + i_r_len );    p_buf += 2 + i_r_len;    i_read += i_r_len;    if( i_read + 2 > i_sig_len )        goto error;    size_t i_s_len = mpi_len( p_buf ); i_read += 2;    if( i_read + i_s_len > i_sig_len || i_s_len > 20 )        goto error;    memcpy( p_sig->s, p_buf, 2 + i_s_len );    p_buf += 2 + i_s_len;    i_read += i_s_len;    assert( i_read == i_sig_len );    if( i_read < i_sig_len ) /* some extra data, hm ? */        goto error;    return VLC_SUCCESS;error:    if( p_sig->version == 4 )    {        free( p_sig->specific.v4.hashed_data );        free( p_sig->specific.v4.unhashed_data );    }    return VLC_EGENERIC;}/* * crc_octets() was lamely copied from rfc 2440 * Copyright (C) The Internet Society (1998).  All Rights Reserved. */#define CRC24_INIT 0xB704CEL#define CRC24_POLY 0x1864CFBLstatic long crc_octets( uint8_t *octets, size_t len ){    long crc = CRC24_INIT;    int i;    while (len--)    {        crc ^= (*octets++) << 16;        for (i = 0; i < 8; i++)        {            crc <<= 1;            if (crc & 0x1000000)                crc ^= CRC24_POLY;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -