Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37542700
en ru br
Репозитории ALT
S:0.5.8-alt1
5.1: 0.5.3-alt1
www.altlinux.org/Changes

Группа :: Система/Основа
Пакет: alterator-ca

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

alterator-ca-0.5.4/000075500000000000000000000000001130311212100140555ustar00rootroot00000000000000alterator-ca-0.5.4/Makefile000064400000000000000000000005551130311212100155220ustar00rootroot00000000000000NAME=ca

all:
clean:
install: install-module install-sbin install-data

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

install-sbin:
install -d $(bindir)
install -d $(sbindir)
install -pm644 bin/ca-sh-functions $(bindir)
install -pm755 bin/ca-sko $(sbindir)

install-data:
install -d $(datadir)/alterator-ca
install -pm644 data/CA.cnf $(datadir)/alterator-ca
alterator-ca-0.5.4/alterator000077700000000000000000000000001130311212100211452interfaces/guileustar00rootroot00000000000000alterator-ca-0.5.4/applications/000075500000000000000000000000001130311212100165435ustar00rootroot00000000000000alterator-ca-0.5.4/applications/ca.desktop000064400000000000000000000003401130311212100205160ustar00rootroot00000000000000[Desktop Entry]
Type=Application
Categories=X-Alterator-System
Terminal=false
Name=Certification Authority
Icon=ca
X-Alterator-URI=/ca
X-Alterator-Help=ca
X-Alterator-UI=html
Name[ru]=пёп╢п╬я│я┌п╬п╡п╣я─я▐я▌я┴п╦п╧ п╕п╣п╫я┌я─
alterator-ca-0.5.4/backend3/000075500000000000000000000000001130311212100155275ustar00rootroot00000000000000alterator-ca-0.5.4/backend3/ca000075500000000000000000000166601130311212100160510ustar00rootroot00000000000000#!/bin/sh -f

alterator_api_version=1
po_domain="alterator-ca"

. alterator-sh-functions
. avahi-sh-functions
. shell-config
. shell-signal

cleanup_function()
{
[ -z "$tmpdir" ] ||
rm -rf -- "$tmpdir"
}
tmpdir="$(mktemp -dt "${0##*/}.XXXXXXXX")"
set_cleanup_handler cleanup_function

conffile="/etc/alterator-ca/dnparam.txt"
autoupdate_file="/etc/cron.d/alterator-ca"
update_cmd="ca-sko update"

export CA_VERBOSE=1

filter_localhost()
{
[ -n "$1" -a "$1" != "localhost" ]
}

do_all_keys()
{
local IFS=';'
local cmd="$1"

for i in $in_key_name; do
ca-sko "$cmd" "$in_hostname" "$i"
done
}

do_all_hosts()
{
local IFS=';'
local cmd="$1"
local filter="${2:-:}"

for i in $in_name; do
"$filter" "$i" || continue
ca-sko "$cmd" "$i"
done
}

write_autoupdate()
{
if ! test_bool "$in_autoupdate"; then
rm -f "$autoupdate_file"
return
fi

in_time="${in_time%:*}"
local hour="${in_time%:*}"
local min="${in_time#*:}"

local tmpfile="$(mktemp "$autoupdate_file.XXXXXXXXXX")"

printf '#autogenerated by alterator-ca\n' >"$tmpfile"
printf 'SHELL=/bin/sh\n' >> "$tmpfile"
printf 'PATH=/sbin:/usr/sbin:/bin:/usr/bin\n' >> "$tmpfile"
printf 'CA_VERBOSE=1\n\n' >> "$tmpfile"
printf '%s %s * * * root %s\n' "$min" "$hour" "$update_cmd" >> "$tmpfile"

mv -f "$tmpfile" "$autoupdate_file"
}

read_autoupdate()
{
if [ -s "$autoupdate_file" ]; then
while read min hour monthday month weekday rest; do
[ -n "$min" ] || continue
[ -n "${min%%\#*}" ] || continue
[ -n "${min##*=*}" ] || continue
write_string_param time "$hour:$min:00"
write_bool_param autoupdate true
return
done < "$autoupdate_file"
fi
write_string_param time "02:00:00"
write_bool_param autoupdate false
}

on_message() {
case "$in_action" in
type)
case "$in__objects" in
root)
write_type_item C iso-3166-alpha-2
write_type_item O ca-cert-field
;;
esac
;;
list)
case "$in__objects" in
avail_hosts)
trust-list | write_enum
;;
host)
if [ -n "$in_hostname" ]; then
ca-sko show "$in_hostname" |
while IFS=' ' read key issued expires subject __ __ __ status; do
name="${key##*/}"
name="${name%.cert}"
status="${status#*:}"

write_table_item \
key_name "$name" \
name "$name" \
issued "$issued" \
expires "$expires" \
subject "$subject" \
status "$status"
done
fi
;;
certs)
write_table_item \
name localhost \
hostname "$(_ "Local certificates")"
ca-sko hosts |
while read host; do
write_table_item \
name "$host" \
hostname "$host"
done
;;
esac
;;
read)
case "$in__objects" in
download)
file="$(ca-sko status | cut -d ' ' -f 1)"

