Changeset 67346 in spip-zone


Ignore:
Timestamp:
Oct 31, 2012, 2:04:56 PM (7 years ago)
Author:
cedric@…
Message:

Les urls des documents protégés de la forme spip.php?action=acceder_document&arg=N&cle=xxxx&file=ext/file.ext ne passent pas dans certains lecteurs vidéos flash (en plus d'être moche).
On remanie donc sous la forme docrestreint.api/N/xxxx/ext/file.ext qui passe bien, est plus lisible et ressemble a un vrai chemin vers un fichier (ce qui permet au navigateur de trouver correctement le nom du fichier quand on veut telecharger le document).

C'est encore imparfait car l'ideal serait de ne pas modifier du tout les URLs mais de les mapper sur l'action via le htaccess et de verifier les droits de lecture à ce moment là.

Location:
_plugins_/acces_restreint/trunk
Files:
1 added
2 edited
2 copied

Legend:

Unmodified
Added
Removed
  • _plugins_/acces_restreint/trunk/action/acceder_document.php

    r28228 r67346  
    2222// http://doc.spip.org/@action_acceder_document_dist
    2323function action_acceder_document_dist() {
    24         include_spip('inc/documents');
    2524
    2625        // $file exige pour eviter le scan id_document par id_document
    2726        $f = rawurldecode(_request('file'));
    28         $file = get_spip_doc($f);
    2927        $arg = rawurldecode(_request('arg'));
     28        $cle = _request('cle');
    3029
    31         $status = $dcc = false;
    32         if (strpos($f,'../') !== false
    33         OR preg_match(',^\w+://,', $f)) {
    34                 $status = 403;
    35         }
    36         else if (!file_exists($file) OR !is_readable($file)) {
    37                 $status = 404;
    38         } else {
    39                 $where = "documents.fichier=".sql_quote(set_spip_doc($file))
    40                 . ($arg ? " AND documents.id_document=".intval($arg): '');
    41 
    42                 $doc = sql_fetsel("documents.id_document, documents.titre, documents.fichier, types.mime_type, types.inclus, documents.extension", "spip_documents AS documents LEFT JOIN spip_types_documents AS types ON documents.extension=types.extension",$where);
    43                 if (!$doc) {
    44                         $status = 404;
    45                 } else {
    46 
    47                         // ETag pour gerer le status 304
    48                         $ETag = md5($file . ': '. filemtime($file));
    49                         if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
    50                         AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
    51                                 http_status(304); // Not modified
    52                                 exit;
    53                         } else {
    54                                 header('ETag: '.$ETag);
    55                         }
    56 
    57                         //
    58                         // Verifier les droits de lecture du document
    59                         // en controlant la cle passee en argument
    60                         //
    61                         include_spip('inc/securiser_action');
    62                         $cle = _request('cle');
    63                         if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
    64                                 spip_log("acces interdit $cle erronee");
    65                                 $status = 403;
    66                         }
    67                 }
    68         }
    69 
    70         switch($status) {
    71 
    72         case 403:
    73                 include_spip('inc/minipres');
    74                 echo minipres();
    75                 break;
    76 
    77         case 404:
    78                 http_status(404);
    79                 include_spip('inc/minipres');
    80                 echo minipres(_T('erreur').' 404',
    81                         _T('info_document_indisponible'));
    82                 break;
    83 
    84         default:
    85                 header("Content-Type: ". $doc['mime_type']);
    86 
    87                 // pour les images ne pas passer en attachment
    88                 // sinon, lorsqu'on pointe directement sur leur adresse,
    89                 // le navigateur les downloade au lieu de les afficher
    90 
    91                 if ($doc['inclus']=='non') {
    92 
    93                         $f = basename($file);
    94                         // ce content-type est necessaire pour eviter des corruptions de zip dans ie6
    95                         header('Content-Type: application/octet-stream');
    96 
    97                         header("Content-Disposition: attachment; filename=\"$f\";");
    98                         header("Content-Transfer-Encoding: binary");
    99 
    100                         // fix for IE catching or PHP bug issue
    101                         header("Pragma: public");
    102                         header("Expires: 0"); // set expiration time
    103                         header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    104 
    105                 }
    106 
    107                 if ($cl = filesize($file))
    108                         header("Content-Length: ". $cl);
    109 
    110                 readfile($file);
    111                 break;
    112         }
     30        $api_docrestreint = charger_fonction("api_docrestreint","action");
     31        return $api_docrestreint("$arg/$cle/$f");
    11332
    11433}
  • _plugins_/acces_restreint/trunk/action/api_docrestreint.php

    r67327 r67346  
    1515include_spip('inc/headers');
    1616
    17 // acces aux documents joints securise
    18 // verifie soit que le demandeur est authentifie
    19 // soit que le document est publie, c'est-a-dire
    20 // joint a au moins 1 article, breve ou rubrique publie
     17/**
     18 * acces aux documents joints securise
     19 * verifie soit que le demandeur est authentifie
     20 * soit que le document est publie, c'est-a-dire
     21 * joint a au moins 1 article, breve ou rubrique publie
     22 *
     23 * URLs de la forme :
     24 * docrestreint.api/id/cle/file
     25 *
     26 * @param null $arg
     27 */
     28function action_api_docrestreint_dist($arg=null) {
     29        $status = 404;
    2130
    22 // http://doc.spip.org/@action_acceder_document_dist
    23 function action_acceder_document_dist() {
    24         include_spip('inc/documents');
     31        if (is_null($arg))
     32                $arg =_request('arg');
    2533
    26         // $file exige pour eviter le scan id_document par id_document
    27         $f = rawurldecode(_request('file'));
    28         $file = get_spip_doc($f);
    29         $arg = rawurldecode(_request('arg'));
     34        $arg = explode("/",$arg);
    3035
    31         $status = $dcc = false;
    32         if (strpos($f,'../') !== false
    33         OR preg_match(',^\w+://,', $f)) {
    34                 $status = 403;
    35         }
    36         else if (!file_exists($file) OR !is_readable($file)) {
    37                 $status = 404;
    38         } else {
    39                 $where = "documents.fichier=".sql_quote(set_spip_doc($file))
    40                 . ($arg ? " AND documents.id_document=".intval($arg): '');
     36        if (count($arg)>=3){
    4137
    42                 $doc = sql_fetsel("documents.id_document, documents.titre, documents.fichier, types.mime_type, types.inclus, documents.extension", "spip_documents AS documents LEFT JOIN spip_types_documents AS types ON documents.extension=types.extension",$where);
    43                 if (!$doc) {
     38                $id_document = intval(array_shift($arg));
     39                $cle = array_shift($arg);
     40                // file exige pour eviter le scan id_document par id_document
     41                $f = implode("/",$arg);
     42
     43                include_spip('inc/documents');
     44
     45                $file = get_spip_doc($f);
     46                spip_log($file,'dbg');
     47
     48                $status = $dcc = false;
     49                // securite : on refuse tout ../ ou url absolue
     50                if (strpos($f,'../') !== false
     51                  OR preg_match(',^\w+://,', $f)) {
     52                        $status = 403;
     53                }
     54                else if (!file_exists($file) OR !is_readable($file)) {
    4455                        $status = 404;
    45                 } else {
     56                }
     57                else {
     58                        $where = "documents.fichier=".sql_quote(set_spip_doc($file))
     59                        . ($id_document ? " AND documents.id_document=".intval($id_document): '');
     60                        spip_log($where,'dbg');
    4661
    47                         // ETag pour gerer le status 304
    48                         $ETag = md5($file . ': '. filemtime($file));
    49                         if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
    50                         AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
    51                                 http_status(304); // Not modified
    52                                 exit;
    53                         } else {
    54                                 header('ETag: '.$ETag);
     62                        $doc = sql_fetsel("documents.id_document, documents.titre, documents.fichier, types.mime_type, types.inclus, documents.extension", "spip_documents AS documents LEFT JOIN spip_types_documents AS types ON documents.extension=types.extension",$where);
     63                        spip_log($doc,'dbg');
     64                        if (!$doc) {
     65                                $status = 404;
    5566                        }
     67                        else {
    5668
    57                         //
    58                         // Verifier les droits de lecture du document
    59                         // en controlant la cle passee en argument
    60                         //
    61                         include_spip('inc/securiser_action');
    62                         $cle = _request('cle');
    63                         if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
    64                                 spip_log("acces interdit $cle erronee");
    65                                 $status = 403;
     69                                // ETag pour gerer le status 304
     70                                $ETag = md5($file . ': '. filemtime($file));
     71                                if (isset($_SERVER['HTTP_IF_NONE_MATCH'])
     72                                AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {
     73                                        http_status(304); // Not modified
     74                                        exit;
     75                                } else {
     76                                        header('ETag: '.$ETag);
     77                                }
     78
     79                                //
     80                                // Verifier les droits de lecture du document
     81                                // en controlant la cle passee en argument
     82                                //
     83                                include_spip('inc/securiser_action');
     84                                if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {
     85                                        spip_log("acces interdit $cle erronee");
     86                                        $status = 403;
     87                                }
    6688                        }
    6789                }
    6890        }
     91
    6992
    7093        switch($status) {
     
    84107        default:
    85108                header("Content-Type: ". $doc['mime_type']);
    86 
    87109                // pour les images ne pas passer en attachment
    88110                // sinon, lorsqu'on pointe directement sur leur adresse,
     
    104126
    105127                }
     128                else {
     129                        header("Expires: 3600"); // set expiration time
     130                }
    106131
    107132                if ($cl = filesize($file))
  • _plugins_/acces_restreint/trunk/paquet.xml

    r67329 r67346  
    22        prefix="accesrestreint"
    33        categorie="auteur"
    4         version="3.6.3"
     4        version="3.7.0"
    55        etat="stable"
    66        compatibilite="[3.0.0;3.0.*]"
     
    3333
    3434        <menu nom="zones" titre="accesrestreint:icone_menu_config" parent="menu_publication" icone="images/zone-16.png" />
     35
     36        <utilise nom="medias" compatibilite="[;]" />
    3537</paquet>
  • _plugins_/acces_restreint/trunk/urls/generer_url_document.php

    r67330 r67346  
    2828 */
    2929function urls_generer_url_document_dist($id, $args='', $ancre='', $public=null, $connect='') {
     30        include_spip('inc/autoriser');
    3031        include_spip('inc/documents');
    31         return generer_url_document_dist($id, $args, $ancre);
     32
     33        if (!autoriser('voir', 'document', $id)) return '';
     34
     35        $r = sql_fetsel("fichier,distant", "spip_documents", "id_document=".intval($id));
     36
     37        if (!$r) return '';
     38
     39        $f = $r['fichier'];
     40
     41        if ($r['distant'] == 'oui') return $f;
     42
     43        // Si droit de voir tous les docs, pas seulement celui-ci
     44        // il est inutilement couteux de rajouter une protection
     45        $r = (autoriser('voir', 'document'));
     46        if (($r AND $r !== 'htaccess'))
     47                return get_spip_doc($f);
     48
     49        include_spip('inc/securiser_action');
     50
     51        // cette url doit etre publique !
     52        $cle = calculer_cle_action($id.','.$f);
     53        return _DIR_RACINE."docrestreint.api/$id/$cle/$f";
    3254}
Note: See TracChangeset for help on using the changeset viewer.