Sisyphus
: 1 2023 | : 18631 | : 37478554
en ru br
ALT
S:0.6.2.2-alt1
5.1: 0.6.2.1-alt1
www.altlinux.org/Changes

:: //
: alterator-trust

                   Gear   Bugs and FR  Repocop 

alterator-trust-0.6.2.1/000075500000000000000000000000001124300634200150235ustar00rootroot00000000000000alterator-trust-0.6.2.1/Makefile000064400000000000000000000003751124300634200164700ustar00rootroot00000000000000NAME=trust

all:
clean:
install: install-module install-bin install-data

include /usr/share/alterator/build/module.mak

install-bin:
install -d $(bindir)
install -pm755 bin/* $(bindir)

install-data:
install -d $(libexecdir)/alterator/hooks/trust.d
alterator-trust-0.6.2.1/applications/000075500000000000000000000000001124300634200175115ustar00rootroot00000000000000alterator-trust-0.6.2.1/applications/trust.desktop000064400000000000000000000003531124300634200222660ustar00rootroot00000000000000[Desktop Entry]
Type=Application
Categories=X-Alterator-System
Icon=trust
Terminal=false
Name=Trust relationships
X-Alterator-URI=/trust
X-Alterator-Help=trust
X-Alterator-UI=html
Name[ru]=Доверительные отношения
alterator-trust-0.6.2.1/backend3/000075500000000000000000000000001124300634200164755ustar00rootroot00000000000000alterator-trust-0.6.2.1/backend3/trust000075500000000000000000000216571124300634200176170ustar00rootroot00000000000000#!/bin/sh

alterator_api_version=1
. alterator-sh-functions
. shell-signal
. shell-quote

cleanup_function()
{
[ -z "$tmpdir" ] ||
rm -rf -- "$tmpdir"
}

tmpdir="$(mktemp -dt "${0##*/}.XXXXXXXX")"
set_cleanup_handler cleanup_function

authorizedkeys_file=/etc/openssh/authorized_keys/root
known_hosts_file=/var/lib/alterator-trust/known_hosts
real_hosts_file="$tmpdir/real_hosts"
avail_hosts_file="$tmpdir/avail_hosts"

SSH1_RSA_KEY=/etc/openssh/ssh_host_key
SSH2_RSA_KEY=/etc/openssh/ssh_host_rsa_key
SSH2_DSA_KEY=/etc/openssh/ssh_host_dsa_key

ID_DSA_KEY=/var/lib/alterator-trust/id_dsa

fingerprint()
{
local line="$1" && shift
local field="${1:-2}"
local tempfile="$tmpdir/fingerprint"

echo "$line">"$tempfile"
if ssh-keygen -l -f "$tempfile" >/dev/null 2>&1; then
ssh-keygen -l -f "$tempfile" | cut -d ' ' -f "$field"
fi
rm -rf -- "$tempfile"
}

get_host_line()
{
local host="$1"
local file="$2"
local line

line="$(ssh-keygen -F "$host" -f "$file" | grep -v '^#')"
[ -n "$line" ] || return 1
printf '%s' "$line"
}

add_known_host()
{
local host line

host="$(hostinfo -1 -n "$1")" || return 1
line="$(get_host_line "$host" "$real_hosts_file")" || return 3

ssh-keygen -R "$host" -f "$known_hosts_file" 2>/dev/null ||:
printf '%s\n' "$line" >>"$known_hosts_file"
if ! trust-ssh "$host" /bin/true; then
ssh-keygen -R "$host" -f "$known_hosts_file" 2>/dev/null
return 4
fi

run-parts /usr/lib/alterator/hooks/trust.d "$host" add ||:
}

del_known_host()
{
local host line

host="$(hostinfo -1 -n "$1")" || return 1
get_host_line "$host" "$known_hosts_file" >/dev/null 2>&1 || return 3

run-parts /usr/lib/alterator/hooks/trust.d "$host" remove ||:

ssh-keygen -R "$host" -f "$known_hosts_file" 2>/dev/null ||:
}

add_avail_host()
{
local host

host="$(hostinfo -1 -n "$1")" || return 1

grep -qsFx -e "$host" "$avail_hosts_file" 2>/dev/null && return 2 ||:

printf '%s\n' "$host" >>"$avail_hosts_file"
}