if [ -z "$file" ]; then
write_error "$(_ "CA not initialized")"
return
fi
case "$in_file" in
ca-root.pem)
write_blob_param "file" "$file"
;;
ca-root.csr)
write_blob_param "file" "${file%.pem}.csr"
;;
output.pem)
if [ ! -s "$tmpdir/output.csr" ]; then
write_error "$(_ "Missing sign request")"
return
fi
ca-sko signfile "$tmpdir/output.csr" "$tmpdir/output.pem"
if [ ! -s "$tmpdir/output.pem" ]; then
write_error "$(_ "Unable to sign request")"
return
fi
write_blob_param "file" "$tmpdir/output.pem"
rm -f "$tmpdir/output.csr"
;;
esac
;;
host)
case "$in_hostname" in
localhost)
write_string_param displayname "$(_ "Local")"
;;
*)
write_string_param displayname "$in_hostname"
;;
esac
write_string_param hostname "$in_hostname"
;;
certs)
read_autoupdate
if [ -s "$tmpdir/output.txt" ]; then
write_bool_param can_has_sign true
write_string_param sign_request "$(cat "$tmpdir/output.txt")"
else
write_bool_param can_has_sign false
fi
;;
root)
write_string_param C "$(shell_config_get "$conffile" "C")"
write_string_param O "$(shell_config_get "$conffile" "O")"

ret=0
status="$(ca-sko status)"
ret=$?

[ $ret != 1 ] &&
write_bool_param is_active true ||
write_bool_param is_active false

[ $ret != 1 ] || return

startdate="$(printf '%s' "$status" | cut -d ' ' -f 2)"
enddate="$(printf '%s' "$status" | cut -d ' ' -f 3)"
subj="$(printf '%s' "$status" | cut -d ' ' -f 4)"
issuer="$(printf '%s' "$status" | cut -d ' ' -f 5)"
sha1fp="$(printf '%s' "$status" | cut -d ' ' -f 6)"
md5fp="$(printf '%s' "$status" | cut -d ' ' -f 7)"
status="$(printf '%s' "$status" | cut -d ' ' -f 8)"
status="${status#*:}"

printf '%s/' "$subj" |
while read -d/ line; do
[ -n "$line" ] || continue
name="${line%%=*}"
value="${line#*=}"

write_string_param "subject_$name" "$value"
done

printf '%s/' "$issuer" |
while read -d/ line; do
[ -n "$line" ] || continue
name="${line%%=*}"
value="${line#*=}"

write_string_param "issuer_$name" "$value"
done

write_string_param startdate "$startdate"
write_string_param enddate "$enddate"

write_string_param sha1fp "$sha1fp"
write_string_param md5fp "$md5fp"
write_string_param status "$status"
;;
esac
;;
write)
if [ -n "$in_new_host" -a -n "$in_new_name" ]; then
ret=0
status="$(ca-sko addhost "$in_new_name" 2>&1 >/dev/null)"
ret=$?

echo "$status" >&2
[ $ret = 0 ] ||
write_error "$status"
elif [ -n "$in_del_host" -a -n "$in_name" ]; then
do_all_hosts delhost filter_localhost
elif [ -n "$in_update_host" -a -n "$in_name" ]; then
do_all_hosts update
elif [ -n "$in_import_host" -a -n "$in_name" ]; then
do_all_hosts import
elif [ -n "$in_sign_host" -a -n "$in_name" ]; then
do_all_hosts sign
elif [ -n "$in_export_host" -a -n "$in_name" ]; then
do_all_hosts export
elif [ -n "$in_sign_key" -a -n "$in_hostname" -a -n "$in_key_name" ]; then
do_all_keys signkey
elif [ -n "$in_apply_autoupdate" ]; then
write_autoupdate
#elif [ -n "" ]; then
# :
fi
;;
create)
if [ -z "$in_C" -a -z "$in_O" ]; then
write_error "$(_ "Country and Organizaton must be defined")"
return
fi
if [ -z "$in_O" ]; then
write_error "$(_ "Organizaton must be defined")"
return
fi
if [ -z "$in_C" ]; then
write_error "$(_ "Country must be defined")"
return
fi
if ca-sko status >/dev/null 2>&1; then
if test_bool "$in_confirm"; then
ca-sko drop
else
write_error "$(_ "CA already initialized")"
return
fi
fi
shell_config_set "$conffile" "C" "$in_C"
shell_config_set "$conffile" "O" "$in_O"
ret=0
status="$(ca-sko init 2>&1 >/dev/null)"
ret=$?
if [ $ret = 0 ]; then
file="$(ca-sko status | cut -d ' ' -f 1)"
if [ -d /srv/public -a -f "$file" ]; then
cp -f -- "$file" /srv/public/ca-root.pem
publish_service alterator-ca "$in_O Root CA (%h)" '_ca-root._tcp' 0 "path=/ca-root.pem"
fi
else
write_error "$status"
fi
;;
upload)
mv -f "$in_request" "$tmpdir/output.csr"

[ -s "$tmpdir/output.csr" ] &&
openssl req -text -noout -in "$tmpdir/output.csr" -out "$tmpdir/output.txt"

if [ ! -s "$tmpdir/output.txt" ]; then
rm -f "$tmpdir/output.csr"
rm -f "$tmpdir/output.txt"
write_error "$(_ "Invalid sign request")"
fi
;;
esac
}

message_loop
# vim:ts=4:
alterator-ca-0.5.4/bin/000075500000000000000000000000001130311212100146255ustar00rootroot00000000000000alterator-ca-0.5.4/bin/ca-sh-functions000064400000000000000000000146661130311212100175660ustar00rootroot00000000000000#!/bin/sh

. cert-sh-functions
. shell-config

