Some of the more complex interfaces will provide input fields and buttons for the user to configure and control the Network Security Toolkit. This is the highest level of scripting available. In order to accomplish this, your script will need to do the following:
Output the necessary HTML to provide the input fields for the end user.
Determine if the user has already entered values (are we processing a user request). This is optional and only needed if you decide to keep the processing of the form submission within the same script that is used to generate the input form itself.
Provide output regarding the state of the form processing (or state of the machine). In general, there is typically a lot of similar output generated both when presenting the form to the user and processing the user's request.
The
wui/cgi-bin/networking/ntp_query.cgi script
can be used as a simple example of this. It does the
following:
It uses the standard
@bashCgiBegin() macro to generate the
standard start of a HTML document (keeps the pages generated
consistent).
Includes the file
../include/form.sh which contains a set
of helper functions for processing forms. It then invokes
the set_query_options function to parse
out any form parameters which might be present in the
QUERY_STRING. This greatly simplifies life as
we can then simply check to see if the
QUERY_host value has been set instead of
trying to parse the contents of the
QUERY_STRING ourselves.
We then put out information about the page.
If the QUERY_host is set (which happens
once the user presses the submit button to make a request),
we will go ahead and run the command and show the
results. If the QUERY_host variable is not
set, then we omit this output.
Finally, we generate a HTML form to
allow the user to specify a host to make a
NTP query against (so the
QUERY_host will be set if the user presses
the submit button).
The following shows the actual script which does the above:
@bashCgiBegin("$Id: ntp_query.cgi,v 1.18 2008/09/13 16:33:05 rwhalb Exp $","2003-10-22","NTP Time Synchronization (Query/Set)")
#
# ntp_query.cgi
#
# local defines...
@define("exitAnchor","System")
#
# load in standard functions...
. ../include/service.sh;
. ../include/clock.sh;
#
# parse any cgi args...
set_query_options;
#
# exit text...
qrft="${QUERY_return_from:-"NST WUI Index"}";
qrlt="${QUERY_return_label:-"Exit"}"
exit_hover_text="@jsn("${qrlt}") to page: @jsqh("${qrft}")...";
exit_hover_text_len="$(((${#qrft} * @dtm()) + 130))";
#
# hidden forms...
@bashCgiOutBegin()
@comment("--------------------------------------------------------------
Hidden Form: \"returnExit\" - for exiting this script...
-----------------------------------------------------------------------")
@formBegin("${QUERY_return:-"@topDir()/index.cgi#System"}","returnExit")
@wuiInputHidden("synckey","${QUERY_synckey}")
@formEnd()
@bashCgiOutEnd()
#
# update_config
#
# Loads/save configuration information from any previous
# visit - session level save.
update_config() {
#
# Save/restore session ipmitool parameters...
# custom NTP custom URL address...
wui_get_set_config NTP_CUSTOM_URL QUERY_custom_url "pool.ntp.org" session;
# custom last ntptrace setting...
if [ -n "${QUERY_host}" ]; then
QUERY_ntptrace="${QUERY_ntptrace:-""}";
fi
wui_get_set_config NTP_NTPTRACE QUERY_ntptrace "" session;
#
# save configuration...
wui_save_config;
}
#
# Load/save configuration...
update_config;
#
# locate progs...
check_required_program PS ps;
check_required_program SUDO sudo;
check_required_program NTPDATE ntpdate;
check_required_program NTPTRACE ntptrace;
#
# If ntpd is running, we don't want to allow user to set time
NTPD_RUNNING="false";
BUTTON_LABEL="Query/Set Time";
queryDomTT="@jsn("Query")/@jsn("Set")";
queryDomTTWidth="420";
if ${PS} -C ntpd &> /dev/null; then
NTPD_RUNNING=true
BUTTON_LABEL="Query Time"
queryDomTT="@jsn("Query")";
queryDomTTWidth="380";
fi
#
# See if we need to query/set time
if [ "${QUERY_host}" != "" ]; then
#
# If "custom" button selected, change host to value in custom field
if [ "${QUERY_host}" = "custom" ]; then
QUERY_host="${NTP_CUSTOM_URL}"
fi
#
# resolve hostname if not and IP address...
hostIPArray=(); # init array...
hostnameResolved="true"; # init flag...
if (! is_IP4_Addr "${QUERY_host}"); then
# is a hostname...
hostIPArray=($(get_ip_for_host "${QUERY_host}" 2>/dev/null));
if [ $? -ne 0 ]; then
hostnameResolved="false";
fi
else
# is a IPv4 address...
hostIPArray=("${QUERY_host}");
fi
if [ "${hostnameResolved}" = "false" ]; then
@bashCgiOutBegin()
@warningMessage("We were unable to resolve the host name: \"@bold("${QUERY_host}")\"
to and IP address. Correct the host name entry and try again.")
@verticalGap()
@bashCgiOutEnd()
else
#
# how many ip columns to display...
IP_COLUMNS=4;
#
# Show hostname resolution information...
@bashCgiOutBegin()
@nstWUIHeader("hostnameresolve","NTP Server Host Name Resolution")
@p("The selected host name: \"@bold("${QUERY_host}")\" resolves to the following
@bold("IP address(es)"):")
@verticalGapSmall()
<center>
<table@htmlAttr("border","1")
@htmlAttr("width","90%")>
<colgroup>
<col@htmlAttr("width","25%")>
<col@htmlAttr("width","25%")>
<col@htmlAttr("width","25%")>
<col@htmlAttr("width","25%")>
</colgroup>
<tr>
$(for ((i=0; i < IP_COLUMNS; i++)); do echo "<th>NTP Server</th>"; done)
</tr>
@bashCgiOutEnd()
EVENODD="even";
for ((i=0; i < ${#hostIPArray[@]}; i++)); do
if [ "$((i%IP_COLUMNS))" == "0" ]; then
echo "<tr>";
if [ "${EVENODD}" = "even" ]; then
EVENODD=odd;
else
EVENODD=even;
fi
fi
@bashCgiOutBegin()
<td@htmlAttr("class","${EVENODD}")>
@wuiIpWizardLink("${hostIPArray[i]}","${hostIPArray[i]}","${QUERY_return}","@toolTipAttr("@jsn("Click") on the @jsqh("Link") to further @jsn("Inspect") this @jstc("NTP Server","@toolTipEmphasis()"): @jsdh("${hostIPArray[i]}")...","520")")
</td>
@bashCgiOutEnd()
if [ "$((i%IP_COLUMNS+1))" == "${IP_COLUMNS}" ]; then
echo "</tr>"
fi
done
#
# complete columns and row if necessary...
if [ "$((i%IP_COLUMNS))" != "0" ]; then
completeTD="$((IP_COLUMNS - i%IP_COLUMNS))";
for ((i=0; i < completeTD; i++)); do
echo "<td@htmlAttr("class","${EVENODD}")> </td>"
done
echo "</tr>"
fi
@bashCgiOutBegin()
<tr>
$(for ((i=0; i < IP_COLUMNS; i++)); do echo "<th>IP Address</th>"; done)
</tr>
</table>
</center>
@verticalGapSmall()
@p("The first resolved IP address: \"@bold("${hostIPArray[0]}")\" will be used
for the following queries. Results will be available in <u>few</u> moments...")
@bashCgiOutEnd()
#
# See if they check the "set time" box, then go ahead and do
if [ "${QUERY_settime}" = "yes" ]; then
@bashCgiOutBegin()
@nstWUIHeader("ntptimeset","NTP Time Set")
@p("The following shows the <u>results</u> of the attempt to set the @nst()
system's time based on the current time at @acroNTP()
server: \"@bold("${QUERY_host}")\":")
@runCommand("${SUDO} ${NTPDATE} -v ${hostIPArray[0]} 2>&1;")
@verticalGap()
@bashCgiOutEnd()
fi
#
# Display information about the server
@bashCgiOutBegin()
@nstWUIHeader("ntpqueryresult","NTP Query Results")
@p("The following shows the time synchonization difference results by using the
@manPageLink("ntpdate") command to query the time from @acroNTP() host:
\"@bold("${QUERY_host}")\":")
@runCommand("${NTPDATE} -d -q -v ${hostIPArray[0]} 2>&1;")
@bashCgiOutEnd()
#
# see if we need to also do a ntp trace...
if [ "${NTP_NTPTRACE}" = "checked" ]; then
@bashCgiOutBegin()
@verticalGapSmall()
@p("Now perform a @manPageLink("ntptrace") to this NTP server.")
@runCommand("${NTPTRACE} ${hostIPArray[0]} 2>&1;")
@bashCgiOutEnd()
fi
clock_navigation;
fi
else
QUERY_host="pool.ntp.org";
fi
#
# Show area to make next query from
if [ "${NTPD_RUNNING}" = "false" ]; then
@bashCgiOutBegin()
@nstWUIHeader("chkserv","NTP Time Synchronization: "Query/Set"")
@p("Use this form to check the @bold("time synchronization")
<u>difference</u> between an @acroNTP() server and
this @nst() probe's system time. Since the @manPageLink("ntpd","NTP") service
(@manPageLink("ntpd")) is @stress("not") running on this @nst() probe, one may
automatically <u>set</u> the @nst() probe's system time based on the
returned query time value from the selected @acroNTP()
server. Select either
one of the public @acroNTP() server <u>pools</u>
(See the: @appExtRef("NTP Pool Project","http://www.pool.ntp.org/"))
or a <u>specific</u>
@manPageLink("ntpd","NTP") server for time \"@bold("Querying/Setting")\".")
@bashCgiOutEnd()
else
@bashCgiOutBegin()
@nstWUIHeader("chkserv","NTP Time Synchronization: "Query"")
@p("Use this form to check the @bold("time synchronization")
<u>difference</u> between an @acroNTP() server and
this @nst() probe's system time. Select either one of the public
@acroNTP() server <u>pools</u>
(See the: @appExtRef("NTP Pool Project","http://www.pool.ntp.org/"))
or a <u>specific</u> @manPageLink("ntpd","NTP")
server for time \"@bold("Querying")\".")
@bashCgiOutEnd()
fi
@bashCgiOutBegin()
@verticalGapSmall()
<center>
<form@htmlAttr("id","queryformid")
@htmlAttr("action","ntp_query.cgi")>
@wuiInputHidden("action","query")
@wuiInputHidden("return","${QUERY_return}")
@wuiInputHidden("return_from","${QUERY_return_from}")
@wuiInputHidden("return_label","${QUERY_return_label}")
@wuiInputHidden("synckey","${QUERY_synckey}")
<table@htmlAttr("border","1")
@htmlAttr("width","50%")>
<tr@htmlAttr("onmouseover","enterRow(this);")
@htmlAttr("onmouseout","exitRow(this);")>
@bashCgiOutEnd()
EVENODD="even";
even_odd '<td@htmlAttr("align","left")@htmlAttr("class","%s")>\n'
@bashCgiOutBegin()
@wuiInputRadio("host","pool.ntp.org","<span@htmlAttr("class","labeledFieldLabelRight")>On Internet (pool.ntp.org)</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("pool.ntp.org") to ${queryDomTT} the time...","${queryDomTTWidth}")")
<br />
<span@htmlAttr("style","font-size: 80%;")>See: "@appExtRef("NTP Pool Project","http://www.pool.ntp.org/")"</span>
</td>
</tr>
@bashCgiOutEnd()
#
# Dump hosts found in: "/etc/ntp.conf"...
for s in $(/bin/awk -- '$1 == "server" { print $2 };' /etc/ntp.conf); do
even_odd '<tr@htmlAttr("onmouseover","enterRow(this);")
@htmlAttr("onmouseout","exitRow(this);")>
<td@htmlAttr("align","left")@htmlAttr("class","%s")>\n'
@bashCgiOutBegin()
@wuiInputRadio("host","${s}","<span@htmlAttr("class","labeledFieldLabelRight")>${s}</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("${s}") to ${queryDomTT} the time...","${queryDomTTWidth}")")
<br />
<span@htmlAttr("style","font-size: 80%;")>
Server found in: "@bold("@tailLinkEval("/etc/ntp.conf","all","/etc/ntp.conf","../time/ntp_query.cgi",,"ASCII")")"
</span>
</td>
</tr>
@bashCgiOutEnd()
done
#
# If ntpd is running, include probe...
if [ "${NTPD_RUNNING}" = "true" ]; then
even_odd '<tr@htmlAttr("onmouseover","enterRow(this);")
@htmlAttr("onmouseout","exitRow(this);")>
<td@htmlAttr("align","left")@htmlAttr("class","%s")>\n'
@bashCgiOutBegin()
@wuiInputRadio("host","127.0.0.1","<span@htmlAttr("class","labeledFieldLabelRight")>This NST Probe</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("127.0.0.1") to ${queryDomTT} the time...","${queryDomTTWidth}")")
<br />
<span@htmlAttr("style","font-size: 80%;")>
Checks @acroNTP() service on: "@bold("127.0.0.1")"
</span>
</td>
</tr>
@bashCgiOutEnd()
fi
#
# Browser client...
even_odd '<tr@htmlAttr("onmouseover","enterRow(this);")
@htmlAttr("onmouseout","exitRow(this);")>
<td@htmlAttr("align","left")@htmlAttr("class","%s")>\n'
@bashCgiOutBegin()
@wuiInputRadio("host","${REMOTE_ADDR}","<span@htmlAttr("class","labeledFieldLabelRight")>Your System</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("${REMOTE_ADDR}") to ${queryDomTT} the time...","${queryDomTTWidth}")")
<br />
<span@htmlAttr("style","font-size: 80%;")>
Checks @acroNTP() service on: "@bold("${REMOTE_ADDR}")"
</span>
</td>
</tr>
@bashCgiOutEnd()
#
# Custom...
@bashCgiOutBegin()
<tr@htmlAttr("onmouseover","enterRow(this);")
@htmlAttr("onmouseout","exitRow(this);")>
<td@htmlAttr("align","left")
@htmlAttr("class","odd")>
<table@htmlAttr("width","96%")
@htmlAttr("border","0")>
<colgroup>
<col@htmlAttr("width","25%")
@htmlAttr("align","left")>
<col@htmlAttr("width","75%")>
</colgroup>
<tr>
<td>
@wuiInputRadio("host","custom","<span@htmlAttr("class","labeledFieldLabelRight")>Custom</span>","checked","@toolTipAttr("@jsn("Allows") one to @jsn("Specify") the \\'@jstc("IP Address","@toolTipEmphasis()")/@jstc("Host Name","@toolTipEmphasis()")\\' of an @jsdh("NTP") server used to ${queryDomTT} the time...","400")")
</td>
<td>
@wuiInputText("custom_url","${NTP_CUSTOM_URL}","256","40","@toolTipAttr("@jsn("Enter") the \\'@jstc("IP Address","@toolTipEmphasis()")/@jstc("Host Name","@toolTipEmphasis()")\\' of an @jsdh("NTP") server used to ${queryDomTT} the time when the @jsqh("Custom") radio button is @jsn("Selected")...","430")")
</td>
</tr>
</table>
</td>
</tr>
@bashCgiOutEnd()
#
# If ntpd is NOT running, include option to set the probe's time
if [ "${NTPD_RUNNING}" = "false" ]; then
@bashCgiOutBegin()
<tr>
<td@htmlAttr("align","left")
@htmlAttr("class","note")>
<input@toolTipAttr("@jsn("Check") to @jsn("Set") the @jsqh("System Clock") for this @jsdh("NST") probe with the @jsn("Returned") @jsdh("Query Time") value...","400")
@wuiInputCheckboxAttr("settime","yes") /> <span@htmlAttr("class","labeledFieldLabelRight")>Set @bold("System Clock") from returned query time.</span>
</td>
</tr>
@bashCgiOutEnd()
fi
#
# check box to include ntp tracing...
@bashCgiOutBegin()
<tr>
<td@htmlAttr("align","left")
@htmlAttr("class","note")>
<input@toolTipAttr("@jsn("Check") to @jsn("Perform") an @jsqh("ntptrace") to the @jsn("Queried") @jsdh("NTP") server...","410")
@wuiInputCheckboxAttr("ntptrace","checked") ${NTP_NTPTRACE} /> <span@htmlAttr("class","labeledFieldLabelRight")>Perform an @manPageLink("ntptrace").</span>
</td>
</tr>
@bashCgiOutEnd()
#
# Add on submit button and finish up HTML
@bashCgiOutBegin()
</table>
</form>
@verticalGapSmall()
<table@htmlAttr("border","0")>
<tr>
<td>
@wuiButtonSubmit("queryformid","${BUTTON_LABEL}","@toolTipAttr("\\'@jstc("Query","@toolTipEmphasis()")/@jstc("Set","@toolTipEmphasis()")\\' the above @jsn("Selected") @jsdh("NTP") server...","310")")
</td>
<td>
@wuiButtonSubmit("returnExit","${qrlt}","@toolTipAttr("${exit_hover_text}","${exit_hover_text_len}")")
</td>
</tr>
</table>
</center>
@verticalGapSmall()
@bashCgiOutEnd()
#
# Put in custom navigation at end
@define("exitAnchor","")
clock_navigation_section;
@bashCgiEnd()