/** * 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)); }