alterator-sslkey-0.2.3/000075500000000000000000000000001151506040500150145ustar00rootroot00000000000000alterator-sslkey-0.2.3/Makefile000064400000000000000000000001721151506040500164540ustar00rootroot00000000000000NAME=sslkey INSTALL=/usr/bin/install all: clean: install: install-module include /usr/share/alterator/build/module.mak alterator-sslkey-0.2.3/applications/000075500000000000000000000000001151506040500175025ustar00rootroot00000000000000alterator-sslkey-0.2.3/applications/sslkey.desktop000064400000000000000000000004311151506040500224050ustar00rootroot00000000000000[Desktop Entry] Type=Application Categories=X-Alterator-System Icon=sslkey Terminal=false Name=SSL keys management X-Alterator-URI=/sslkey X-Alterator-Weight=30 X-Alterator-Help=sslkey Name[ru]=Управление ключами SSL Name[uk]=Керування ключами SSL alterator-sslkey-0.2.3/backend3/000075500000000000000000000000001151506040500164665ustar00rootroot00000000000000alterator-sslkey-0.2.3/backend3/sslkey000075500000000000000000000135461151506040500177370ustar00rootroot00000000000000#!/bin/sh po_domain="alterator-sslkey" alterator_api_version=1 . alterator-sh-functions . shell-config . cert-sh-functions OPENSSL="${OPENSSL:-/usr/bin/openssl}" sysconfigclock_file=/etc/sysconfig/clock zonetab_file=/usr/share/zoneinfo/zone.tab get_expire_date() { local cert="$1"; shift local d="$($OPENSSL x509 -noout -enddate -in "$cert" | sed -nr 's/^[[:blank:]]*notAfter=(.+)$/\1/p' 2>/dev/null)" [ -n "$d" ] && date --date="$d" +%x } is_cert() { [ -n "$1" ] || return 1 $OPENSSL x509 -noout -in "$1" 2>/dev/null } ssl_modulus_md5() { [ -n "$1" -a -n "$2" ] || return 1 $OPENSSL "$1" -noout -modulus -in "$2" | $OPENSSL md5 } validate_cert() { local cert="$1"; shift local key="$1"; shift [ -f "$cert" -a -f "$key" ] && is_cert "$cert" && \ [ "$(ssl_modulus_md5 x509 "$cert")" = "$(ssl_modulus_md5 rsa "$key")" ] } ### lists list_keys() { find "$SSL_KEYDIR" -type f -name \*.key -printf "%f\n" | sed s/.key//g 2>/dev/null } list_sslfiles() { local str= expire= list_keys | sort | while read i; do if ssl_check_cert "$i"; then if validate_cert "$SSL_CERTDIR/$i.cert" "$SSL_KEYDIR/$i.key"; then expire="$(get_expire_date "$SSL_CERTDIR/$i.cert")" if [ -n "$expire" ]; then str="(`_ "expire"`: $expire)" else str="(`_ "OK certificate"`)" fi else str="(`_ "Invalid certificate"`)" fi else str="(`_ "No certificate"`)" fi write_enum_item "$i" "$i $str" done } ### read _get_subj_item() { [ -n "$1" -a -n "$2" -a -n "$3" ] || return $OPENSSL "$1" -noout -subject -in "$2" | sed -rn "s|^.*/$3=([^/]+).*$|\1|p" 2>/dev/null } get_subj_item() { local name="$1"; shift local item="$1"; shift [ -n "$name" -a -n "$item" ] || return if ssl_check_req "$name"; then _get_subj_item req "$SSL_CSRDIR/$name.csr" "$item" elif ssl_check_cert "$name"; then _get_subj_item x509 "$SSL_CERTDIR/$name.cert" "$item" fi } read_ssl() { local items='CN O C L OU emailAddress' if [ -n "$1" ] && ssl_check_key "$1"; then write_bool_param key_exist true for i in $items; do write_string_param "$i" "$(get_subj_item "$1" "$i")" done else write_bool_param key_exist false fi } read_zone() { shell_config_get "$sysconfigclock_file" ZONE } read_country() { local zone="$(read_zone)" [ -n "$zone" ] || return grep "$zone" "$zonetab_file" | cut -f1 } read_location() { local zone="$(read_zone)" echo "${zone##*/}" } read_ssl_defaults() { write_string_param CN "$DEFAULT_CN" write_string_param O "$DEFAULT_O" write_string_param C "$(read_country)" write_string_param L "$(read_location)" write_string_param OU "$DEFAULT_OU" write_string_param emailAddress "$DEFAULT_emailAddress" } ### write make_name() { local name= if [ -n "$in_CN" ]; then name="$in_CN" elif [ -n "$in_O" ]; then name="$in_O" elif [ -n "$in_OU" ]; then name="$in_OU" else return fi echo "$name" } create_sslconf() { local cn="$in_CN" local org="${in_O:+O=$in_O\n}" local country="${in_C:+C=$in_C\n}" local locality="${in_L:+L=$in_L\n}" local ounit="${in_OU:+OU=$in_OU\n}" local email="${in_emailAddress:+emailAddress=$in_emailAddress\n}" local sslconf= [ -n "$1" ] || return if [ -z "$cn" ]; then local hostname="$(hostname)" cn="${hostname:-localhost.localdomain}" fi sslconf="$(mktemp -t "ssl_$1.conf.XXXXXXXX")" echo "$DEFAULT_CERT" | sed -e "s|@HOSTNAME@|$cn|" \ -e "s|^O=@PRODUCT@|$org$country$locality$ounit$email|" \ >"$sslconf" echo "$sslconf" } write_ssl() { local sslconf="$(create_sslconf "$1")" if [ -n "$sslconf" ]; then rm -f "$SSL_KEYDIR/$1.key" rm -f "$SSL_CSRDIR/$1.csr" ssl_make_key "$1" "$sslconf" ssl_make_req "$1" "$sslconf" rm "$sslconf" fi } ### on_message() { case "$in_action" in type) write_type_item CN ssl-cert-field write_type_item C ssl-cert-country-code write_type_item L ssl-cert-field write_type_item O ssl-cert-field write_type_item OU ssl-cert-field write_type_item emailAddress e-mail ;; read) case "$in__objects" in /) read_ssl "$in_name" if [ -n "$in_name" ]; then SSL_FILES_NAME="$in_name" fi ;; name) write_string_param name "$SSL_FILES_NAME" ;; sslkey-default) read_ssl_defaults ;; csr) write_string_param csr "$SSL_CSRDIR/$SSL_FILES_NAME.csr" ;; make-name) local name="$(make_name)" if [ -n "$name" ]; then SSL_FILES_NAME="$name" write_string_param name "$name" else write_error "`_ "Unable to determine file name"`" fi ;; *) ;; esac ;; write) case "$in__objects" in /) if [ -n "$in_name" ]; then SSL_FILES_NAME="$in_name" write_ssl "$in_name" fi ;; reset-name) SSL_FILES_NAME="$in_name" ;; upload|import-cert) local name="${in_name:-$SSL_FILES_NAME}" [ -n "$in_certificate" -a -n "$name" ] || return local keyfile="$SSL_KEYDIR/$name.key" local certfile="$SSL_CERTDIR/$name.cert" if validate_cert "$in_certificate" "$keyfile"; then cp -f "$in_certificate" "$certfile" chmod 644 "$certfile" else write_error "`_ "Invalid certificate file"`" fi ;; export-request) if [ -n "$in_path" -a -n "$in_name" ]; then if [ ! -f "$SSL_CSRDIR/$in_name.csr" ]; then write_error "`_ "Sign request does not exist"`" elif [ ! -d "$in_path" ]; then write_error "`_ "Target directory does not exist"`" else cp -T "$SSL_CSRDIR/$in_name.csr" "$in_path/$in_name.csr" || write_error "`_ "Export sign request failed"`" fi fi ;; delete) if [ -n "$in_name" ]; then rm -f "$SSL_KEYDIR/$in_name.key" "$SSL_CERTDIR/$in_name.cert" "$SSL_CSRDIR/$in_name.csr" fi ;; esac ;; list) case "${in__objects##*/}" in avail_keys) set_locale list_sslfiles ;; *) ;; esac ;; esac } message_loop alterator-sslkey-0.2.3/type/000075500000000000000000000000001151506040500157755ustar00rootroot00000000000000alterator-sslkey-0.2.3/type/ssl-cert-country-code.scm000064400000000000000000000006301151506040500226450ustar00rootroot00000000000000(define-module (alterator type ssl-cert-country-code) :use-module (alterator woo) :use-module ((type iso-3166-alpha-2) :select (*iso-3166-alpha-2*)) :export (type)) (define (type v _) (or (and (string? v) (or (string-null? v) (member v *iso-3166-alpha-2*))) (type-error (_ "invalid ISO-3166-alpha-2 country code")))) alterator-sslkey-0.2.3/type/ssl-cert-field.scm000064400000000000000000000007311151506040500213170ustar00rootroot00000000000000(define-module (alterator type ssl-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-sslkey")))) alterator-sslkey-0.2.3/ui/000075500000000000000000000000001151506040500154315ustar00rootroot00000000000000alterator-sslkey-0.2.3/ui/sslkey/000075500000000000000000000000001151506040500167435ustar00rootroot00000000000000alterator-sslkey-0.2.3/ui/sslkey/ajax.scm000064400000000000000000000020101151506040500203630ustar00rootroot00000000000000(define-module (ui sslkey ajax) :use-module (alterator ajax) :use-module (alterator woo) :export (init)) (define (ui-update-keys) (let* ((keys (woo-list "/sslkey/avail_keys" 'language (form-value "language"))) (first-value (if (null? keys) #f (woo-get-option (car keys) 'name)))) (form-update-enum "keys" keys) (form-update-value "keys" first-value))) (define (on-change) (form-replace (format #f "/sslkey/generate?name=~A" (form-value "keys")))) (define (on-new) (form-replace "/sslkey/generate")) (define (on-delete) (woo-write "/sslkey/delete" 'name (form-value "keys" 'language (form-value "language"))) (form-update-visibility "confirm_delete" #f) (form-update-value "delete_all" #f) (ui-update-keys)) (define (init) (ui-update-keys) (form-bind "change_button" "click" on-change) (form-bind "new_button" "click" on-new) (form-bind "delete_all" "change" (lambda() (form-update-visibility "confirm_delete" (form-value "delete_all")))) (form-bind "confirm_delete" "click" on-delete)) alterator-sslkey-0.2.3/ui/sslkey/csr/000075500000000000000000000000001151506040500175325ustar00rootroot00000000000000alterator-sslkey-0.2.3/ui/sslkey/csr/ajax.scm000064400000000000000000000005031151506040500211570ustar00rootroot00000000000000(define-module (ui sslkey csr ajax) :use-module (alterator ajax) :use-module (alterator woo) :export (ui)) (define (ui) (let* ((name (woo-get-option (woo-read-first "/sslkey/name") 'name)) (file (string-append name ".csr"))) (ui-file "csr" (woo-read-first "/sslkey/csr") "text/plain" file))) alterator-sslkey-0.2.3/ui/sslkey/generate/000075500000000000000000000000001151506040500205355ustar00rootroot00000000000000alterator-sslkey-0.2.3/ui/sslkey/generate/ajax.scm000064400000000000000000000072271151506040500221740ustar00rootroot00000000000000(define-module (ui sslkey generate ajax) :use-module (alterator ajax) :use-module (alterator woo) :use-module (alterator algo) :export (init)) (define *name* (make-cell "")) (define (backend-path) (or (form-value "backend") "/sslkey")) (define (make-name) (or (catch/message (lambda() (woo-get-option (apply woo-read-first "/sslkey/make-name" (form-value-list '("CN" "C" "L" "O" "OU" "emailAddress"))) 'name))) "")) (define (get-or-make-name) (let ((name (cell-ref *name*))) (if (string=? "" name) (make-name) name))) (define (get-name) (let ((name (cell-ref *name*))) (if (string=? "" name) (read-name "/sslkey") name))) (define (read-name backend) (or (catch/message (lambda() (let ((backend-obj (string-append backend "/sslkey-name"))) (woo-get-option (woo-read-first backend-obj) 'name)))) "")) (define (read-hide backend) (catch/message (lambda() (let ((backend-obj (string-append backend "/sslkey-hide"))) (woo-get-option (woo-read-first backend-obj) 'hide))))) (define (ui-read-defaults backend name) (let* ((backend-obj (string-append backend "/sslkey-default")) (cmd (woo-read-first backend-obj 'name name))) (form-update-value-list '("CN" "C" "L" "O" "OU" "emailAddress") cmd))) (define (ui-read backend name) (catch/message (lambda() (let* ((cmd (woo-read-first "/sslkey" 'name name)) (key_exist (woo-get-option cmd 'key_exist))) (if key_exist (form-update-value-list '("CN" "C" "L" "O" "OU" "emailAddress") cmd) (and backend (ui-read-defaults backend name))) (form-update-activity "download_sr" key_exist))))) (define (ui-fields-hide hide) (for-each (lambda(item) (form-update-visibility item #f)) (string-split hide #\;))) (define (ui-update active) (form-update-activity "upload_button" active) (form-update-activity "certificate" active) (form-update-value "generate_key" (not active)) (form-update-visibility "confirm_button" (not active))) (define (reset-name) (let ((name (form-value "name"))) (catch/message (lambda() (woo-write "sslkey/reset-name" 'name (or name "")))))) (define (ui-init) (form-update-visibility "ca_upload_message" #f) (let* ((backend (backend-path)) (name (or (form-value "name") (read-name backend))) (hide (or (form-value "hide") (read-hide backend)))) (and name (cell-set! *name* name)) (and (string=? "" (cell-ref *name*)) (ui-update #f)) (and hide (not (string=? "" hide)) (ui-fields-hide hide)) (ui-read backend (cell-ref *name*)))) (define (on-upload) (form-update-visibility "ca_upload_message" #f) (call-with-form-file "certificate" (lambda(path) (and (catch/message (lambda() (woo-write "/sslkey/upload" 'certificate path 'name *name* 'language (form-value "language")))) (form-update-visibility "ca_upload_message" #t))))) (define (on-confirm) (let ((name (get-or-make-name))) (catch/message (lambda() (apply woo-write "/sslkey" 'name name (form-value-list '("CN" "C" "L" "O" "OU" "emailAddress" "language"))))) (ui-read (backend-path) name) (ui-update #t))) (define (download-csr) (form-replace "/sslkey/csr")) (define (init) (ui-init) (form-bind-upload "upload_button" "click" "certificate" on-upload) (form-bind "generate_key" "change" (lambda() (form-update-visibility "confirm_button" (form-value "generate_key")))) (form-bind "download_sr" "click" download-csr) (form-bind "confirm_button" "click" (lambda() (begin (ui-update #f) (on-confirm))))) alterator-sslkey-0.2.3/ui/sslkey/generate/index.html000064400000000000000000000055511151506040500225400ustar00rootroot00000000000000