CA_VERBOSE="${CA_VERBOSE:-}"
CA_SKO_ROOT="${CA_SKO_ROOT:-/var/lib/alterator-ca}"
CA_SKO_CADIR="${CA_SKO_CADIR:-$CA_SKO_ROOT/CA}"
CA_SKO_CONFIG="${CA_SKO_CONFIG:-/usr/share/alterator-ca/CA.cnf}"
CA_SKO_DNPARAM="${CA_SKO_DNPARAM:-/etc/alterator-ca/dnparam.txt}"

#CA infrastructure

ca_check_CAdir()
{
[ -d "$CA_SKO_CADIR" -a -d "$CA_SKO_CADIR/private" ]
}

ca_make_CAdir()
{
ca_check_CAdir && return

mkdir -m700 -p "$CA_SKO_CADIR"
mkdir -m700 -p "$CA_SKO_CADIR/certs"
mkdir -m700 -p "$CA_SKO_CADIR/private"
mkdir -m700 -p "$CA_SKO_CADIR/newcerts"

touch "$CA_SKO_CADIR/index.txt"
chmod 600 "$CA_SKO_CADIR/index.txt"

echo 01 > "$CA_SKO_CADIR/serial"
chmod 600 "$CA_SKO_CADIR/serial"
}

ca_get_subject()
{
local C O

C="$(shell_config_get "$CA_SKO_DNPARAM" "C")"
C="${C:-RU}"
O="$(shell_config_get "$CA_SKO_DNPARAM" "O")"
O="${O:-Snake Oil, Ltd.}"
printf "/C=%s/O=%s/OU=%s Certification Authority/CN=%s Root Certification Authority" "$C" "$O" "$O" "$O"
}

#CA private key

ca_check_CAkey()
{
[ -f "$CA_SKO_CADIR/private/cakey.pem" ]
}

ca_make_CAkey()
{
ca_check_CAkey && return

"$OPENSSL" genrsa -out "$CA_SKO_CADIR/private/cakey.pem" 1024 >/dev/null 2>&1 ||
ssl_fatal "Unable to create CA private key"
}

#CA itself

ca_check_CA()
{
[ -f "$CA_SKO_CADIR/cacert.pem" ] || return 1

subject="$(ca_get_cert_attr "$CA_SKO_CADIR/cacert.pem" subject)"
ca_subject="$(ca_get_subject)"

[ "$subject" = "$ca_subject" ]
}

ca_make_CA()
{
ca_check_CA && return

subject="$(ca_get_subject)"

"$OPENSSL" req -batch -new -key "$CA_SKO_CADIR/private/cakey.pem" -out "$CA_SKO_CADIR/cacert.csr" -subj "$subject" >/dev/null 2>&1 ||
ssl_fatal "Unable to create sign request"
"$OPENSSL" ca -batch -config "$CA_SKO_CONFIG" -selfsign -days 3650 -extensions v3_ca -extfile /etc/openssl/openssl.cnf -keyfile "$CA_SKO_CADIR/private/cakey.pem" -in "$CA_SKO_CADIR/cacert.csr" -out "$CA_SKO_CADIR/cacert.pem" -subj "$subject" >/dev/null 2>&1 ||
ssl_fatal "Unable to create CA certificate"

printf '%s\n' "$subject" >> "$CA_SKO_ROOT/ca_history.txt"
# validating newly-created certificate may yeld "not yet valid"
sleep 1
}

ca_export_CAcert()
{
[ -n "$1" ] ||
ssl_fatal 'Insufficient arguments'

cat "$CA_SKO_CADIR/cacert.pem" > "$SSL_CERTDIR/$1.pem"
c_rehash "$SSL_CERTDIR" >/dev/null 2>&1
}

ca_update_db()
{
"$OPENSSL" ca -batch -config "$CA_SKO_CONFIG" -updatedb 2>/dev/null ||:
}

#CA sign

ca_check_req()
{
[ -n "$1" -a -n "$2" ] ||
ssl_fatal 'Insufficient arguments'
[ -f "$1" ] ||
ssl_fatal 'Missing sign request'
[ ! -f "$2" -o "$1" -nt "$2" ] ||
ssl_fatal "Certificate is newer than sign request"
}

ca_sign_req2()
{
[ -n "$1" -a -n "$2" ] ||
ssl_fatal 'Insufficient arguments'

"$OPENSSL" ca -batch -config "$CA_SKO_CONFIG" -out "$2" -in "$1" -notext >/dev/null 2>&1 ||
ssl_fatal "Unable to sign certificate"
}

ca_sign_req()
{
[ -n "$1" ] ||
ssl_fatal 'Insufficient arguments.'

ssl_check_req "$1" ||
ssl_fatal 'Missing sign request'

ca_sign_req2 "$SSL_CSRDIR/$1.csr" "$SSL_CERTDIR/$1.cert"

ln -sf "$1.cert" "$SSL_CERTDIR/$1.pem"
c_rehash "$SSL_CERTDIR" > /dev/null

ssl_make_pem "$1"
}

#CA attributes

ca_get_cert_attr()
{
local file param

[ -n "$1" -a -n "$2" ] ||
ssl_fatal 'Insufficient arguments'

file="$1" && shift
param="$1" && shift
"$OPENSSL" x509 -in "$file" -noout "-$param" "$@" 2>/dev/null | cut -d= -f 2- | sed 's,\(^[[:blank:]]\+\|[[:blank:]]\+$\),,g'
}

#CA check

