The SDSI graphical user interface, in `sdsi2ui', uses sdsi2sh's
code as its foundation. What it adds is a collection of Perl 4 scripts
that issue commands to the shell, read its output, and dress it up into
HTML pages that it feeds to the user's Netscape.
These Perl scripts are kept in `tools/sdsi2ui-scripts'. When
sdsi2ui is compiled, they are combined into one large
perl-ready script, which is checked for syntax and then
compressed with gzip. The resulting image is converted into a C
source file defining a string with that image's contents. sdsi2sh
is then compiled with `-DSDSI2UI', which, among other things, makes
it #include that C source file.
When run, sdsi2ui invokes perl and connects to its standard
input and output. After feeding perl the monster script through
a `gzip -cd', the sdsi2sh heart of sdsi2ui just waits
for the Perl scripts to print commands for it on its standard output.
The results are made available to the scripts on their standard input.
The "root" of the sdsi2ui scripts is `main.pl'. This script
is responsible for requireing the other scripts, creating the
secure directory from which the user's pages will be served,
starting its HTTP server, and kicking off the page generation and
the user's browser. You probably shouldn't touch this file,
`network.pl', or `pages.pl'.
To add support for browsers other than Netscape, change
`browser.pl'. The idea is that at the top of the
browser_start subroutine, you decide on the browser to use and
put a name for it in $user_browser_name. The remainder of that
subroutine is a big if...else, branching on that name, that
gets that browser to display $first_page, a URL for the first
page. The subroutine browser_still_running should return nonzero
if, when called, that browser is still running.
All of the remaining files have functions that create HTML pages, accept POST
input, and interact with the sdsi2sh heart. For page generation,
any subroutine that ends in _generate that is defined at start time
is automatically called with the filehandle PAGE open to a file for accepting
its content. The base name of the file is the name of that generating subroutine,
less the _generate, with remaining underscores changed to parentheses,
and `.html' tacked on the end.
For example, the subroutine new_pubkey_name_generate is called
with PAGE opened for writing a file in the secure directory with
the base name `new-pubkey-name.html'. HTML links can be forged
between pages by knowing that the filenames for other pages will be
similarly named.
The HTML pages generated by the GUI should use POST forms for
soliciting user input. The names of the methods used in the pages must
match Perl subroutines that will accept the values from the form, and
all forms must include a hidden value named cookie. The value of
cookie is used by the HTTP server in `main.pl' to
authenticate an HTTP POST as being from the user's Web browser,
as opposed to anyone else's.
For example, the HTML generated by the new_pubkey_name_generate
subroutine includes:
<form action=$server_url_base/new-pubkey-name method=post> <input type=hidden name=cookie value=$session_cookie> What do you want to name that public key?<br> <input type=text name=the-name maxlen=40>
followed by more HTML defining the rest of the form.
The POST data will be fed back to a subroutine called
new_pubkey_name_post. These _post subroutines
are always called with an associative array as the argument
list. The keys of the array are the variable names used in
the POST form. For example, in:
# accepts a new-pubkey-name POST:
sub new_pubkey_name_post {
local(%params) = @_;
$params{'cookie'} is the value of the cookie,
$params{'the-name'} is the value the user entered for the HTML
form's the-name variable, etc. All values have already been decoded.
Some functions in main.pl are available for helping these
_post functions for further checking their variable values.
&main_check_parameters takes a single string, which has
newline-separated records. A record consists of a variable's name, a
colon, and the Perl regular expression that the variable's value must
match. &main_check_parameters returns undef if everything
is okay, or the name of a variable whose value isn't acceptable.
new_pubkey_name_post uses this to check its variables:
# make sure that we have all of our parameters, and they look valid:
if ($_ = &main_check_parameters(<<'EOF', %params)) {
pk-type:page|file
pk-where:[\w\-\.\/:]+
the-name:
not-before:now|specified
not-before-date:\d{4}-\d\d-\d\d_\d\d:\d\d:\d\d
not-after:never|specified
not-after-date:\d{4}-\d\d-\d\d_\d\d:\d\d:\d\d
EOF
# FIXME - can do better than just saying this:
&main_return_error_page("Malformed CGI invocation - value for ${_}, $params{$_}, looked bad");
return;
}
A function main_sh_define is available to define a sdsi2sh variable
with a value. It takes two strings: the name of the variable followed by its value.
If the definition fails (say, if the value is a cert object that doesn't
parse), this function returns a ::-separated set of pairs of the major error
code and its text, the minor error code and its text, and the error locus and its
text.
A function main_sh_get returns a shell variable's current value.
It takes the name of the variable as its argument.
main_sh_commands can run a series of commands (none of them can
be defines). It takes the commands as a newline-separated
string, and returns a list. The first value of the list is undef
if no errors were encountered. The remaining values are the return
values from the commands.
Go to the first, previous, next, last section, table of contents.