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

📄 http.c

📁 vlc源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            /* Clean */            free( current_cookie_name );            free( current_cookie_domain );            break;        }        free( current_cookie_name );        free( current_cookie_domain );    }    free( cookie_name );    free( cookie_domain );    vlc_array_append( cookies, cookie );}/***************************************************************************** * "RFC 2617: Basic and Digest Access Authentication" header parsing *****************************************************************************/static char *AuthGetParam( const char *psz_header, const char *psz_param ){    char psz_what[strlen(psz_param)+3];    sprintf( psz_what, "%s=\"", psz_param );    psz_header = strstr( psz_header, psz_what );    if( psz_header )    {        const char *psz_end;        psz_header += strlen( psz_what );        psz_end = strchr( psz_header, '"' );        if( !psz_end ) /* Invalid since we should have a closing quote */            return strdup( psz_header );        return strndup( psz_header, psz_end - psz_header );    }    else    {        return NULL;    }}static char *AuthGetParamNoQuotes( const char *psz_header, const char *psz_param ){    char psz_what[strlen(psz_param)+2];    sprintf( psz_what, "%s=", psz_param );    psz_header = strstr( psz_header, psz_what );    if( psz_header )    {        const char *psz_end;        psz_header += strlen( psz_what );        psz_end = strchr( psz_header, ',' );        /* XXX: Do we need to filter out trailing space between the value and         * the comma/end of line? */        if( !psz_end ) /* Can be valid if this is the last parameter */            return strdup( psz_header );        return strndup( psz_header, psz_end - psz_header );    }    else    {        return NULL;    }}static void AuthParseHeader( access_t *p_access, const char *psz_header,                             http_auth_t *p_auth ){    /* FIXME: multiple auth methods can be listed (comma seperated) */    /* 2 Basic Authentication Scheme */    if( !strncasecmp( psz_header, "Basic ", strlen( "Basic " ) ) )    {        msg_Dbg( p_access, "Using Basic Authentication" );        psz_header += strlen( "Basic " );        p_auth->psz_realm = AuthGetParam( psz_header, "realm" );        if( !p_auth->psz_realm )            msg_Warn( p_access, "Basic Authentication: "                      "Mandatory 'realm' parameter is missing" );    }    /* 3 Digest Access Authentication Scheme */    else if( !strncasecmp( psz_header, "Digest ", strlen( "Digest " ) ) )    {        msg_Dbg( p_access, "Using Digest Access Authentication" );        if( p_auth->psz_nonce ) return; /* FIXME */        psz_header += strlen( "Digest " );        p_auth->psz_realm = AuthGetParam( psz_header, "realm" );        p_auth->psz_domain = AuthGetParam( psz_header, "domain" );        p_auth->psz_nonce = AuthGetParam( psz_header, "nonce" );        p_auth->psz_opaque = AuthGetParam( psz_header, "opaque" );        p_auth->psz_stale = AuthGetParamNoQuotes( psz_header, "stale" );        p_auth->psz_algorithm = AuthGetParamNoQuotes( psz_header, "algorithm" );        p_auth->psz_qop = AuthGetParam( psz_header, "qop" );        p_auth->i_nonce = 0;        /* printf("realm: |%s|\ndomain: |%s|\nnonce: |%s|\nopaque: |%s|\n"                  "stale: |%s|\nalgorithm: |%s|\nqop: |%s|\n",                  p_auth->psz_realm,p_auth->psz_domain,p_auth->psz_nonce,                  p_auth->psz_opaque,p_auth->psz_stale,p_auth->psz_algorithm,                  p_auth->psz_qop); */        if( !p_auth->psz_realm )            msg_Warn( p_access, "Digest Access Authentication: "                      "Mandatory 'realm' parameter is missing" );        if( !p_auth->psz_nonce )            msg_Warn( p_access, "Digest Access Authentication: "                      "Mandatory 'nonce' parameter is missing" );        if( p_auth->psz_qop ) /* FIXME: parse the qop list */        {            char *psz_tmp = strchr( p_auth->psz_qop, ',' );            if( psz_tmp ) *psz_tmp = '\0';        }    }    else    {        const char *psz_end = strchr( psz_header, ' ' );        if( psz_end )            msg_Warn( p_access, "Unknown authentication scheme: '%*s'",                      psz_end - psz_header, psz_header );        else            msg_Warn( p_access, "Unknown authentication scheme: '%s'",                      psz_header );    }}static char *AuthDigest( access_t *p_access, vlc_url_t *p_url,                         http_auth_t *p_auth, const char *psz_method ){    (void)p_access;    const char *psz_username = p_url->psz_username ?: "";    const char *psz_password = p_url->psz_password ?: "";    char *psz_HA1 = NULL;    char *psz_HA2 = NULL;    char *psz_response = NULL;    struct md5_s md5;    /* H(A1) */    if( p_auth->psz_HA1 )    {        psz_HA1 = strdup( p_auth->psz_HA1 );        if( !psz_HA1 ) goto error;    }    else    {        InitMD5( &md5 );        AddMD5( &md5, psz_username, strlen( psz_username ) );        AddMD5( &md5, ":", 1 );        AddMD5( &md5, p_auth->psz_realm, strlen( p_auth->psz_realm ) );        AddMD5( &md5, ":", 1 );        AddMD5( &md5, psz_password, strlen( psz_password ) );        EndMD5( &md5 );        psz_HA1 = psz_md5_hash( &md5 );        if( !psz_HA1 ) goto error;        if( p_auth->psz_algorithm            && !strcmp( p_auth->psz_algorithm, "MD5-sess" ) )        {            InitMD5( &md5 );            AddMD5( &md5, psz_HA1, 32 );            free( psz_HA1 );            AddMD5( &md5, ":", 1 );            AddMD5( &md5, p_auth->psz_nonce, strlen( p_auth->psz_nonce ) );            AddMD5( &md5, ":", 1 );            AddMD5( &md5, p_auth->psz_cnonce, strlen( p_auth->psz_cnonce ) );            EndMD5( &md5 );            psz_HA1 = psz_md5_hash( &md5 );            if( !psz_HA1 ) goto error;            p_auth->psz_HA1 = strdup( psz_HA1 );            if( !p_auth->psz_HA1 ) goto error;        }    }    /* H(A2) */    InitMD5( &md5 );    if( *psz_method )        AddMD5( &md5, psz_method, strlen( psz_method ) );    AddMD5( &md5, ":", 1 );    if( p_url->psz_path )        AddMD5( &md5, p_url->psz_path, strlen( p_url->psz_path ) );    else        AddMD5( &md5, "/", 1 );    if( p_auth->psz_qop && !strcmp( p_auth->psz_qop, "auth-int" ) )    {        char *psz_ent;        struct md5_s ent;        InitMD5( &ent );        AddMD5( &ent, "", 0 ); /* XXX: entity-body. should be ok for GET */        EndMD5( &ent );        psz_ent = psz_md5_hash( &ent );        if( !psz_ent ) goto error;        AddMD5( &md5, ":", 1 );        AddMD5( &md5, psz_ent, 32 );        free( psz_ent );    }    EndMD5( &md5 );    psz_HA2 = psz_md5_hash( &md5 );    if( !psz_HA2 ) goto error;    /* Request digest */    InitMD5( &md5 );    AddMD5( &md5, psz_HA1, 32 );    AddMD5( &md5, ":", 1 );    AddMD5( &md5, p_auth->psz_nonce, strlen( p_auth->psz_nonce ) );    AddMD5( &md5, ":", 1 );    if( p_auth->psz_qop        && ( !strcmp( p_auth->psz_qop, "auth" )             || !strcmp( p_auth->psz_qop, "auth-int" ) ) )    {        char psz_inonce[9];        snprintf( psz_inonce, 9, "%08x", p_auth->i_nonce );        AddMD5( &md5, psz_inonce, 8 );        AddMD5( &md5, ":", 1 );        AddMD5( &md5, p_auth->psz_cnonce, strlen( p_auth->psz_cnonce ) );        AddMD5( &md5, ":", 1 );        AddMD5( &md5, p_auth->psz_qop, strlen( p_auth->psz_qop ) );        AddMD5( &md5, ":", 1 );    }    AddMD5( &md5, psz_HA2, 32 );    EndMD5( &md5 );    psz_response = psz_md5_hash( &md5 );    error:        free( psz_HA1 );        free( psz_HA2 );        return psz_response;}static void AuthReply( access_t *p_access, const char *psz_prefix,                       vlc_url_t *p_url, http_auth_t *p_auth ){    access_sys_t *p_sys = p_access->p_sys;    v_socket_t     *pvs = p_sys->p_vs;    const char *psz_username = p_url->psz_username ?: "";    const char *psz_password = p_url->psz_password ?: "";    if( p_auth->psz_nonce )    {        /* Digest Access Authentication */        char *psz_response;        if(    p_auth->psz_algorithm            && strcmp( p_auth->psz_algorithm, "MD5" )            && strcmp( p_auth->psz_algorithm, "MD5-sess" ) )        {            msg_Err( p_access, "Digest Access Authentication: "                     "Unknown algorithm '%s'", p_auth->psz_algorithm );            return;        }        if( p_auth->psz_qop || !p_auth->psz_cnonce )        {            /* FIXME: needs to be really random to prevent man in the middle             * attacks */            free( p_auth->psz_cnonce );            p_auth->psz_cnonce = strdup( "Some random string FIXME" );        }        p_auth->i_nonce ++;        psz_response = AuthDigest( p_access, p_url, p_auth, "GET" );        if( !psz_response ) return;        net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs,                    "%sAuthorization: Digest "                    /* Mandatory parameters */                    "username=\"%s\", "                    "realm=\"%s\", "                    "nonce=\"%s\", "                    "uri=\"%s\", "                    "response=\"%s\", "                    /* Optional parameters */                    "%s%s%s" /* algorithm */                    "%s%s%s" /* cnonce */                    "%s%s%s" /* opaque */                    "%s%s%s" /* message qop */                    "%s%08x%s" /* nonce count */                    "\r\n",                    /* Mandatory parameters */                    psz_prefix,                    psz_username,                    p_auth->psz_realm,                    p_auth->psz_nonce,                    p_url->psz_path ?: "/",                    psz_response,                    /* Optional parameters */                    p_auth->psz_algorithm ? "algorithm=\"" : "",                    p_auth->psz_algorithm ?: "",                    p_auth->psz_algorithm ? "\", " : "",                    p_auth->psz_cnonce ? "cnonce=\"" : "",                    p_auth->psz_cnonce ?: "",                    p_auth->psz_cnonce ? "\", " : "",                    p_auth->psz_opaque ? "opaque=\"" : "",                    p_auth->psz_opaque ?: "",                    p_auth->psz_opaque ? "\", " : "",                    p_auth->psz_qop ? "qop=\"" : "",                    p_auth->psz_qop ?: "",                    p_auth->psz_qop ? "\", " : "",                    p_auth->i_nonce ? "nc=\"" : "uglyhack=\"", /* Will be parsed as an unhandled extension */                    p_auth->i_nonce,                    p_auth->i_nonce ? "\"" : "\""                  );        free( psz_response );    }    else    {        /* Basic Access Authentication */        char buf[strlen( psz_username ) + strlen( psz_password ) + 2];        char *b64;        snprintf( buf, sizeof( buf ), "%s:%s", psz_username, psz_password );        b64 = vlc_b64_encode( buf );        if( b64 != NULL )        {             net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs,                         "%sAuthorization: Basic %s\r\n", psz_prefix, b64 );             free( b64 );        }    }}static int AuthCheckReply( access_t *p_access, const char *psz_header,                           vlc_url_t *p_url, http_auth_t *p_auth ){    int i_ret = VLC_EGENERIC;    char *psz_nextnonce = AuthGetParam( psz_header, "nextnonce" );    char *psz_qop = AuthGetParamNoQuotes( psz_header, "qop" );    char *psz_rspauth = AuthGetParam( psz_header, "rspauth" );    char *psz_cnonce = AuthGetParam( psz_header, "cnonce" );    char *psz_nc = AuthGetParamNoQuotes( psz_header, "nc" );    if( psz_cnonce )    {        char *psz_digest;        if( strcmp( psz_cnonce, p_auth->psz_cnonce ) )        {            msg_Err( p_access, "HTTP Digest Access Authentication: server replied with a different client nonce value." );            goto error;        }        if( psz_nc )        {            int i_nonce;            i_nonce = strtol( psz_nc, NULL, 16 );            if( i_nonce != p_auth->i_nonce )            {                msg_Err( p_access, "HTTP Digest Access Authentication: server replied with a different nonce count value." );                goto error;            }        }        if( psz_qop && p_auth->psz_qop && strcmp( psz_qop, p_auth->psz_qop ) )            msg_Warn( p_access, "HTTP Digest Access Authentication: server replied using a different 'quality of protection' option" );        /* All the clear text values match, let's now check the response         * digest */        psz_digest = AuthDigest( p_access, p_url, p_auth, "" );        if( strcmp( psz_digest, psz_rspauth ) )        {            msg_Err( p_access, "HTTP Digest Access Authentication: server replied with an invalid response digest (expected value: %s).", psz_digest );            free( psz_digest );            goto error;        }        free( psz_digest );    }    if( psz_nextnonce )    {        free( p_auth->psz_nonce );        p_auth->psz_nonce = psz_nextnonce;        psz_nextnonce = NULL;    }    i_ret = VLC_SUCCESS;    error:        free( psz_nextnonce );        free( psz_qop );        free( psz_rspauth );        free( psz_cnonce );        free( psz_nc );    return i_ret;}static void AuthReset( http_auth_t *p_auth ){    FREENULL( p_auth->psz_realm );    FREENULL( p_auth->psz_domain );    FREENULL( p_auth->psz_nonce );    FREENULL( p_auth->psz_opaque );    FREENULL( p_auth->psz_stale );    FREENULL( p_auth->psz_algorithm );    FREENULL( p_auth->psz_qop );    p_auth->i_nonce = 0;    FREENULL( p_auth->psz_cnonce );    FREENULL( p_auth->psz_HA1 );}

⌨️ 快捷键说明

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