ca_needs_resign()
{
local code="$1"

[ "$code" = "1" -o "$code" = "3" -o "$code" = "4" -o "$code" = "6" ] &&
return 0
return 1
}

# 0 - OK
# 1 - invalid
# 2 - not yet valid
# 3 - expired
# 4 - will expire in 10 days
# 5 - issuer does not match CA
# 6 - self-signed certificate
ca_check_cert2()
{
local startdate enddate curdate subject issuer ca_subject ca_issuer

[ -n "$1" ] ||
ssl_fatal 'Insufficient arguments.'

[ -s "$1" ] ||
return 1

startdate="$(ca_get_cert_attr "$1" startdate)" ||
return 1
enddate="$(ca_get_cert_attr "$1" enddate)" ||
return 1
subject="$(ca_get_cert_attr "$1" subject)" ||
return 1
issuer="$(ca_get_cert_attr "$1" issuer)" ||
return 1
ca_subject="$(ca_get_cert_attr "$CA_SKO_CADIR/cacert.pem" subject)" ||
return 1
ca_issuer="$(ca_get_subject)"

if [ "$issuer" = "$ca_subject" ]; then
# local CA itself or signed by local CA
if [ "$subject" = "$issuer" -a "$issuer" != "$ca_issuer" ]; then
# outdated local CA
return 1
fi
else
if [ "$subject" = "$issuer" ]; then
# self-signed
return 6
else
if grep -qsFx -e "$ca_subject" "$CA_SKO_ROOT/ca_history.txt" 2>/dev/null; then
# old local
[ "$issuer" = "$ca_issuer" ] ||
return 1
else
# foreign trusted
return 5
fi
fi
fi

startdate="$(date -d "$startdate" +%s)"
enddate="$(date -d "$enddate" +%s)"
curdate="$(date +%s)"
[ -n "$startdate" -a -n "$enddate" -a -n "$curdate" ] ||
return 1

[ "$curdate" -gt "$startdate" ] ||
return 2
[ "$curdate" -lt "$enddate" ] ||
return 3
"$OPENSSL" x509 -in "$1" -checkend 864000 > /dev/null||
return 4

"$OPENSSL" verify -CAfile "$CA_SKO_CADIR/cacert.pem" "$1" >/dev/null 2>&1 ||
return 1
}

ca_status_message()
{
[ -n "$1" ] ||
ssl_fatal 'Insufficient arguments.'

case "$1" in
0) printf 'OK\n';;
1) printf 'invalid\n';;
2) printf 'not yet valid\n';;
3) printf 'expired\n';;
4) printf 'will expire in 10 or less days\n';;
5) printf 'issuer does not match CA\n';;
6) printf 'self-signed certificate\n';;
*) printf 'unknown error';;
esac
}

ca_check_cert()
{
local ret

[ -n "$1" ] ||
ssl_fatal 'Insufficient arguments.'

ret=0
ca_check_cert2 "$@" || ret=$?

printf '%s: %s\n' "$1" "$(ca_status_message "$ret")"

return $ret
}

#CA info

ca_show_cert()
{
local startdate enddate sha1fp md5fp subj issuer retcode status

[ -n "$1" ] ||
ssl_fatal 'Insufficient arguments'
[ -f "$1" ] ||
ssl_fatal 'Missing certificate'

startdate="$(ca_get_cert_attr "$1" startdate)"
enddate="$(ca_get_cert_attr "$1" enddate)"
sha1fp="$(ca_get_cert_attr "$1" fingerprint)"
md5fp="$(ca_get_cert_attr "$1" fingerprint -md5)"
subj="$(ca_get_cert_attr "$1" subject)"
issuer="$(ca_get_cert_attr "$1" issuer)"

retcode=0
ca_check_cert2 "$@" || retcode=$?
status="$(ca_status_message "$retcode")"

if [ -z "$CA_VERBOSE" ]; then
printf '%s\t%s\t%s\t%s\n' "${1##*/}" "$enddate" "$subj" "$status"
else
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%d:%s\n' "$1" "$startdate" "$enddate" "$subj" "$issuer" "$sha1fp" "$md5fp" "$retcode" "$status"
fi
}


# vim: set ts=4:
alterator-ca-0.5.4/bin/ca-sko000075500000000000000000000126361130311212100157400ustar00rootroot00000000000000#!/bin/sh -f

. cert-sh-functions
. ca-sh-functions

CA_SKO_INDIR="${CA_SKO_INDIR:-$CA_SKO_ROOT/in}"
CA_SKO_OUTDIR="${CA_SKO_OUTDIR:-$CA_SKO_ROOT/out}"

host_csr_dir()
{
[ -n "$1" -a "$1" != "localhost" ] &&
printf '%s/%s' "$CA_SKO_INDIR" "$1" ||
printf '%s' "$SSL_CSRDIR"
}

host_cert_dir()
{
[ -n "$1" -a "$1" != "localhost" ] &&
printf '%s/%s' "$CA_SKO_OUTDIR" "$1" ||
printf '%s' "$SSL_CERTDIR"
}

import_keys()
{
local csr_dir cert_dir

[ -n "$1" -a "$1" != "localhost" ] ||
return 0

csr_dir="$(host_csr_dir "$1")"
cert_dir="$(host_cert_dir "$1")"

rsync -qaH -e trust-ssh --delete-after --include='*.csr' --exclude='*' "$1:$SSL_CSRDIR/" "$csr_dir/" &&
rsync -qaH -e trust-ssh --delete-after --include='*.cert' --include='*.pem' --exclude='*' "$1:$SSL_CERTDIR/" "$cert_dir/"
}

