fakeroot usage added to avoid root privileges requirements.
[threegates.git] / raw / root / var / www / onlycrs / Obj / certgate.pho
1 <?php
2
3 /* CONFIG VARS */
4 $CRLURINEW_PATH = "/var/lib/3gates/crlurinew";
5 $CRLURI_PATH  = "/var/lib/3gates/crluri";
6 $CRL_PATH     = "/var/lib/3gates/crl";
7 $OPENSSL_PATH = "/usr/bin/openssl";
8
9 /* function crgt_certgate() return values */
10 define("CRGT_TRUE",  0);
11 define("CRGT_FALSE", 1);
12 define("CRGT_RETRY", 2);
13
14
15 /*
16  * NAME
17  *   string crgt_ret2str(er)
18  * 
19  * DESCRIPTION
20  *   convert the return value of crgt_certgate() to a string   
21  *
22  *   er - value returned by crgt_certgate()
23  *
24  * RETURN
25  *   Return a string description of the returned value of crgt_certgate() function, "value unknown" 
26  *   elseXXX.
27  *
28  */
29 function crgt_ret2str($er)
30 {
31   switch ($er) {
32   case CRGT_TRUE:
33     $ret = "CRGT_TRUE";
34     break;
35   case CRGT_FALSE:
36     $ret = "CRGT_FALSE";
37     break;
38   case CRGT_RETRY:
39     $ret = "CRGT_RETRY";
40     break;
41   default:
42     $ret = "value unknown";
43     break;
44   }
45   
46   return ($ret);
47 }
48
49 /*
50  * NAME
51  *   lock_handle crgt_lock(mode)
52  * 
53  * DESCRIPTION
54  *   lock the shared dir where cooperate with certgate python script
55  *
56  *   mode - LOCK_SH or LOCK_EX - to share as a reader or a writer
57  *
58  * RETURN
59  *   Return a handle to lock the locked file, FALSE elseXXX.
60  *
61  */
62
63 class crgt_lock {
64     var $fp;
65     var $lck;
66
67     function crgt_lock () {        
68         $fp  = FALSE;
69         $lck = FALSE;
70     }
71
72     function lock($mode)
73     {
74         GLOBAL $CRLURINEW_PATH;
75         
76         $umask_old = umask(002);
77         if (($this->fp = fopen($CRLURINEW_PATH."/certgate.lck", "w+")) == FALSE) {
78             echo "LOCK FALSE";
79             return (FALSE);
80         }
81         umask($umask_old);
82         $lck = flock($this->fp, $mode);
83         return ($lck);
84     }
85
86     function unlock()
87     {
88         if ($this->lck) {
89             flock($this->lck, LOCK_UN);
90             $this->lck = FALSE;
91         }
92         if ($this->fp) {
93             fclose($this->fp);
94             $this->fp = FALSE;
95         }
96     }
97
98 }
99
100
101
102 /*
103  * NAME
104  *   lock_handle crgt_lock(mode)
105  * 
106  * DESCRIPTION
107  *   lock the shared dir where cooperate with certgate python script
108  *
109  *   mode - LOCK_SH or LOCK_EX - to share as a reader or a writer
110  *
111  * RETURN
112  *   Return a handle to lock the locked file, FALSE elseXXX.
113  *
114  */
115 function crgt_lock($mode)
116 {
117   GLOBAL $CRLURINEW_PATH;
118   
119   $umask_old = umask(002);
120   if (($fp = fopen($CRLURINEW_PATH."/certgate.lck", "w+")) == FALSE) {
121     umask($umask_old);
122     return (FALSE);
123   }
124   umask($umask_old);
125   return (flock($fp, $mode));
126 }
127
128 /*
129  * NAME
130  *   void crgt_lock(lock_handle)
131  * 
132  * DESCRIPTION
133  *   unlock a previews locked session
134  *
135  *   lock_handle - the handle of the lock
136  *
137  */
138 function crgt_unlock($lck)
139 {
140   flock($lck, LOCK_UN);
141   fclose($lck);
142 }
143
144 /*
145  * NAME
146  *   array &crgt_getcrluri($cert)
147  * 
148  * DESCRIPTION
149  *   get crl URIS from a client certificate
150  *
151  * RETURN
152  *   return an array of URIS (string) or FALSE if an error is occurred
153  *
154  */
155 function &crgt_getcrluri($cert)
156 {
157   GLOBAL $OPENSSL_PATH;
158
159   $retarr = array();
160   $retarr_n = 0;
161   $st = -1;
162   $pipes = array();
163   
164   $descriptorspec = array(
165                           0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
166                           1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
167                           2 => array("pipe", "w")   // stderr is a file to write to
168                           );
169
170   
171   $process = proc_open($OPENSSL_PATH.' x509 -text -noout', $descriptorspec, $pipes);
172   if (is_resource($process)) {
173     // $pipes now looks like this:
174     // 0 => writeable handle connected to child stdin
175     // 1 => readable handle connected to child stdout
176     // Any error output will be appended to /tmp/error-output.txt
177     
178     fwrite($pipes[0], $cert);
179     $st = 0;
180     while (!feof($pipes[1])) {
181       $buffer = fgets($pipes[1], 4096);
182       if ($st == 0) {
183         if (stristr($buffer, 'CRL Distribution Points')) {
184           $st = 1;
185         }
186       }
187       else if ($st == 1) {
188         // if (strstr($buffer, 'URI:')) {
189         if (eregi('^ *URI:', $buffer)) {
190           $retarr[$retarr_n++] = eregi_replace('^ *URI:', '', rtrim($buffer, "\r\n"));
191         }
192         else if ($buffer != "\n")
193           $st = 2;
194       }
195     }
196
197     fclose($pipes[0]);
198     fclose($pipes[1]);
199     fclose($pipes[2]);
200     
201     // It is important that you close any pipes before calling
202     // proc_close in order to avoid a deadlock
203     $return_value = proc_close($process);
204   }
205
206   if ($st != 2 || $return_value != 0) 
207     return (false);
208   else
209     return ($retarr);
210 }
211
212 /*
213  * NAME
214  *   string crgt_crluri2str(crluri)
215  * 
216  * DESCRIPTION
217  *   convert the crluri array to a string
218  *
219  *   crluri - array of crluri (strings)
220  *
221  * RETURN
222  *   return a string that is the sum of all crluri array entries ('\n' separated)
223  *
224  */
225 function crgt_crluri2str($crluri)
226 {
227    $crluri_str = "";
228
229    for ($i = 0 ; $i < count($crluri) ; $i++) 
230      $crluri_str .= $crluri[$i]."\n";
231    
232    return ($crluri_str);
233 }
234
235
236 /*
237  * NAME
238  *   string crgt_str2hash(str)
239  * 
240  * DESCRIPTION
241  *   compute the hash of a string
242  *
243  *   str - string to be hashed
244  *
245  * RETURN
246  *   return the computed hash
247  *
248  */
249 function crgt_str2hash($str)
250 {
251    $hash = mhash(MHASH_CRC32, $str);
252
253    return ($hash);
254 }
255     
256 function crgt_certgate($cert, $onlycheck)
257 {
258   GLOBAL $CRLURI_PATH, $CRLURINEW_PATH, $CRL_PATH;
259
260   $ret = CRGT_FALSE;
261   $fp = FALSE;
262   $umask_old = -1;
263
264   $crluri = FALSE;
265   $lock = new crgt_lock();
266   do {
267     if (($lock->lock(LOCK_SH)) == FALSE)
268       break;
269     if (($crluri = crgt_getcrluri($cert)) == FALSE)
270       break;
271
272     if (!is_array($crluri))
273       break;
274
275     $crluri_str = crgt_crluri2str($crluri);
276
277     $crluri_hash = crgt_str2hash($crluri_str);
278
279     $crluri_file = sprintf("%s/%s.cont", $CRLURI_PATH, bin2hex($crluri_hash));
280     $crlurinew_file = sprintf("%s/%s.cont", $CRLURINEW_PATH, bin2hex($crluri_hash));
281     $crluri_exists = file_exists($crluri_file);
282     $crlurinew_exists = file_exists($crlurinew_file);
283
284
285     // if crluri file don't exists: 
286     if (!$crluri_exists && !$crlurinew_exists) {
287
288       // if onlycheck return false
289       if ($onlycheck) 
290         break;
291       
292       // else add it in the list of crluri list
293       $lock->unlock();
294       
295       // lock the dir as writer
296       if (($lock->lock(LOCK_EX)) == FALSE)
297         break;
298       
299       $umask_old = umask(002);
300       if (($fp = fopen($crlurinew_file, "w")) == FALSE)
301         break;
302       if (fwrite($fp, $crluri_str) < strlen($crluri_str))
303         break;
304       $ret = CRGT_RETRY;
305       break;
306     }
307
308     $crl_file = sprintf("%s/%s.crl", $CRL_PATH, bin2hex($crluri_hash));
309     if (($crl_exists = file_exists($crl_file)) == FALSE) {
310       $ret = CRGT_RETRY;
311       break;
312     }
313
314     $ret = CRGT_TRUE;
315   } while (0);
316
317
318   if ($umask_old != -1)
319     umask($umask_old);
320
321   if ($fp != FALSE)
322     fclose($fp);
323
324   $lock->unlock();
325
326   return ($ret);
327 }
328
329 ?>