txt_record()
{
echo "$2" |
sed -n "s/\(^\|.*[[:space:]]\)\"$(quote_sed_regexp "$1")=\([^\"]*\)\".*/\2/p"
}

refresh_avail_hosts()
{
local __ prefix ip txt role domain
local localdomain="$(hostname -d)"

:>"$avail_hosts_file"
avahi-browse -prtk _server._tcp |
while IFS=';' read prefix __ __ __ __ __ __ ip __ txt; do
[ "$prefix" = "=" ] || continue
role="$(txt_record role "$txt")"
domain="$(txt_record domain "$txt")"
[ "$role" = "slave" ] || continue
[ "$domain" = "$localdomain" ] || continue
add_avail_host "$ip"
done
}

list_hosts()
{
local __ fp host real_fp status msg newkey realkey

:>"$real_hosts_file"
if ssh-keygen -l -f "$known_hosts_file" >/dev/null 2>&1; then
ssh-keygen -l -f "$known_hosts_file" |
sort -t ' ' -k 3 |
while IFS=' ' read -r __ fp host __; do
status="managed"
msg=
newkey=
realkey="$(ssh-keyscan "$host" 2>/dev/null)"
real_fp="$(fingerprint "$realkey")"

if [ -z "$real_fp" ]; then
status="down"
msg="$(_ "Host is down!")"
elif [ "$fp" != "$real_fp" ]; then
status="forged"
msg="$(_ "Key does not match! New key:")"
newkey="$real_fp"
fi
write_table_item \
host "$host" \
url "https://$host:8080/trust/slave" \
status "trust/$status" \
hostkey "$fp" \
message "$msg" \
realkey "$newkey"

ssh-keygen -R "$host" -f "$real_hosts_file" 2>/dev/null
printf '%s\n' "$realkey" >>"$real_hosts_file"
done
fi

sort <"$avail_hosts_file" |
while read -r host; do
get_host_line "$host" "$real_hosts_file" >/dev/null 2>&1 && continue
get_host_line "$host" "$known_hosts_file" >/dev/null 2>&1 && continue

status="available"
msg=
realkey="$(ssh-keyscan "$host" 2>/dev/null)"
real_fp="$(fingerprint "$realkey")"

if [ -z "$real_fp" ]; then
status="down"
msg="$(_ "Host is down!")"
fi
write_table_item \
host "$host" \
url "https://$host:8080/trust/slave" \
status "trust/$status" \
hostkey "$real_fp" \
message "$msg" \
realkey ""

ssh-keygen -R "$host" -f "$real_hosts_file" 2>/dev/null
printf '%s\n' "$realkey" >>"$real_hosts_file"
done
}

parse_authorized_keys()
{
local line="$1" && shift
local opts= keytype= key= comment=

local tempfile="$tmpdir/parse_authorized_keys"
printf '%s\n' "$line" >"$tempfile"
case "$line" in
ssh-*)
IFS=' ' read keytype key comment <"$tempfile"
;;
*)
IFS=' ' read opts keytype key comment <"$tempfile"
;;
esac

case "$1" in
options)
printf '%s' "$opts"
;;
type)
printf '%s' "$keytype"
;;
key)
printf '%s' "$key"
;;
comment)
printf '%s' "$comment"
;;
*)
printf '%s\t%s\t%s\t%s' "$opts" "$keytype" "$key" "$comment"
;;
esac

rm -rf -- "$tempfile"
}

list_ssh_keys()
{
local line comment comment_field

while IFS=' ' read -r line; do
comment="$(parse_authorized_keys "$line" comment)"
case "$comment" in
alterator-trust@*)
write_string_param master_fp "$(fingerprint "$line")"
write_string_param master_comment "$comment"
return
;;
esac
done <"$authorizedkeys_file"

write_string_param master_fp "$(_ "not set")"
write_string_param master_comment "$(_ "not set")"
}

del_ssh_key()
{
local tempfile="$tmpdir/new_authorized_keys"
local comment

while IFS=' ' read -r line; do
comment="$(parse_authorized_keys "$line" comment)"
[ -n "$comment" -a -z "${comment##alterator-trust@*}" ] ||
printf '%s\n' "$line"
done <"$authorizedkeys_file" >"$tempfile"

mv -f -- "$tempfile" "$authorizedkeys_file"
}