find_files()
{
[ -n "$1" -a -n "$2" -a -n "$3" ] ||
return 1

find "$1" -mindepth 1 -maxdepth 1 -type "$3" -name "$2" -printf '%P\n'
}

show_keys()
{
local SSL_CERTDIR="$(host_cert_dir "$@")"

[ -d "$SSL_CERTDIR" ] ||
return 1

find_files "$SSL_CERTDIR" '*.cert' f |
while IFS= read cert; do
[ -f "$SSL_CSRDIR/${cert%.cert}.csr" ] ||
continue
ca_show_cert "$SSL_CERTDIR/$cert"
done
}

forcesign_key()
{
local host="${1:-localhost}"
local SSL_CSRDIR="$(host_csr_dir "$host")"
local SSL_CERTDIR="$(host_cert_dir "$host")"
local ret base req cert status

[ -d "$SSL_CSRDIR" ] ||
return 1

base="$2"
req="$base.csr"
cert="$base.cert"

[ -f "$SSL_CERTDIR/$req" ] ||
return 1

[ -z "$CA_VERBOSE" ] ||
printf '%s:%s: resigned\n' "$host" "$cert"
ca_sign_req "$base"
}

sign_key()
{
local host="${1:-localhost}"
local SSL_CSRDIR="$(host_csr_dir "$host")"
local SSL_CERTDIR="$(host_cert_dir "$host")"
local ret base req cert status

[ -d "$SSL_CSRDIR" ] ||
return 1

base="$2"
req="$base.csr"
cert="$base.cert"

[ -f "$SSL_CERTDIR/$req" ] ||
return 1

ret=0
ca_check_cert2 "$SSL_CERTDIR/$cert" || ret=$?

status=
if [ "$SSL_CSRDIR/$req" -nt "$SSL_CERTDIR/$cert" ]; then
status="new sign request found"
elif ca_needs_resign "$ret"; then
status="$(ca_status_message "$ret")"
fi

if [ -n "$status" ]; then
[ -z "$CA_VERBOSE" ] ||
printf '%s:%s: %s, resigned\n' "$host" "$cert" "$status"
ca_sign_req "$base"
fi
}

sign_keys()
{
local host="${1:-localhost}"
local SSL_CSRDIR="$(host_csr_dir "$host")"
local SSL_CERTDIR="$(host_cert_dir "$host")"

[ -d "$SSL_CSRDIR" ] ||
return 1

find_files "$SSL_CSRDIR" '*.csr' f |
while IFS= read req; do
local base

base="${req%.csr}"
sign_key "$host" "$base"
done
ca_export_CAcert ca-root
}

export_keys()
{
local csr_dir cert_dir

if [ -z "$1" -o "$1" = "localhost" ]; then
c_rehash "$SSL_CERTDIR" >/dev/null
return 0
fi

csr_dir="$(host_csr_dir "$1")"
cert_dir="$(host_cert_dir "$1")"

rsync -qaH -e trust-ssh --include='*.csr' --exclude='*' "$csr_dir/" "$1:$SSL_CSRDIR/" &&
rsync -qaH -e trust-ssh --include='*.cert' --include='*.pem' --exclude='*' "$cert_dir/" "$1:$SSL_CSRDIR/" &&
trust-ssh "$1" c_rehash "$SSL_CERTDIR" >/dev/null
}

update_host()
{
import_keys "$@" &&
sign_keys "$@" &&
export_keys "$@"
}

each_host()
{
local function list

function="$1" && shift
list=

if [ "$#" -gt 0 ]; then
while [ "$#" -gt 0 ]; do
list="${list:+$list
}$1" && shift
done
else
list="localhost
$(find_files "$CA_SKO_INDIR" '*' d)"
fi

printf '%s\n' "$list" |
while IFS= read host; do
"$function" "$host" ||
printf '%s: Update failed.\n' "$host"
done
}

cmd="$1" && shift

case "$cmd" in
init)
ca_make_CAdir
ca_make_CAkey
ca_make_CA
ca_export_CAcert ca-root
exit $?
;;
status)
ca_check_CA ||
exit $?
cert="$CA_SKO_CADIR/cacert.pem"
ca_show_cert "$cert"
ca_check_cert2 "$cert"
exit $?
;;
*)
ca_check_CAdir >/dev/null 2>&1 &&
ca_check_CAkey >/dev/null 2>&1 &&
ca_check_CA >/dev/null 2>&1 ||
ssl_fatal "CA not initialized"

ret=0
ca_check_cert2 "$CA_SKO_CADIR/cacert.pem" >/dev/null 2>&1 ||
ret=$?

if [ $ret != 0 ]; then
if ca_needs_resign "$ret"; then
ca_make_CA
else
ssl_fatal "$(ca_status_message "$ret")"
fi
fi
;;
esac

ca_update_db

rc=0
case "$cmd" in
drop)
rm -rf "$CA_SKO_CADIR" ||: 2>/dev/null
;;
addhost)
[ -n "$1" -a "$1" != "localhost" ] ||
ssl_fatal "lolwhut?"

host="$1"

[ -d "$CA_SKO_INDIR/$host" ] || mkdir -p "$CA_SKO_INDIR/$host"
[ -d "$CA_SKO_OUTDIR/$host" ] || mkdir -p "$CA_SKO_OUTDIR/$host"