SSL settings

Common Name (CN):
(hostname for server or something else for client)
Country (C):
(two letter country code)
Location (L):
(state or city, written in latin letters)
Organization (O):
(organization name, written in latin letters)
Organizational Unit (OU):
(organizational unit name, written in latin letters)
E-mail address:
(your e-mail address)
 
  (Re)create key and sign request

Sign


Upload certificate signed by CA:  
Certificate successfully uploaded
alterator-sslkey-0.2.3/ui/sslkey/generate/index.scm000064400000000000000000000125371151506040500223600ustar00rootroot00000000000000(document:surround "/std/frame") ;;; Functions (define *name* (make-cell "")) (define (backend-path) (or (global 'backend) "/sslkey")) (define (make-name) (or (catch/message (lambda() (woo-get-option (apply woo-read-first "/sslkey/make-name" (form-value-list '("CN" "C" "L" "O" "OU" "emailAddress"))) 'name))) "")) (define (get-or-make-name) (let ((name (cell-ref *name*))) (if (string=? "" name) (make-name) name))) (define (get-name) (let ((name (cell-ref *name*))) (if (string=? "" name) (read-name "/sslkey") name))) (define (read-name backend) (or (catch/message (lambda() (let ((backend-obj (string-append backend "/sslkey-name"))) (woo-get-option (woo-read-first backend-obj) 'name)))) "")) (define (read-hide backend) (catch/message (lambda() (let ((backend-obj (string-append backend "/sslkey-hide"))) (woo-get-option (woo-read-first backend-obj) 'hide))))) (define (ui-read-defaults backend name) (let* ((backend-obj (string-append backend "/sslkey-default")) (cmd (woo-read-first backend-obj 'name name))) (form-update-value-list '("CN" "C" "L" "O" "OU" "emailAddress") cmd))) (define (ui-read backend name) (catch/message (lambda() (let ((cmd (woo-read-first "/sslkey" 'name name))) (if (woo-get-option cmd 'key_exist) (form-update-value-list '("CN" "C" "L" "O" "OU" "emailAddress") cmd) (and backend (ui-read-defaults backend name))))))) (define (ui-fields-hide hide) (for-each (lambda(item) (form-update-visibility item #f)) (string-split hide #\;))) (define (ui-update active) (form-update-value "generate_key" (not active)) (form-update-visibility "confirm_button" (not active))) (define (reset-name) (let ((name (global 'name))) (catch/message (lambda() (woo-write "sslkey/reset-name" 'name (or name "")))))) (define (ui-init) (let* ((backend (backend-path)) (name (or (global 'name) (read-name backend))) (hide (or (global 'hide) (read-hide backend)))) (and name (cell-set! *name* name)) (and (string=? "" (cell-ref *name*)) (ui-update #f)) (and hide (not (string=? "" hide)) (ui-fields-hide hide)) (ui-read backend (cell-ref *name*)))) (define (confirm-export-request) (let ((path (export-request value)) (name (get-name))) (or (string=? path "") (string=? name "") (and (catch/message (lambda() (woo-write "/sslkey/export-request" 'path path 'name name))) (export-request value ""))))) (define (confirm-import-cert) (let ((path (import-cert value)) (name (get-name))) (or (string=? path "") (string=? name "") (and (catch/message (lambda() (woo-write "/sslkey/import-cert" 'certificate path 'name name))) (import-cert value ""))))) (define (on-confirm) (let ((name (get-or-make-name))) (catch/message (lambda() (apply woo-write "/sslkey" 'name name (form-value-list '("CN" "C" "L" "O" "OU" "emailAddress"))))) (ui-read (backend-path) name) (ui-update #t))) (define (ui-exit) (document:end)) (define (apply-all) (and (confirm-export-request) (confirm-import-cert))) (define (ok) (and (apply-all) (ui-exit))) ;;; UI width 600 height 500 (define fileselect (make-widget 'fileselect)) (define url (make-attribute 'url)) (define value (make-attribute 'value)) (define filter (make-attribute 'filter)) (define hints (make-attribute 'hints)) (gridbox columns "0;100" margin 10 (label colspan 2 text (bold (_ "SSL settings:"))) (label text (_ "Common Name (CN):") name "CN" align "left") (edit name "CN") ;; (label text (_ "Country (C):") name "C" align "left") (edit name "C") ;; (label text (_ "Location (L):") name "L" align "left") (edit name "L") ;; (label text (_ "Organization (O):") name "O" align "left") (edit name "O") ;; (label text (_ "Organizational Unit (OU):") name "OU" align "left") (edit name "OU") ;; (label text (_ "E-mail address:") name "emailAddress" align "left") (edit name "emailAddress") ;; (checkbox text (_ "Generate key and sign request") name "generate_key") (button (_ "Confirm") name "confirm_button" align "left" visibility #f) ;; (separator colspan 2) ;; (label text (_ "Export sign request") name "sign_req" align "left") (spacer) (label text (_ "Destination directory:")) (document:id export-request (fileselect title (_"Export sign request") url "/" filter "*.csr" hints "existing_file;directory;show_dirs_only")) ;; (separator colspan 2) (spacer colspan 2) ;; (label text (_ "Import user certificate:")) (document:id import-cert (fileselect title (_"Import user certificate") url "/" filter "*.cert *.crt *.pem" hints "existing_file")) ;; (spacer colspan 2) (spacer colspan 2) (hbox align "right" colspan 2 (button (_ "OK") name "ok") (button (_ "Apply") name "apply") (button (_ "Cancel") name "cancel"))) ;;;;;;;;;;;;;;;;;; (document:root (when loaded (reset-name)(ui-init)) (form-bind "ok" "click" ok) (form-bind "apply" "click" apply-all) (form-bind "cancel" "click" ui-exit) (form-bind "generate_key" "change" (lambda() (form-update-visibility "confirm_button" (form-value "generate_key")))) (form-bind "confirm_button" "click" (lambda() (begin (ui-update #f) (on-confirm))))) alterator-sslkey-0.2.3/ui/sslkey/index.html000064400000000000000000000024561151506040500207470ustar00rootroot00000000000000

SSL keys:

 
 
Delete key, certificate and sign request
alterator-sslkey-0.2.3/ui/sslkey/index.scm000064400000000000000000000025021151506040500205550ustar00rootroot00000000000000(document:surround "/std/frame") ;;; Functions (define (ui-update-keys) (let* ((keys (woo-list "/sslkey/avail_keys")) (first-value (if (null? keys) #f (woo-get-option (car keys) 'name)))) (form-update-enum "keys" keys) (form-update-value "keys" first-value))) (define (on-change) (form-popup "/sslkey/generate" 'name (form-value "keys")) (ui-update-keys)) (define (on-new) (form-popup "/sslkey/generate") (ui-update-keys)) (define (on-delete) (woo-write "/sslkey/delete" 'name (form-value "keys")) (form-update-visibility "confirm_delete" #f) (form-update-value "delete_all" #f) (ui-update-keys)) ;;; UI (gridbox columns "0;100" margin 40 (listbox name "keys") (spacer) (hbox align "right" (button (_ "New...") name "new_button") (button (_ "Change...") name "change_button")) (spacer colspan 2) (spacer colspan 2) (checkbox text (_ "Delete key, certificate and sign request") name "delete_all") (button (_ "Confirm") name "confirm_delete" align "left" visibility #f)) ;;;;;;;;;;;;;;;;;; (document:root (when loaded (ui-update-keys)) (form-bind "change_button" "click" on-change) (form-bind "new_button" "click" on-new) (form-bind "delete_all" "change" (lambda() (form-update-visibility "confirm_delete" (form-value "delete_all")))) (form-bind "confirm_delete" "click" on-delete))