TFCweb  1.0.4 $Rev: 483 $
TFC Primavera 2012: Nucli d'un servidor web
Permisos.cc
Veure la documentació d'aquest fitxer.
1 
8 /*
9  * Copyright (c) 2012 Toni Corvera
10  *
11  * This file is part of TFCWeb.
12  *
13  * TFCWeb is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * TFCWeb is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with TFCWeb. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #include "Permisos.h"
28 
29 using namespace boost::filesystem;
30 
31 namespace {
32 
33 enum {
35 
37 };
38 
39 } // ns anònim
40 
41 
42 namespace tfc {
43 
44 void Cerber::defineix_regla(const ruta_t & ruta, FlagsPermis perm) {
45  perm &= MASCARA_PERMIS; // Desactiva els bits irrellevants
46  // Rebre 0 es considera equivalent a PRIVAT
47  if (0 == perm || 0 != (PRIVAT & perm)) {
48  // Privat: La resta de permisos no tenen sentit
49  perm = PRIVAT;
50  }
51  // INVARIANTS:
52  assert( 0 != perm );
53  assert( perm <= PERMIS_LIMIT );
54 
55  // Si ja està definida, les combinem (PRIVAT no combina amb res)
56  if (PRIVAT != perm) {
57  auto it = regles_.find(ruta);
58  if (regles_.end() != it) {
59  perm = perm | it->second;
60  }
61  }
62 
63  // regles_.insert( make_pair(ruta, perm) ); // No sobre-escriu!
64  regles_[ruta] = perm;
65 }
66 
67 CodiEstatHTTP Cerber::acces(const path & ruta, TipusPeticioHTTP t) const {
68  const FlagsPermis p = permis(ruta);
69  assert( 0 != p ); // INVARIANT
70  assert( p <= PERMIS_LIMIT ); // INVARIANT
71  if (0 != (p & PRIVAT)) {
72  return CODI_403;
73  }
74  if (0 != (p & PROTEGIT)) {
75  return CODI_401;
76  }
77  Permis mascara;
78  switch (t) {
79  case GET:
80  case HEAD:
81  case POST:
82  case OPTIONS:
83  case TRACE:
84  case CONNECT:
85  mascara = LECTURA;
86  break;
87  case PUT:
88  case METODE_DELETE:
89  mascara = ESCRIPTURA;
90  break;
91  default:
92  assert( !"Error intern" );
93  return CODI_403;
94  }
95 
96  if (0 == (p & mascara)) {
97  return CODI_405;
98  }
99 
100  return CODI_200;
101 }
102 
103 FlagsPermis Cerber::permis(const path & ruta) const {
104  const path buit = path();
105  path r(ruta);
106  do { // Comprovem la ruta inicial i les superiors
107  if (exists(r) &&!utils::es_llegible(r)) {
108  // Si existeix però els permisos d'accés no permeten l'accés,
109  // és com si estigués prohibit l'accés
110  return PRIVAT;
111  }
112  auto it = regles_.find(r);
113  if (regles_.end() != it) {
114  // Trobat!
115  return it->second;
116  }
117  r = r.parent_path();
118  } while (buit != r);
119  return per_defecte_ ;
120 }
121 
122 bool Cerber::executable(const ruta_t & ruta) const {
123  const FlagsPermis p = permis(ruta);
124  assert( 0 != p ); // INVARIANT
125  assert( p <= PERMIS_LIMIT ); // INVARIANT
126  return 0 != ( (LECTURA|EXECUCIO) & p );
127 }
128 
129 // friend Cerber
130 ostream& operator<<(ostream & os, const Cerber & c) {
131  os << "Permisos {"
132  << "\n\tdefecte = " << nom_permis(c.per_defecte_);
133  for (auto it=c.regles_.begin(); it != c.regles_.end(); ++it) {
134  os << "\n\t" << it->first << " = " << nom_permis(it->second) ;
135  }
136  return os << "\n}";
137 }
138 
140  f &= MASCARA_PERMIS; // Desactiva els bits irrellevants
141  if (PRIVAT == f) {
142  return "Privat";
143  }
144  string n;
145  if (0 != (f & PROTEGIT)) {
146  n += ",Protegit";
147  }
148  if (0 != (f & LECTURA)) {
149  n += ",Lectura";
150  }
151  if (0 != (f & ESCRIPTURA)) {
152  n += ",Escriptura";
153  }
154  if (0 != (f & EXECUCIO)) {
155  n += ",Execució";
156  }
157  if (n.empty()) {
158  return n;
159  }
160  assert( n.length() > 0 );
161  n.erase(0, 1);
162  return n;
163 }
164 
165 } // ns tfc
166 
167 // vim:set ts=4 et ai: //