printf 'Added host:\n%s\n' "$hostkey"

rc=$?
;;
delhost)
[ -n "$1" -a "$1" != "localhost" ] ||
ssl_fatal "lolwhut?"

host="$1"

rm -rf "$CA_SKO_INDIR/$host"
rm -rf "$CA_SKO_OUTDIR/$host"
rc=$?
;;
update)
each_host update_host "$@"
rc=$?
;;
import)
each_host import_keys "$@"
rc=$?
;;
sign)
each_host sign_keys "$@"
rc=$?
;;
export)
each_host export_keys "$@"
rc=$?
;;
show)
show_keys "$@"
rc=$?
;;
hosts)
find_files "$CA_SKO_INDIR" '*' d
rc=$?
;;
signkey)
case "$#" in
2)
host="$1"
key="$2"
;;
1)
host="localhost"
key="$1"
;;
*)
ssl_fatal "Usage: ${0##*/} sign [HOST] NAME"
;;
esac
sign_key "$host" "$key"
rc=$?
;;
signfile)
case "$#" in
2)
ca_sign_req2 "$1" "$2"
rc=$?
;;
*)
ssl_fatal "Usage: ${0##*/} sign REQUEST CERTIFICATE"
;;
esac
;;
check)
[ -n "$1" ] ||
ssl_fatal "Usage: ${0##*/} check CERTIFICATE"

ca_check_cert "$1"
rc=$?
;;
*)
ssl_fatal "Invalid command: $cmd"
;;
esac

exit $rc
# vim: set ts=4:
alterator-ca-0.5.4/data/000075500000000000000000000000001130311212100147665ustar00rootroot00000000000000alterator-ca-0.5.4/data/CA.cnf000064400000000000000000000013321130311212100157400ustar00rootroot00000000000000[ ca ]
default_ca = CA_default

[ CA_default ]
dir = /var/lib/alterator-ca/CA
database = $dir/index.txt
new_certs_dir = $dir/newcerts

certificate = $dir/cacert.pem
serial = $dir/serial
private_key = $dir/private/cakey.pem
RANDFILE = $dir/private/.rand

default_days = 365
default_crl_days= 30
default_md = md5

policy = policy_any
email_in_dn = no
unique_subject = no

name_opt = ca_default
cert_opt = ca_default
copy_extensions = none

[ policy_any ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

alterator-ca-0.5.4/etc/000075500000000000000000000000001130311212100146305ustar00rootroot00000000000000alterator-ca-0.5.4/etc/dnparam.txt000064400000000000000000000000061130311212100170070ustar00rootroot00000000000000C=
O=
alterator-ca-0.5.4/hook/000075500000000000000000000000001130311212100150155ustar00rootroot00000000000000alterator-ca-0.5.4/hook/ca000064400000000000000000000003221130311212100153200ustar00rootroot00000000000000#!/bin/sh

# Hook for alterator-trust
# $1 - host
# $2 - action

host="$1"
action="$2"

case "$action" in
add)
ca-sko addhost "$host"
ca-sko update "$host"
;;
remove)
ca-sko delhost "$host"
;;
esac
alterator-ca-0.5.4/interfaces/000075500000000000000000000000001130311212100162005ustar00rootroot00000000000000alterator-ca-0.5.4/interfaces/guile/000075500000000000000000000000001130311212100173055ustar00rootroot00000000000000alterator-ca-0.5.4/interfaces/guile/type/000075500000000000000000000000001130311212100202665ustar00rootroot00000000000000alterator-ca-0.5.4/interfaces/guile/type/ca-cert-field.scm000064400000000000000000000007241130311212100233740ustar00rootroot00000000000000(define-module (alterator type ca-cert-field)
:use-module (alterator woo)
:export (type))

(define *latin-string-regex-str* "^[a-zA-Z_[:space:][:punct:]0-9-]+$")
(define *latin-string-regex* (make-regexp *latin-string-regex-str* regexp/extended))

