Пример #1
0
 /**
  * Create a policy from a file
  *
  * <code>
  *   uses('security.Policy', 'io.File');
  *
  *   try {
  *     $policy= Policy::fromFile(new File('my.policy'));
  *   } catch(PolicyException $e) {
  *     $e->printStackTrace();
  *     exit();
  *   }
  *
  *   echo $policy->toString();
  * </code>
  *
  * @see     http://java.sun.com/j2se/1.4.1/docs/guide/security/PolicyFiles.html
  * @param   io.Stream stream
  * @return  security.Policy policy
  */
 public static function fromFile($stream)
 {
     static $errors = array(PF_ST_EPARSE => 'Parse error', PF_ST_EGRANT => 'Grant syntax error', PF_ST_EPERM => 'Permission syntax error', PF_ST_ESTATE => 'State error', PF_ST_EREFLECT => 'Reflection error');
     $policy = new Policy();
     $stream->open(FILE_MODE_READ);
     $state = PF_ST_INITIAL;
     $num = 0;
     do {
         while (!$stream->eof() && FALSE !== ($line = $stream->readLine())) {
             $num++;
             // Ignore empty lines
             if (empty($line)) {
                 continue;
             }
             switch ($state) {
                 case PF_ST_INITIAL:
                     switch ($line[0]) {
                         case '/':
                             if ('/' != $line[1]) {
                                 $state = PF_ST_EPARSE;
                                 $message = 'expecting "/", have "' . $line[1] . '"';
                                 break 4;
                             }
                             $line = substr($line, 1);
                             // break missing intentionally
                         // break missing intentionally
                         case '#':
                         case ';':
                             // TBD: Put comments somewhere?
                             break;
                         case 'g':
                             // grant {
                             // grant signedBy "Duke" {
                             // grant signedBy "sysadmin", codeBase "file:/home/sysadmin/" {
                             if ('rant' == substr($line, 1, 4)) {
                                 $state = PF_ST_GRANT;
                                 $end = FALSE;
                                 $t = strtok(substr($line, 5), " \t,");
                                 do {
                                     switch ($t) {
                                         case 'signedBy':
                                             $signer = strtok('"');
                                             break;
                                         case 'codeBase':
                                             $codebase = strtok('"');
                                             break;
                                         case '{':
                                             // End
                                             $end = TRUE;
                                             break 2;
                                         default:
                                             $state = PF_ST_EGRANT;
                                             $message = 'unknown grant token "' . $t . '"';
                                             break 6;
                                     }
                                 } while ($t = strtok(" \t,"));
                                 // OK
                                 if ($end) {
                                     break;
                                 }
                                 $state = PF_ST_EGRANT;
                                 $message = 'expecting {';
                             }
                             break 4;
                         default:
                             $state = PF_ST_EPARSE;
                             $message = 'unexpected input "' . $line . '"';
                             break 4;
                     }
                     break;
                 case PF_ST_GRANT:
                     if (';' != $line[strlen($line) - 1]) {
                         $state = PF_ST_EPARSE;
                         $message = 'permission line not terminated by ";"';
                         break 3;
                     }
                     if ('}' == $line[0]) {
                         $state = PF_ST_INITIAL;
                         break;
                     }
                     // permission java.util.PropertyPermission "java.vendor", "read";
                     // permission java.security.SecurityPermission "Security.insertProvider.*";
                     if (FALSE === ($p = strpos($line, 'permission'))) {
                         $state = PF_ST_EPARSE;
                         $message = 'expecting permission';
                         break 3;
                     }
                     if (FALSE === ($class = strtok(substr($line, $p + 10), " \t;")) || FALSE === ($name = strtok('"'))) {
                         $state = PF_ST_EPERM;
                         $message = 'class and name required but not found';
                         break 3;
                     }
                     try {
                         $permission = XPClass::forName($class);
                     } catch (ClassNotFoundException $e) {
                         $state = PF_ST_EREFLECT;
                         $message = $e->message;
                         break 3;
                     }
                     // Parse actions
                     $actions = array();
                     while ($t = strtok(', ";')) {
                         $actions[] = $t;
                     }
                     // Add permission
                     $policy->addPermission($permission->newInstance($name, $actions));
                     break;
             }
         }
         if (PF_ST_INITIAL != $state) {
             $state = PF_ST_ESTATE;
             $message = 'unterminated section';
         } else {
             $state = PF_ST_DONE;
         }
     } while (PF_ST_BREAK > $state);
     // Close stream
     $stream->close();
     if (PF_ST_DONE == $state) {
         return $policy;
     }
     // Errors
     throw new PolicyException(sprintf("%s in %s on line %d: %s", $errors[$state], $stream->uri, $num, $message));
 }