add_ssh_key()
{
local new_line="$1" && shift
local new_fp="$(fingerprint "$new_line")"
local keytype key comment

keytype="$(parse_authorized_keys "$new_line" type)"
key="$(parse_authorized_keys "$new_line" key)"
comment="$(parse_authorized_keys "$new_line" comment)"

if [ -z "$new_fp" -o -z "$comment" -o -n "${comment##alterator-trust@*}" ];then
write_error "$(_ "Invalid ssh key")"
return
fi

while IFS=' ' read -r line; do
local fp="$(fingerprint "$line")"
if [ "$fp" = "$new_fp" ];then
write_error "$(_ "Same ssh key already exists")"
return
fi
done <"$authorizedkeys_file"

del_ssh_key

printf 'no-pty %s %s %s\n' "$keytype" "$key" "$comment" >>"$authorizedkeys_file"
}

generate_ssh_host_keys()
{
rm -rf -- \
"$SSH2_RSA_KEY" "$SSH2_RSA_KEY.pub" \
"$SSH2_DSA_KEY" "$SSH2_DSA_KEY.pub" \
"$SSH1_RSA_KEY" "$SSH1_RSA_KEY.pub"
ssh-keygen -q -t rsa -f "$SSH2_RSA_KEY" -C '' -N ''
ssh-keygen -q -t dsa -f "$SSH2_DSA_KEY" -C '' -N ''
ssh-keygen -q -t rsa1 -f "$SSH1_RSA_KEY" -C '' -N ''

service sshd condreload >/dev/null 2>&1
refresh_avail_hosts
}

generate_ssh_key()
{
rm -rf -- \
"$ID_DSA_KEY" "$ID_DSA_KEY.pub"
ssh-keygen -q -t dsa -f "$ID_DSA_KEY" -C "alterator-trust@$HOSTNAME" -N ''
}

trust_strerror()
{
case $1 in
1) printf "%s" "$(_ "unknown host")" ;;
2) printf "%s" "$(_ "already exists")" ;;
3) printf "%s" "$(_ "unable to get host key")" ;;
4) printf "%s" "$(_ "can't connect (missing key?)")" ;;
esac
}

touch "$known_hosts_file"
touch "$avail_hosts_file"

[ -s "$ID_DSA_KEY" ] ||
generate_ssh_key

[ -s "$SSH1_RSA_KEY" -a -s "$SSH2_RSA_KEY" -a -s "$SSH2_DSA_KEY" ] ||
generate_ssh_host_keys

refresh_avail_hosts

on_message()
{
case "$in_action" in
list)
case "$in__objects" in
hosts) list_hosts;;
esac
;;
read)
case "$in__objects" in
master/trust-key.pub)
[ -s "$ID_DSA_KEY.pub" ] &&
write_string_param key "$ID_DSA_KEY.pub"
;;
master)
[ -s "$ID_DSA_KEY.pub" ] &&
write_string_param key_fp "$(ssh-keygen -l -f "$ID_DSA_KEY.pub" | cut -d ' ' -f 2)"
;;
slave)
[ -s "$SSH2_RSA_KEY.pub" ] &&
write_string_param hostkey_fp "$(ssh-keygen -l -f "$SSH2_RSA_KEY.pub" | cut -d ' ' -f 2)"
list_ssh_keys
;;
esac
;;
write)
if [ -n "$in_add_host_to_avail" ]; then
add_avail_host "$in_new_host"
err=$?
[ $err = 0 ] ||
write_error "$(printf "$(_ "Unable to add host %s: %s")" "$in_new_host" "$(trust_strerror $err)")"
elif [ -n "$in_refresh_avail" ]; then
refresh_avail_hosts
elif [ -n "$in_pwn_host" ]; then
(IFS=';'
err_fmt="$(_ "Error adding host(s):%s")"
err_msg=
for i in $in_host; do
[ -n "$i" ] &&
add_known_host "$i"
err=$?
[ $err = 0 ] ||
err_msg="$(printf "%s\n%s - %s" "$err_msg" "$i" "$(trust_strerror $err)")"
done
[ -z "$err_msg" ] ||
write_error "$(printf "$err_fmt" "$err_msg")"
)
elif [ -n "$in_create_ssh_key" ]; then
generate_ssh_key
elif [ -n "$in_create_ssh_hostkey" ]; then
generate_ssh_host_keys
elif [ -n "$in_del_known_host" ]; then
(IFS=';'
err_fmt="$(_ "Error removing host(s):%s")"
err_msg=
for i in $in_host; do
[ -n "$i" ] &&
del_known_host "$i"
err=$?
[ $err = 0 ] ||
err_msg="$(printf "%s\n%s - %s" "$err_msg" "$i" "$(trust_strerror $err)")"
done
[ -z "$err_msg" ] ||
write_error "$(printf "$err_fmt" "$err_msg")"
)
elif [ -n "$in_add_ssh_key" ]; then
add_ssh_key "$in_key_file"
elif [ -n "$in_del_ssh_key" ]; then
del_ssh_key
fi
;;
esac
}