(define (type v _)
(or (and (string? v) (string-null? v))
(and (string? v) (regexp-exec *latin-string-regex* v))
(type-error (_ "only digits, punctuation and latin letters allowed" "alterator-ca"))))
alterator-ca-0.5.4/ui/000075500000000000000000000000001130311212100144725ustar00rootroot00000000000000alterator-ca-0.5.4/ui/ca/000075500000000000000000000000001130311212100150555ustar00rootroot00000000000000alterator-ca-0.5.4/ui/ca/ajax.scm000064400000000000000000000007521130311212100165100ustar00rootroot00000000000000(define-module (ui ca ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:export (ui))

(define (download file)
(ui-blob "file"
(woo-read-first "/ca/download"
'file file)
"text/plain"
file))

(define (module-path)
(if (woo-get-option (woo-read-first "/ca/root") 'is_active)
"/ca/certs"
"/ca/root"))

(define (ui)
(let ((file (form-value "download")))
(if file
(download file)
(ui-replace (module-path)))))
alterator-ca-0.5.4/ui/ca/certs/000075500000000000000000000000001130311212100161755ustar00rootroot00000000000000alterator-ca-0.5.4/ui/ca/certs/ajax.scm000064400000000000000000000044461130311212100176340ustar00rootroot00000000000000(define-module (ui ca certs ajax)
:use-module (alterator ajax)
:use-module (alterator effect)
:use-module (alterator woo)
:export (init))

(define (ui-read)
(let* ((obj (woo-read-first "/ca/certs"))
(can_has_sign (woo-get-option obj 'can_has_sign)))
(form-update-value-list obj)
(update-effect)
(form-update-visibility '("can_has_sign") can_has_sign)))

(define (ui-list)
(form-update-enum "name"
(woo-list "/ca/certs" 'language (form-value "language")))
(form-update-enum "new_name"
(woo-list "/ca/avail_hosts" 'language (form-value "language"))))

(define (on-autoupdate)
(catch/message
(lambda()
(woo-write "/ca/certs"
'apply_autoupdate #t
'language (form-value "language")
'autoupdate (form-value "autoupdate")
'time (form-value "time"))
(ui-read))))

(define (on-upload)
(call-with-form-file
"request"
(lambda (path)
(catch/message
(lambda()
(woo "upload" "/ca"
'request path
'language (form-value "language"))))))
(ui-read))

(define (on-del-host)
(catch/message
(lambda()
(woo-write "/ca/certs"
'del_host #t
'name (form-value "name")
'language (form-value "language"))
(ui-list))))

(define (on-new-host)
(catch/message
(lambda()
(woo-write "/ca/certs"
'new_host #t
'new_name (form-value "new_name")
'language (form-value "language"))
(ui-list))))

(define (on-update-host)
(catch/message
(lambda()
(woo-write "/ca/certs"
'update_host #t
'name (form-value "name")
'language (form-value "language"))
(ui-list))))

(define (on-sign)
(form-update-visibility '("can_has_sign") #f)
(form-replace "/ca?download=output.pem"))

(define (init)
(effect-enable "time" "autoupdate" #t)
(init-effect)
(ui-read)
(ui-list)
(form-bind-upload "upload_button" "click" "request" on-upload)
(form-bind "sign_button" "click" on-sign)
(form-bind "apply_autoupdate" "click" on-autoupdate)
(form-bind "del_host" "click" on-del-host)
(form-bind "new_host" "click" on-new-host)
(form-bind "update_host" "click" on-update-host))
alterator-ca-0.5.4/ui/ca/certs/host/000075500000000000000000000000001130311212100171525ustar00rootroot00000000000000alterator-ca-0.5.4/ui/ca/certs/host/ajax.scm000064400000000000000000000011661130311212100206050ustar00rootroot00000000000000(define-module (ui ca certs host ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:export (init))

(define (ui-read)
(form-update-enum
"key_name"
(woo-list "/ca/host"
'language (form-value "language")
'hostname (form-value "hostname"))))

(define (ui-write)
(catch/message
(lambda()
(woo-write "/ca/host"
'sign_key #t
'language (form-value "language")
'hostname (form-value "hostname")
'key_name (form-value "key_name"))
(ui-read))))

(define (init)
(ui-read)
(form-bind "sign_key" "click" ui-write))alterator-ca-0.5.4/ui/ca/certs/host/index.html000064400000000000000000000027051130311212100211530ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<!-- host certificates administration module -->
<html>
<body>
<form method="POST">
<a href="/ca/certs"><span translate="_">Back to list</span></a>
<h2><span class="alterator-label" name="displayname"/>&nbsp;<span translate="_">certificates</span></h2>
<table name="key_name" class="alterator-listbox multi-select" style="width:100%">
<thead>
<tr>
<th><span translate="_">Name</span></th>
<th><span translate="_">Status</span></th>
<th><span translate="_">Date issued</span></th>
<th><span translate="_">Expiry date</span></th>
<th><span translate="_">Subject</span></th>
</tr>
</thead>
<tbody>
<tr alterator-class="cert_status">
<td nowrap="yes"><span class="alterator-label" name="name"/></td>
<td nowrap="yes"><span class="alterator-label" name="status"/></td>
<td nowrap="yes"><tt><span class="alterator-label" name="issued"/></tt></td>
<td nowrap="yes"><tt><span class="alterator-label" name="expires"/></tt></td>
<td nowrap="yes"><span class="alterator-label" name="subject"/></td>
</tr>
</tbody>
</table>
<span translate="_">With selected:</span>
<input type="button" name="sign_key" value="Sign" class="btn"/>
</form>
</body>
</html>
alterator-ca-0.5.4/ui/ca/certs/index.html000064400000000000000000000041041130311212100201710ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<!-- certificates administration module -->
<html>
<body>
<table width="100%">
<tr>
<td style="text-align:center;"><b><span translate="_">Certificate management</span></b></td>
<td style="text-align:center;"><a href="/ca/root"><span translate="_">CA management</span></a></td>
</tr>
</table>
<hr/>
<form method="POST">
<input type="checkbox" value="#t" name="autoupdate"/>
<span translate="_">Enable daily updates at</span>
<input type="text" class="text" size="8" name="time"/>
<input type="button" name="apply_autoupdate" value="Apply" class="btn"/>
<hr/>
<h3><span translate="_">Sign certificate</span></h3>
<input type="file" name="request" class="text"/>
<input type="button" name="upload_button" value="Upload request" class="btn"/>
<div name="can_has_sign">
<pre><span class="alterator-label" name="sign_request"/></pre>
<input type="button" name="sign_button" value="Sign" class="btn"/>
</div>
<hr/>
<h3><span translate="_">Managed hosts</span></h3>
<table name="name" class="alterator-listbox multi-select" style="width:100%">
<thead>
<tr>
<th><span translate="_">Host</span></th>
</tr>
</thead>
<tbody>
<tr>
<td nowrap="yes" style="width:100%">
<a prefix-href="/ca/certs/host?hostname=" class="alterator-href" name="name">
<span class="alterator-label" name="hostname"/>
</a>
</td>
</tr>
</tbody>
</table>
<span translate="_">With selected:</span>
<input type="button" name="del_host" value="Delete" class="btn"/>
<input type="button" name="update_host" value="Update" class="btn"/>
<br/>
<span translate="_">Add host:</span>
<select name="new_name" enumref="/ca/avail_hosts"/>
<input type="button" name="new_host" value="Add" class="btn"/>
</form>
</body>
</html>
alterator-ca-0.5.4/ui/ca/root/000075500000000000000000000000001130311212100160405ustar00rootroot00000000000000alterator-ca-0.5.4/ui/ca/root/ajax.scm000064400000000000000000000013631130311212100174720ustar00rootroot00000000000000(define-module (ui ca root ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:use-module (alterator effect)
:export (init))

(define (ui-read)
(form-update-value-list
(woo-read-first "/ca/root"))
(form-update-value "confirm" #f)
(update-effect))

(define (ui-write)
(catch/message
(lambda()
(apply woo "create" "/ca/root"
'language (form-value "language")
(form-value-list))
(ui-read))))

(define (init)
(effect-show "active" "is_active" #t)
(effect-show "inactive" "is_active" #f)
(effect-show "confirm_button" "confirm" #t)
(init-effect)
(ui-read)
(form-bind "confirm_button" "click" ui-write)
(form-bind "create_button" "click" ui-write))
alterator-ca-0.5.4/ui/ca/root/index.html000064400000000000000000000116411130311212100200400ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<!-- CA administration module -->
<html>
<body>
<table width="100%" name="active">
<tr>
<td style="text-align:center;"><a href="/ca/certs"><span translate="_">Certificate management</span></a></td>
<td style="text-align:center;"><b><span translate="_">CA management</span></b></td>
</tr>
</table>
<hr/>
<form method="POST">
<input type="checkbox" name="is_active" value="#t" style="display:none"/>
<h3><span translate="_">CA status:</span> <span class="alterator-label" name="status"/></h3>
<table class="form-table" name="active">
<tbody>
<tr>
<td colspan="2" style="text-align:left;"><b><span translate="_">Subject</span></b></td>
</tr>
<tr>
<td><span translate="_">Common Name (CN):</span></td>
<td><span class="alterator-label" name="subject_CN"/></td>
</tr>
<tr>
<td><span translate="_">Organizational Unit (OU):</span></td>
<td><span class="alterator-label" name="subject_OU"/></td>
</tr>
<tr>
<td><span translate="_">Organization (O):</span></td>
<td><span class="alterator-label" name="subject_O"/></td>
</tr>
<tr>
<td><span translate="_">Country (C):</span></td>
<td><span class="alterator-label" name="subject_C"/></td>
<tr>
</tr>
<td colspan="2" style="text-align:left;"><b><span translate="_">Issuer</span></b></td>
</tr>
<tr>
<td><span translate="_">Common Name (CN):</span></td>
<td><span class="alterator-label" name="issuer_CN"/></td>
</tr>
<tr>
<td><span translate="_">Organizational Unit (OU):</span></td>
<td><span class="alterator-label" name="issuer_OU"/></td>
</tr>
<tr>
<td><span translate="_">Organization (O):</span></td>
<td><span class="alterator-label" name="issuer_O"/></td>
</tr>
<tr>
<td><span translate="_">Country (C):</span></td>
<td><span class="alterator-label" name="issuer_C"/></td>
</tr>
<tr>
<td colspan="2" style="text-align:left;"><b><span translate="_">Other</span></b></td>
</tr>
<tr>
<td><span translate="_">Issued on:</span></td>
<td>
<tt><span class="alterator-label" name="startdate"/></tt>
</td>
</tr>
<tr>
<td><span translate="_">Expires on:</span></td>
<td>
<tt><span class="alterator-label" name="enddate"/></tt>
</td>
</tr>
<tr>
<td><span translate="_">SHA1 Fingerprint:</span></td>
<td>
<tt><span class="alterator-label" name="sha1fp"/></tt>
</td>
</tr>
<tr>
<td><span translate="_">MD5 Fingerprint:</span></td>
<td>
<tt><span class="alterator-label" name="md5fp"/></tt>
</td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td><span translate="_">Download certificate:</span></td>
<td><tt><a href="/ca?download=ca-root.pem">ca-root.pem</a></tt></td>
</tr>
<tr>
<td><span translate="_">Download sign request:</span></td>
<td><tt><a href="/ca?download=ca-root.csr">ca-root.csr</a></tt></td>
</tr>
</tbody>
</table>
<hr/>
<span name="active">
<input type="checkbox" name="confirm" value="#t"/><span translate="_">Re-generate CA</span>
</span>
<table class="form-table">
<tbody>
<tr>
<td><span name="C" translate="_">Country (C):</span></td>
<td>
<input type="text" name="C" class="text"/><br/>
<small><span translate="_">(two letter country code)</span></small>
</td>
</tr>
<tr>
<td><span name="O" translate="_">Organization (O):</span></td>
<td>
<input type="text" name="O" class="text"/><br/>
<small><span translate="_">(organization name, written in latin letters)</span></small>
</td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td nowrap="yes">
<span name="active">
<input type="button" name="confirm_button" value="Confirm" class="btn"/>
</span>
<span name="inactive">
<input type="button" name="create_button" value="Create" class="btn"/>
</span>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin