Changeset 4981062b2acde89c8ff3e938375cc0ccb482b154

Show
Ignore:
Timestamp:
09/04/08 21:31:54 (6 months ago)
Author:
Antoine Cellerier <dionoea@videolan.org>
git-committer:
Antoine Cellerier <dionoea@videolan.org> 1207769514 +0200
git-parent:

[ee8a709f6b5b8e66c2de73030f2c422546070f0a]

git-author:
Antoine Cellerier <dionoea@videolan.org> 1207769463 +0200
Message:

Simplify the HTTP Digest Access Authentification code.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/access/http.c

    r7e269d8 r4981062  
    128128    int i_nonce; 
    129129    char *psz_cnonce; 
    130     char *psz_A1; /* stored A1 value if algorithm = "MD5-sess" */ 
     130    char *psz_HA1; /* stored H(A1) value if algorithm = "MD5-sess" */ 
    131131} http_auth_t; 
    132132 
     
    15121512        psz_header += strlen( psz_what ); 
    15131513        psz_end = strchr( psz_header, '"' ); 
    1514         if( !psz_end ) 
    1515         { 
    1516             psz_end = psz_header; 
    1517             while( *psz_end ) psz_end++; 
    1518         } 
     1514        if( !psz_end ) /* Invalid since we should have a closing quote */ 
     1515            return strdup( psz_header ); 
    15191516        return strndup( psz_header, psz_end - psz_header ); 
    15201517    } 
     
    15271524static char *AuthGetParamNoQuotes( const char *psz_header, const char *psz_param ) 
    15281525{ 
    1529     char psz_what[strlen(psz_param)+3]; 
     1526    char psz_what[strlen(psz_param)+2]; 
    15301527    sprintf( psz_what, "%s=", psz_param ); 
    15311528    psz_header = strstr( psz_header, psz_what ); 
     
    15351532        psz_header += strlen( psz_what ); 
    15361533        psz_end = strchr( psz_header, ',' ); 
    1537         if( !psz_end ) 
    1538         { 
    1539             psz_end = psz_header; 
    1540             while( *psz_end ) psz_end++; 
    1541         } 
     1534        /* XXX: Do we need to filter out trailing space between the value and 
     1535         * the comma/end of line? */ 
     1536        if( !psz_end ) /* Can be valid if this is the last parameter */ 
     1537            return strdup( psz_header ); 
    15421538        return strndup( psz_header, psz_end - psz_header ); 
    15431539    } 
     
    15771573        p_auth->psz_qop = AuthGetParam( psz_header, "qop" ); 
    15781574        p_auth->i_nonce = 0; 
    1579         /* printf("realm: %s\ndomain: %s\nnonce: %s\nopaque: %s\nstale: %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); */ 
     1575        /* printf("realm: |%s|\ndomain: |%s|\nnonce: |%s|\nopaque: |%s|\n" 
     1576                  "stale: |%s|\nalgorithm: |%s|\nqop: |%s|\n", 
     1577                  p_auth->psz_realm,p_auth->psz_domain,p_auth->psz_nonce, 
     1578                  p_auth->psz_opaque,p_auth->psz_stale,p_auth->psz_algorithm, 
     1579                  p_auth->psz_qop); */ 
    15801580        if( !p_auth->psz_realm ) 
    15811581            msg_Warn( p_access, "Digest Access Authentication: " 
     
    15841584            msg_Warn( p_access, "Digest Access Authentication: " 
    15851585                      "Mandatory 'nonce' parameter is missing" ); 
    1586         if( p_auth->psz_qop ) /* FIXME */ 
     1586        if( p_auth->psz_qop ) /* FIXME: parse the qop list */ 
    15871587        { 
    15881588            char *psz_tmp = strchr( p_auth->psz_qop, ',' ); 
     
    15931593    { 
    15941594        const char *psz_end = strchr( psz_header, ' ' ); 
    1595         if( !psz_end ) 
    1596         { 
    1597             psz_end = psz_header; 
    1598             while( *psz_end ) psz_end++; 
    1599         } 
    1600         msg_Warn( p_access, "Unknown authentication scheme: '%*s'", 
    1601                   psz_end - psz_header, psz_header ); 
    1602     } 
    1603 
    1604  
     1595        if( psz_end ) 
     1596            msg_Warn( p_access, "Unknown authentication scheme: '%*s'", 
     1597                      psz_end - psz_header, psz_header ); 
     1598        else 
     1599            msg_Warn( p_access, "Unknown authentication scheme: '%s'", 
     1600                      psz_header ); 
     1601    } 
     1602
    16051603static char *AuthAlgoMD5( const char *psz_data ) 
    16061604{ 
     
    16261624    { 
    16271625        /* Digest Access Authentication */ 
     1626        char *psz_HA1 = NULL; 
     1627        char *psz_HA2 = NULL; 
    16281628        char *psz_response = NULL; 
    1629         char *psz_A1 = NULL; 
    1630         char *psz_A2 = NULL; 
    1631         char *psz_secret = NULL; 
    1632         char *psz_data = NULL; 
    1633         char * (*pf_algo)( const char * ); 
    1634  
    1635         if(    p_auth->psz_algorithm == NULL 
    1636             || !strcmp( p_auth->psz_algorithm, "MD5" ) 
    1637             || !strcmp( p_auth->psz_algorithm, "MD5-sess" ) ) 
    1638         { 
    1639             pf_algo = AuthAlgoMD5; 
    1640         } 
    1641         else 
     1629        struct md5_s md5; 
     1630 
     1631        if(    p_auth->psz_algorithm 
     1632            && strcmp( p_auth->psz_algorithm, "MD5" ) 
     1633            && strcmp( p_auth->psz_algorithm, "MD5-sess" ) ) 
    16421634        { 
    16431635            msg_Err( p_access, "Digest Access Authentication: " 
    16441636                     "Unknown algorithm '%s'", p_auth->psz_algorithm ); 
    1645         } 
    1646         if( !pf_algo ) return; 
    1647  
    1648         if( p_auth->psz_qop
     1637            return; 
     1638        } 
     1639 
     1640        if( p_auth->psz_qop || !p_auth->psz_cnonce
    16491641        { 
    16501642            /* FIXME: needs to be really random to prevent man in the middle 
     
    16551647        p_auth->i_nonce ++; 
    16561648 
    1657         if( p_auth->psz_algorithm && !strcmp( p_auth->psz_algorithm, "MD5-sess" ) ) 
    1658         { 
    1659             if( !p_auth->psz_A1 ) 
     1649        /* H(A1) */ 
     1650        if( p_auth->psz_HA1 ) 
     1651        { 
     1652            psz_HA1 = strdup( p_auth->psz_HA1 ); 
     1653            if( !psz_HA1 ) goto error; 
     1654        } 
     1655        else 
     1656        { 
     1657            InitMD5( &md5 ); 
     1658            AddMD5( &md5, psz_username, strlen( psz_username ) ); 
     1659            AddMD5( &md5, ":", 1 ); 
     1660            AddMD5( &md5, p_auth->psz_realm, strlen( p_auth->psz_realm ) ); 
     1661            AddMD5( &md5, ":", 1 ); 
     1662            AddMD5( &md5, psz_password, strlen( psz_password ) ); 
     1663            EndMD5( &md5 ); 
     1664 
     1665            psz_HA1 = psz_md5_hash( &md5 ); 
     1666            if( !psz_HA1 ) goto error; 
     1667 
     1668            if( p_auth->psz_algorithm 
     1669                && !strcmp( p_auth->psz_algorithm, "MD5-sess" ) ) 
    16601670            { 
    1661                 char *psz_tmp = NULL; 
    1662                 if( asprintf( &psz_A1, "%s:%s:%s", psz_username, 
    1663                               p_auth->psz_realm, psz_password ) < 0 ) 
    1664                     goto error; 
    1665                 psz_tmp = pf_algo( psz_A1 ); 
    1666                 free( psz_A1 ); psz_A1 = NULL; 
    1667                 if( !psz_tmp ) goto error; 
    1668                 if( asprintf( &psz_A1, "%s:%s:%s", psz_tmp, p_auth->psz_nonce, 
    1669                     p_auth->psz_cnonce ) < 0 ) 
    1670                 { 
    1671                     free( psz_tmp ); 
    1672                     goto error; 
    1673                 } 
    1674                 p_auth->psz_A1 = strdup( psz_A1 ); 
     1671                InitMD5( &md5 ); 
     1672                AddMD5( &md5, psz_HA1, 32 ); 
     1673                free( psz_HA1 ); 
     1674                AddMD5( &md5, ":", 1 ); 
     1675                AddMD5( &md5, p_auth->psz_nonce, strlen( p_auth->psz_nonce ) ); 
     1676                AddMD5( &md5, ":", 1 ); 
     1677                AddMD5( &md5, p_auth->psz_cnonce, strlen( p_auth->psz_cnonce ) ); 
     1678                EndMD5( &md5 ); 
     1679 
     1680                psz_HA1 = psz_md5_hash( &md5 ); 
     1681                if( !psz_HA1 ) goto error; 
     1682                p_auth->psz_HA1 = strdup( psz_HA1 ); 
     1683                if( !p_auth->psz_HA1 ) goto error; 
    16751684            } 
    1676             else 
    1677             { 
    1678                 psz_A1 = strdup( p_auth->psz_A1 ); 
    1679             } 
    1680         } 
     1685        } 
     1686 
     1687        /* H(A2) */ 
     1688        InitMD5( &md5 ); 
     1689        AddMD5( &md5, "GET", 3 ); /* FIXME ? */ 
     1690        AddMD5( &md5, ":", 1 ); 
     1691        if( p_url->psz_path ) 
     1692            AddMD5( &md5, p_url->psz_path, strlen( p_url->psz_path ) ); 
    16811693        else 
    1682         { 
    1683             if( asprintf( &psz_A1, "%s:%s:%s", psz_username, p_auth->psz_realm, 
    1684                           psz_password ) < 0 ) goto error; 
    1685         } 
    1686  
    1687         if( !p_auth->psz_qop || !strcmp( p_auth->psz_qop, "auth" ) ) 
    1688         { 
    1689             if( asprintf( &psz_A2, "%s:%s", "GET", p_url->psz_path ?: "/" ) 
    1690                 < 0 ) goto error
    1691         } 
    1692         else 
    1693         { 
    1694             char *psz_tmp = pf_algo( "FIXME entity-body" ); /* FIXME */ 
    1695             if( asprintf( &psz_A2, "%s:%s:%s", "GET", p_url->psz_path ?: "/", 
    1696                 psz_tmp ) < 0 ) 
    1697             { 
    1698                 free( psz_tmp )
    1699                 goto error; 
    1700             } 
    1701             free( psz_tmp ); 
    1702         } 
    1703  
    1704         psz_secret = pf_algo( psz_A1 ); 
    1705  
     1694            AddMD5( &md5, "/", 1 ); 
     1695        if( p_auth->psz_qop && !strcmp( p_auth->psz_qop, "auth-int" ) ) 
     1696        { 
     1697            char *psz_ent; 
     1698            struct md5_s ent; 
     1699            InitMD5( &ent ); 
     1700            AddMD5( &ent, "", 0 ); /* XXX: entity-body. should be ok for GET */ 
     1701            EndMD5( &ent ); 
     1702            psz_ent = psz_md5_hash( &ent )
     1703            if( !psz_ent ) goto error; 
     1704            AddMD5( &md5, ":", 1 ); 
     1705            AddMD5( &md5, psz_ent, 32 ); 
     1706            free( psz_ent ); 
     1707        } 
     1708        EndMD5( &md5 ); 
     1709        psz_HA2 = psz_md5_hash( &md5 ); 
     1710        if( !psz_HA2 ) goto error
     1711 
     1712        /* Request digest */ 
     1713        InitMD5( &md5 ); 
     1714        AddMD5( &md5, psz_HA1, 32 ); 
     1715        AddMD5( &md5, ":", 1 ); 
     1716        AddMD5( &md5, p_auth->psz_nonce, strlen( p_auth->psz_nonce ) ); 
     1717        AddMD5( &md5, ":", 1 ); 
    17061718        if( p_auth->psz_qop 
    17071719            && ( !strcmp( p_auth->psz_qop, "auth" ) 
    17081720                 || !strcmp( p_auth->psz_qop, "auth-int" ) ) ) 
    17091721        { 
    1710             char *psz_tmp = pf_algo( psz_A2 ); 
    1711             if( !psz_tmp ) goto error; 
    1712             if( asprintf( &psz_data, "%s:%08x:%s:%s:%s", 
    1713                           p_auth->psz_nonce, p_auth->i_nonce, 
    1714                           p_auth->psz_cnonce, p_auth->psz_qop, psz_tmp ) < 0 ) 
    1715             { 
    1716                 free( psz_tmp ); 
    1717                 goto error; 
    1718             } 
    1719             free( psz_tmp ); 
    1720         } 
    1721         else 
    1722         { 
    1723             char *psz_tmp = pf_algo( psz_A2 ); 
    1724             if( !psz_tmp ) goto error; 
    1725             if( asprintf( &psz_data, "%s:%s", p_auth->psz_nonce, psz_tmp ) < 0 ) 
    1726             { 
    1727                 free( psz_tmp ); 
    1728                 goto error; 
    1729             } 
    1730             free( psz_tmp ); 
    1731         } 
    1732  
    1733         if( psz_secret && psz_data ) 
    1734         { 
    1735             char *psz_tmp = NULL; 
    1736             if( asprintf( &psz_tmp, "%s:%s", psz_secret, psz_data ) < 0 ) 
    1737                 goto error; 
    1738             psz_response = pf_algo( psz_tmp ); 
    1739             free( psz_tmp ); 
    1740             if( !psz_response ) 
    1741                 goto error; 
    1742         } 
    1743         else 
    1744         { 
    1745             goto error; 
    1746         } 
     1722            char psz_inonce[9]; 
     1723            snprintf( psz_inonce, 9, "%08x", p_auth->i_nonce ); 
     1724            AddMD5( &md5, psz_inonce, 8 ); 
     1725            AddMD5( &md5, ":", 1 ); 
     1726            AddMD5( &md5, p_auth->psz_cnonce, strlen( p_auth->psz_cnonce ) ); 
     1727            AddMD5( &md5, ":", 1 ); 
     1728            AddMD5( &md5, p_auth->psz_qop, strlen( p_auth->psz_qop ) ); 
     1729            AddMD5( &md5, ":", 1 ); 
     1730        } 
     1731        AddMD5( &md5, psz_HA2, 32 ); 
     1732        EndMD5( &md5 ); 
     1733        psz_response = psz_md5_hash( &md5 ); 
     1734        if( !psz_response ) goto error; 
    17471735 
    17481736        net_Printf( VLC_OBJECT(p_access), p_sys->fd, pvs, 
     
    17861774                  ); 
    17871775 
     1776 
    17881777    error: 
     1778        free( psz_HA1 ); 
     1779        free( psz_HA2 ); 
    17891780        free( psz_response ); 
    1790         free( psz_A1 ); 
    1791         free( psz_A2 ); 
    1792         free( psz_secret ); 
    1793         free( psz_data ); 
    17941781    } 
    17951782    else 
     
    18221809    p_auth->i_nonce = 0; 
    18231810    FREENULL( p_auth->psz_cnonce ); 
    1824     FREENULL( p_auth->psz_A1 ); 
    1825 } 
     1811    FREENULL( p_auth->psz_HA1 ); 
     1812}