message_loop
alterator-trust-0.6.2.1/bin/000075500000000000000000000000001124300634200155735ustar00rootroot00000000000000alterator-trust-0.6.2.1/bin/trust-list000075500000000000000000000002661124300634200176570ustar00rootroot00000000000000#!/bin/sh

/usr/bin/ssh-keygen -l -f /var/lib/alterator-trust/known_hosts >/dev/null 2>&1 || exit $?
/usr/bin/ssh-keygen -l -f /var/lib/alterator-trust/known_hosts | cut -d ' ' -f 3
alterator-trust-0.6.2.1/bin/trust-scp000075500000000000000000000000741124300634200174660ustar00rootroot00000000000000#!/bin/sh

exec /usr/bin/scp -Bq -S /usr/bin/trust-ssh "$@"
alterator-trust-0.6.2.1/bin/trust-ssh000075500000000000000000000005031124300634200174730ustar00rootroot00000000000000#!/bin/sh

exec /usr/bin/ssh -2akqTxy \
-i /var/lib/alterator-trust/id_dsa \
-F /dev/null \
-o BatchMode=yes \
-o ConnectTimeout=30 \
-o PasswordAuthentication=no \
-o StrictHostKeyChecking=yes \
-o GlobalKnownHostsFile=/var/lib/alterator-trust/known_hosts \
-o UserKnownHostsFile=/dev/null \
-o User=root \
"$@"
alterator-trust-0.6.2.1/design/000075500000000000000000000000001124300634200162745ustar00rootroot00000000000000alterator-trust-0.6.2.1/design/images/000075500000000000000000000000001124300634200175415ustar00rootroot00000000000000alterator-trust-0.6.2.1/design/images/trust/000075500000000000000000000000001124300634200207225ustar00rootroot00000000000000alterator-trust-0.6.2.1/design/images/trust/available.png000064400000000000000000000014371124300634200233550ustar00rootroot00000000000000PNG

IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8ϋU?U=Nvwvsp1EAۂMÜ/K`;$,ы?`ЃDN$_Wzfg3 E.^wg0UP.df7G,Kʲ~(;<5OG7*ug-~K_Sϧ|{ ܖz9; GLDq:;|>WɝLUE5L5AuYkցԖP5=^'g/fƓIbYf)qIr'DL5\DP5L*9YpY4ɉ1cҴѡCLU( %T
s5xZ%"FCh`dȬ<9ULTO I̔~uu kn)tB˗w/ !Sܾ}n8.txE sOyp/3r4X7NTuM53# (4 !iv{{׻U4s󜢕t(Z9WkWSr"ٮ\zCM?SJPQ%t!?yx4G'Tl0|:$)%n;%4S({ ݵ{?y6vVH}yC\\^jPߢ`<@4Z
@ 澜&?ÏW
IENDB`alterator-trust-0.6.2.1/design/images/trust/down.png000064400000000000000000000016101124300634200223750ustar00rootroot00000000000000PNG

IHDRw=sRGBbKGD pHYs  d_tIME 3E>tEXtCommentCreated with The GIMP

(c) 2003 Jakub 'jimmac' Steiner'3XIDATHǵMHa;;ITHuLŒh)"d \ZK-[l.+ "qK&E׾ϝVG2<3Ktv^JbXPPp\0h4湮.uU4RR4Jk:4݌RJjDMJ4-C)R
/WKO@!PB"4 4!ldR"6uL9|Ov(Q~۸44鎁{"hk'04F40Uϴ^hAӴ@Q{G{{G-93dX.e:"yn7'˦L0Mn,v9T. >5) IJ҄m|`ٔ]_M:"4BHlBLEez(*R[}EQ{pOPt|+2Mў^xCoaA>1oN8~Aݷ!-vs>6SeE+J}#UL&"ܾJF>%X[fJ4 fx[Ш(WWR6)A8l0[sG~Xd _yI")ŀ,LU]S{=NܿqWZhD"'X80=ea'а-Ճ>4xIENDB`alterator-trust-0.6.2.1/design/images/trust/forged.png000064400000000000000000000022311124300634200226740ustar00rootroot00000000000000PNG

IHDRw=sRGBbKGD pHYs  d_tIME 6[>tEXtCommentCreated with The GIMP

(c) 2003 Jakub 'jimmac' Steiner'3XIDATHǵ_lU3wvgwB[hmWDF@&>M|l,
OP*ĨI`Pl )tBR-vwvC[6l1f29gp'STBw
ˉDڤ뺺p]WG"mB@A>ނ,hcDZkH A@&@NFd傛ibbj22H1Βɺ@i դJZ(>7ԅ i`߾Tbl_Bk)% KRܯ,0>2O[ehk WΪlp7%'S߅ܪx14Nmd~Ѷ$`V3 BV<Џ_w<(|HSx,0L2cQ!//b3pc1 hlغ {b.@s/K˯'zXam@.Z))8eUU tvb{_dc1T6B̀N4J.vޯ=Nۣ%:wmlduS' }y={XH>ww-Zz#gͨ 2@f[BJ)%RC_/RQjuF=pz m#TWԩɡ!o"NSt/,. >{s_>[0>[PQ
U ;6Tȥ܉ җ/#麹5rFƘ1"?F"cӳilNe/&j5?(.F `}=kXq#ٕe VuaX'q3ӷt8Ne_8<R DKs -ͭs\d+pQ`v[qSZ^ѐ}pxk_֓ryIENDB`alterator-trust-0.6.2.1/design/images/trust/managed.png000064400000000000000000000013511124300634200230240ustar00rootroot00000000000000PNG

IHDRĴl;sBIT|dIDAT8MHTQya-,%MCY"Z}6hQAph,M \ieDPQTjI8hG㿹½s}?NPpod.UAD" nhRhZh>4$JJVk֚0᣾/kZHR%PBz!_H*J~},f|<?Ղ0 I<PScNb`8$IZ[镠t-rebƕPJiX~ݲY*q!Ȇa({//savw2y+5nK|k֬%IcY6!<W/2\c8NL&in!$"rU5iE \>|Ȋ|ミk</@AV/uq*?O\ST:~}IJ8=Ւ|չr<-9y-.?k:TYjdI;{vSa7ldfv#b*پ/cχ!$jlKQ4pjogcdtHbfvB0/cD(C <m;`\5M'aDy@ͶeQswl,&|+VJ,IENDB`alterator-trust-0.6.2.1/ui/000075500000000000000000000000001124300634200154405ustar00rootroot00000000000000alterator-trust-0.6.2.1/ui/trust/000075500000000000000000000000001124300634200166215ustar00rootroot00000000000000alterator-trust-0.6.2.1/ui/trust/ajax.scm000064400000000000000000000004701124300634200202510ustar00rootroot00000000000000(define-module (ui trust ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:export (ui))

(define (module-path)
(if (string=? (woo-get-option (woo-read-first "/net-domain") 'server_role)
"slave")
"/trust/slave"
"/trust/master"))

(define (ui)
(ui-replace (module-path)))
alterator-trust-0.6.2.1/ui/trust/master/000075500000000000000000000000001124300634200201145ustar00rootroot00000000000000alterator-trust-0.6.2.1/ui/trust/master/index.html000064400000000000000000000054611124300634200221170ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html wf="form">
<body>
<form method="POST">
<h2><span translate="_">Master server</span></h2>
<table>
<tr>
<td>
<span translate="_">Host key:</span>
<tt><span class="alterator-label" name="key_fp"/></tt>
</td>
</tr>
<tr>
<td>
<input type="button" class="btn" onClick="document.location.href='/trust/master/trust-key.pub'" value="Download key file"/>
<!--
<input type="submit" name="create_ssh_key" value="Regenerate" class="btn"/>
-->
<br/>
<small><span translate="_">(you should first upload this key to slave servers)</span></small>
</td>
</tr>
</table>
<hr/>
<h2><span translate="_">Slave servers</span></h2>
<table>
<tr>
<td>
<table class="alterator-listbox" enumref="/trust/hosts" style="width:98%">
<thead>
<tr>
<th style="width:1px">&nbsp;</th>
<th><span translate="_">Status</span></th>
<th><span translate="_">Server</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="host"/></td>
<td align="center" valign="center"><img class="alterator-img" name="status"/></td>
<td nowrap="yes">
<a class="alterator-ref2" name="url" encode="no"><span class="alterator-label" name="host"/></a><br/>
<span translate="_">Host key:</span><tt><span class="alterator-label" name="hostkey"/></tt><br/>
<span style="color:red; font-weight:bold;"><span class="alterator-label" name="message"/><tt><span class="alterator-label" name="realkey"/></tt></span>
</td>
</tr>
</tbody>
</table>
</td>
<td>
<table>
<tr>
<td><input type="submit" class="btn" name="pwn_host" value="Manage selected"/></td>
</tr>
<tr>
<td><input type="submit" class="btn" name="del_known_host" value="Delete selected"/></td>
</tr>
<tr>
<td><input type="submit" class="btn" name="refresh_avail" value="Refresh list"/></td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">
<span translate="_">Add host by name:</span>
<input name="new_host" type="text" class="text"/>
<input type="submit" class="btn" name="add_host_to_avail" value="Add"/>
</td>
</tr>
</table>
</form>
</body>
</html>
alterator-trust-0.6.2.1/ui/trust/master/trust-key.pub/000075500000000000000000000000001124300634200226505ustar00rootroot00000000000000alterator-trust-0.6.2.1/ui/trust/master/trust-key.pub/ajax.scm000064400000000000000000000004141124300634200242760ustar00rootroot00000000000000(define-module (ui trust master trust-key.pub ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:export (ui))

(define (ui)
(ui-file "key"
(woo-read-first "/trust/master/trust-key.pub")
"text/plain"
"trust-key.pub"))
alterator-trust-0.6.2.1/ui/trust/slave/000075500000000000000000000000001124300634200177335ustar00rootroot00000000000000alterator-trust-0.6.2.1/ui/trust/slave/index.html000064400000000000000000000031501124300634200217270ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html wf="form">
<body>
<form method="POST" enctype="multipart/form-data">
<h2><span translate="_">Slave server</span></h2>
<table>
<tr>
<td>
<span translate="_">Host key:</span>
<tt><span class="alterator-label" name="hostkey_fp"/></tt>
</td>
</tr>
<!--
<tr>
<td>
<input type="submit" name="create_ssh_hostkey" value="Regenerate" class="btn"/>
</td>
</tr>
-->
</table>
<hr/>
<h2><span translate="_">Master server</span></h2>
<table>
<tr>
<td>
<span translate="_">Key created by:</span>
<span class="alterator-label" name="master_comment"/>
</td>
</tr>
<tr>
<td>
<span translate="_">Master server key:</span>
<tt><span class="alterator-label" name="master_fp"/></tt>
</td>
</tr>
<tr>
<td>
<input type="submit" class="btn" name="del_ssh_key" value="Delete key"/>
</td>
</tr>
<tr>
<td>
<span translate="_">Upload key:</span>
<input name="key_file" type="file" class="btn"/>
<input type="submit" class="btn" name="add_ssh_key" value="Upload"/>
</td>
</tr>
<tr>
<td>
<small><span translate="_">You should first download key from master server.</span></small>
</td>
</tr>
</table>
</form>
</body>
</html>
 
: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
: Michael Shigorin