diff -Nru kxd-0.13+git20170730.6182dc8/debian/changelog kxd-0.14/debian/changelog --- kxd-0.13+git20170730.6182dc8/debian/changelog 2017-08-02 12:13:04.000000000 +0000 +++ kxd-0.14/debian/changelog 2020-04-05 09:17:44.000000000 +0000 @@ -1,3 +1,34 @@ +kxd (0.14-2) unstable; urgency=medium + + [ HÃ¥vard Flaget Aasen ] + * Set absolute path in d/rules (Closes: #952332) + * Cherry-pick upstream commit, needed for upstream testsuite. + 0001-tests-Add-missing-conn.getresponse-which-was-causing.patch + + [ Maximiliano Curia ] + * Release to unstable + + -- Maximiliano Curia Sun, 05 Apr 2020 11:17:44 +0200 + +kxd (0.14-1) unstable; urgency=medium + + [ Michael Stapelberg ] + * Set Built-Using field (Closes: 892117) + + [ Maximiliano Curia ] + * Update Vcs fields + * New upstream release (0.14). (Closes: 936811) + * Bump debhelper build-dep and compat to 12. + * Bump Standards-Version to 4.4.1. + * Use python3 + * Drop obsolete dh-systemd + * Use the right extensions + * Set GOCACHE + * Drop no longer needed overrides + * Release to unstable + + -- Maximiliano Curia Thu, 03 Oct 2019 18:28:56 +0200 + kxd (0.13+git20170730.6182dc8-1) sid; urgency=medium [ Alberto Bertogli ] diff -Nru kxd-0.13+git20170730.6182dc8/debian/compat kxd-0.14/debian/compat --- kxd-0.13+git20170730.6182dc8/debian/compat 2017-08-02 12:13:04.000000000 +0000 +++ kxd-0.14/debian/compat 2020-04-05 09:17:44.000000000 +0000 @@ -1 +1 @@ -9 +12 diff -Nru kxd-0.13+git20170730.6182dc8/debian/control kxd-0.14/debian/control --- kxd-0.13+git20170730.6182dc8/debian/control 2017-08-02 12:13:04.000000000 +0000 +++ kxd-0.14/debian/control 2020-04-05 09:17:44.000000000 +0000 @@ -3,20 +3,20 @@ Priority: optional Maintainer: Maximiliano Curia Uploaders: Alberto Bertogli -Build-Depends: debhelper (>= 9), - dh-systemd, +Build-Depends: debhelper (>= 12~), golang-go, openssl, - python, - python-docutils -Standards-Version: 4.0.0 + python3, + python3-docutils +Standards-Version: 4.4.1 Homepage: https://blitiri.com.ar/p/kxd -Vcs-Browser: https://anonscm.debian.org/git/collab-maint/kxd.git -Vcs-Git: https://anonscm.debian.org/git/collab-maint/kxd.git +Vcs-Browser: https://salsa.debian.org/debian/kxd +Vcs-Git: https://salsa.debian.org/debian/kxd.git Package: kxc Architecture: any Depends: cryptsetup, ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${misc:Built-Using} Description: Key exchange daemon -- client kxd is a key exchange daemon, which serves blobs of data (keys) over https. . @@ -29,6 +29,7 @@ Package: kxd Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${misc:Built-Using} Description: Key exchange daemon kxd is a key exchange daemon, which serves blobs of data (keys) over https. . diff -Nru kxd-0.13+git20170730.6182dc8/debian/docs kxd-0.14/debian/docs --- kxd-0.13+git20170730.6182dc8/debian/docs 2017-08-02 12:13:04.000000000 +0000 +++ kxd-0.14/debian/docs 2020-04-05 09:17:44.000000000 +0000 @@ -1,2 +1,2 @@ -doc/quick_start.rst -README +doc/quick_start.md +README.md diff -Nru kxd-0.13+git20170730.6182dc8/debian/patches/0001-tests-Add-missing-conn.getresponse-which-was-causing.patch kxd-0.14/debian/patches/0001-tests-Add-missing-conn.getresponse-which-was-causing.patch --- kxd-0.13+git20170730.6182dc8/debian/patches/0001-tests-Add-missing-conn.getresponse-which-was-causing.patch 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/debian/patches/0001-tests-Add-missing-conn.getresponse-which-was-causing.patch 2020-04-05 09:17:44.000000000 +0000 @@ -0,0 +1,30 @@ +From: Alberto Bertogli +Date: Sun, 29 Mar 2020 11:40:46 +0100 +Subject: tests: Add missing conn.getresponse() which was causing false + negatives + +Somewhere around Python 3.8, http.client.HTTPConnection objects changed +how result handling was done, and ignored SSL errors until +.getresponse() was called. + +This causes the test_no_local_cert to fail, even though the server is +responding correctly. + +This patch fixes this by adding a .getresponse() call, which forces +validation of the result and makes the test pass again. +--- + tests/run_tests | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/run_tests b/tests/run_tests +index d6d4ba2..9499bfe 100755 +--- a/tests/run_tests ++++ b/tests/run_tests +@@ -407,6 +407,7 @@ class TrickyRequests(TestCase): + conn = self.https_connection("localhost", 19840) + try: + conn.request("GET", "/v1/") ++ conn.getresponse() + conn.close() + except ssl.SSLError as err: + self.assertEqual(err.reason, "SSLV3_ALERT_BAD_CERTIFICATE") diff -Nru kxd-0.13+git20170730.6182dc8/debian/patches/series kxd-0.14/debian/patches/series --- kxd-0.13+git20170730.6182dc8/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/debian/patches/series 2020-04-05 09:17:44.000000000 +0000 @@ -0,0 +1 @@ +0001-tests-Add-missing-conn.getresponse-which-was-causing.patch diff -Nru kxd-0.13+git20170730.6182dc8/debian/rules kxd-0.14/debian/rules --- kxd-0.13+git20170730.6182dc8/debian/rules 2017-08-02 12:13:04.000000000 +0000 +++ kxd-0.14/debian/rules 2020-04-05 09:17:44.000000000 +0000 @@ -1,16 +1,10 @@ #!/usr/bin/make -f # -*- makefile -*- -%: - dh $@ --with=systemd - -override_dh_auto_clean: - dh_auto_clean - make -C doc/man clean +export GOCACHE=$(CURDIR)/debian/cache -override_dh_auto_build: - dh_auto_build - make -C doc/man +%: + dh $@ override_dh_auto_install: # Avoid calling make install-all, install files with the dh_install diff -Nru kxd-0.13+git20170730.6182dc8/doc/index.md kxd-0.14/doc/index.md --- kxd-0.13+git20170730.6182dc8/doc/index.md 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/index.md 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,90 @@ + +# Key exchange daemon + +[kxd](https://blitiri.com.ar/p/kxd) is a key exchange daemon, and +corresponding client, which serves blobs of data (keys) over https. + +It can be used to get keys remotely instead of using local storage. +The main use case is to get keys to open dm-crypt devices automatically, +without having to store them on the local machine. + +[![Travis-CI build status](https://travis-ci.org/albertito/kxd.svg?branch=master)](https://travis-ci.org/albertito/kxd) + + +## Quick start + +Please see the [quick start](https://blitiri.com.ar/p/kxd/docs/quick_start) +document for a step by step guide of a typical server and client setups. + + +## Server configuration + +The server configuration is stored in a root directory (`/etc/kxd/data`), and +within there, with per-key directories (e.g. `/etc/kxd/data/host1/key1`), each +containing the following files: + +- `key`: Contains the key to give to the client. +- `allowed_clients`: Contains one or more PEM-encoded client certificates + that will be allowed to request the key. If not present, then no clients + will be allowed to access this key. +- `allowed_hosts`: Contains one or more host names (one per line). If not + present, then all hosts will be allowed to access that key (as long as they + are authorized with a valid client certificate). +- `email_to`: Contains one or more email destinations to notify (one per + line). If not present, then no notifications will be sent upon key + accesses. + + +## Client configuration + +The basic command line client (*kxc*) will take the client key and +certificate, the expected server certificate, and a URL to the server (like +`kxd://server/host1/key1`), and it will print on standard output the returned +key (the contents of the corresponding key file). + +There are scripts to tie this with cryptsetup's infrastructure to make the +opening of encrypted devices automatic; see `cryptsetup/` for the details. + + +## Security + +All traffic between the server and the clients goes over SSL, using the +provided server certificate. + +The clients are authenticated and authorized based on their SSL client +certificates matching the ones associated with the key in the server +configuration, not using a root of trust (for now). + +Likewise, the clients will authenticate the server based on a certificate +given on the command line, and will only accept keys from it. + +Note the server will return reasonably detailed information on errors, for +example it will tell when a key is not found vs. when the client is not +allowed. While this leaks some information about existence of keys, it makes +troubleshooting much easier. + +The server itself makes no effort to protect the data internally; for example, +there is no on-disk encryption, and memory is not locked. We work under the +assumption that the server's host is secure and trusted. + + +## Dependencies + +There are no runtime dependencies for the kxd and kxc binaries. + +Building requires Go 1.11. + +The configuration helper scripts (`create-kxd-config`, `kxc-add-key`, etc.) +depend on: `bash`, `openssl` (the binary), and core utilities (`mkdir`, `dd`, +etc.). + +Testing needs Python 3, and openssl (the binary). + + +## Bugs and contact + +Please report bugs to albertito@blitiri.com.ar. + +The latest version can be found at +[https://blitiri.com.ar/p/kxd/](https://blitiri.com.ar/p/kxd/) + diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/generate.sh kxd-0.14/doc/man/generate.sh --- kxd-0.13+git20170730.6182dc8/doc/man/generate.sh 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/generate.sh 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Convert pod files to manual pages, using pod2man. +# +# Assumes files are named like: +# .
.pod + +set -e + +for IN in *.pod; do + OUT=$( basename $IN .pod ) + SECTION=${OUT##*.} + NAME=${OUT%.*} + + # If it has not changed in git, set the mtime to the last commit that + # touched the file. + CHANGED=$( git status --porcelain -- "$IN" | wc -l ) + if [ $CHANGED -eq 0 ]; then + GIT_MTIME=$( git log --pretty=%at -n1 -- "$IN" ) + touch -d "@$GIT_MTIME" "$IN" + fi + + podchecker $IN + pod2man --section=$SECTION --name=$NAME \ + --release "" --center "" \ + $IN $OUT +done diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/.gitignore kxd-0.14/doc/man/.gitignore --- kxd-0.13+git20170730.6182dc8/doc/man/.gitignore 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/doc/man/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -*.1 diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxc.1 kxd-0.14/doc/man/kxc.1 --- kxd-0.13+git20170730.6182dc8/doc/man/kxc.1 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/kxc.1 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,178 @@ +.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "kxc 1" +.TH kxc 1 "2019-08-10" "" "" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +kxc \- Key exchange client +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +\&\fBkxc\fR [\fIoptions\fR...] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +kxc is a client for \fBkxd\fR\|(1), a key exchange daemon. +.PP +It will take a client key and certificate, the expected server certificate, +and a \s-1URL\s0 to the server (like \f(CW\*(C`kxd://server/host1/key1\*(C'\fR), and it will print +on standard output the returned key (the contents of the corresponding key +file on the server). +.PP +There are scripts to tie this with cryptsetup's infrastructure to make the +opening of encrypted devices automatic; see \fBkxc\-cryptsetup\fR\|(1) for the +details. +.SH "OPTIONS" +.IX Header "OPTIONS" +.IP "\fB\-\-client_key\fR=\fIfile\fR" 8 +.IX Item "--client_key=file" +File containing the client private key (in \s-1PAM\s0 format). +.IP "\fB\-\-client_cert\fR=\fIfile\fR" 8 +.IX Item "--client_cert=file" +File containing the client certificate that corresponds to the given key (in +\&\s-1PAM\s0 format). +.IP "\fB\-\-server_cert\fR=\fIfile\fR" 8 +.IX Item "--server_cert=file" +File containing valid server certificate (in \s-1PAM\s0 format). +.SH "CONTACT" +.IX Header "CONTACT" +Main website . +.PP +If you have any questions, comments or patches please send them to +\&\f(CW\*(C`albertito@blitiri.com.ar\*(C'\fR. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fBkxc\-cryptsetup\fR\|(1), \fBkxd\fR\|(1). diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxc.1.pod kxd-0.14/doc/man/kxc.1.pod --- kxd-0.13+git20170730.6182dc8/doc/man/kxc.1.pod 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/kxc.1.pod 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,54 @@ +=head1 NAME + +kxc - Key exchange client + +=head1 SYNOPSIS + +B [I...] + + +=head1 DESCRIPTION + +kxc is a client for L, a key exchange daemon. + +It will take a client key and certificate, the expected server certificate, +and a URL to the server (like C), and it will print +on standard output the returned key (the contents of the corresponding key +file on the server). + +There are scripts to tie this with cryptsetup's infrastructure to make the +opening of encrypted devices automatic; see L for the +details. + + +=head1 OPTIONS + +=over 8 + +=item B<--client_key>=I + +File containing the client private key (in PAM format). + +=item B<--client_cert>=I + +File containing the client certificate that corresponds to the given key (in +PAM format). + +=item B<--server_cert>=I + +File containing valid server certificate (in PAM format). + +=back + + +=head1 CONTACT + +L
. + +If you have any questions, comments or patches please send them to +C. + + +=head1 SEE ALSO + +L, L. diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxc-cryptsetup.1 kxd-0.14/doc/man/kxc-cryptsetup.1 --- kxd-0.13+git20170730.6182dc8/doc/man/kxc-cryptsetup.1 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/kxc-cryptsetup.1 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,180 @@ +.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "kxc-cryptsetup 1" +.TH kxc-cryptsetup 1 "2019-08-10" "" "" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +kxc\-cryptsetup \- Cryptsetup helper to kxc +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +\&\fBkxc-cryptsetup\fR \fI\s-1NAME\s0\fR +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fBkxc\fR\|(1) is a client for \fBkxd\fR\|(1), a key exchange daemon. +.PP +kxc-cryptsetup is a convenience wrapper for invoking kxc while taking the +options from the files in \fI/etc/kxc/\fR. +.SH "OPTIONS" +.IX Header "OPTIONS" +Its only command-line argument is a descriptive name, which will be used to +find the configuration files. +.SH "FILES" +.IX Header "FILES" +For a given \fI\s-1NAME\s0\fR that is passed as the only command-line argument, the +following files are needed: +.IP "\fI/etc/kxc/NAME.key.pem\fR" 8 +.IX Item "/etc/kxc/NAME.key.pem" +Private key to use. +.IP "\fI/etc/kxc/NAME.cert.pem\fR" 8 +.IX Item "/etc/kxc/NAME.cert.pem" +Certificate to use. Must match the given key. +.IP "\fI/etc/kxc/NAME.server_cert.pem\fR" 8 +.IX Item "/etc/kxc/NAME.server_cert.pem" +Server certificate, used to validate the server. +.IP "\fI/etc/kxc/NAME.url\fR" 8 +.IX Item "/etc/kxc/NAME.url" +Contains the \s-1URL\s0 to the key; usually in the form of \f(CW\*(C`kxd://server/name\*(C'\fR. +.SH "CONTACT" +.IX Header "CONTACT" +Main website . +.PP +If you have any questions, comments or patches please send them to +\&\f(CW\*(C`albertito@blitiri.com.ar\*(C'\fR. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fBkxc\fR\|(1), \fBkxd\fR\|(1), \fBcrypttab\fR\|(5), \fBcryptsetup\fR\|(8). diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxc-cryptsetup.1.pod kxd-0.14/doc/man/kxc-cryptsetup.1.pod --- kxd-0.13+git20170730.6182dc8/doc/man/kxc-cryptsetup.1.pod 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/kxc-cryptsetup.1.pod 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,60 @@ +=head1 NAME + +kxc-cryptsetup - Cryptsetup helper to kxc + +=head1 SYNOPSIS + +B I + + +=head1 DESCRIPTION + +L is a client for L, a key exchange daemon. + +kxc-cryptsetup is a convenience wrapper for invoking kxc while taking the +options from the files in F. + + +=head1 OPTIONS + +Its only command-line argument is a descriptive name, which will be used to +find the configuration files. + + +=head1 FILES + +For a given I that is passed as the only command-line argument, the +following files are needed: + +=over 8 + +=item F + +Private key to use. + +=item F + +Certificate to use. Must match the given key. + +=item F + +Server certificate, used to validate the server. + +=item F + +Contains the URL to the key; usually in the form of C. + +=back + + +=head1 CONTACT + +L
. + +If you have any questions, comments or patches please send them to +C. + + +=head1 SEE ALSO + +L, L, L, L. diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxc-cryptsetup.rst kxd-0.14/doc/man/kxc-cryptsetup.rst --- kxd-0.13+git20170730.6182dc8/doc/man/kxc-cryptsetup.rst 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/doc/man/kxc-cryptsetup.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ - -================ - kxc-cryptsetup -================ - ------------------------- -Cryptsetup helper to kxc ------------------------- - -:Author: Alberto Bertogli -:Manual section: 1 - - -SYNOPSIS -======== - -kxc-cryptsetup - - -DESCRIPTION -=========== - -``kxc(1)`` is a client for kxd, a key exchange daemon. - -kxc-cryptsetup is a convenience wrapper for invoking kxc while taking the -options from the files in ``/etc/kxc/``. - -It can be used as a cryptsetup keyscript, to automatically get keys to open -encrypted devices with kxc. - - -OPTIONS -======= - -Its only command-line argument is a descriptive name, which will be used to -find the configuration files. - - -FILES -===== - -For a given *NAME* that is passed as the only command-line argument, the -following files are needed: - -/etc/kxc/NAME.key.pem - Private key to use. - -/etc/kxc/NAME.cert.pem - Certificate to use. Must match the given key. - -/etc/kxc/NAME.server_cert.pem - Server certificate, used to validate the server. - -/etc/kxc/NAME.url - Contains the URL to the key; usually in the form of ``kxd://server/name``. - - -SEE ALSO -======== - -``kxc(1)``, ``kxd(1)``, ``crypttab(5)``, ``cryptsetup(8)``. - - -BUGS -==== - -If you want to report bugs, or have any questions or comments, just let me -know. For more information, you can go to http://blitiri.com.ar/p/kxd. - diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxc.rst kxd-0.14/doc/man/kxc.rst --- kxd-0.13+git20170730.6182dc8/doc/man/kxc.rst 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/doc/man/kxc.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ - -===== - kxc -===== - -------------------- -Key exchange client -------------------- -:Author: Alberto Bertogli -:Manual section: 1 - - -SYNOPSIS -======== - -kxc --client_cert= --client_key= --server_cert= - - -DESCRIPTION -=========== - -kxc is a client for kxd, a key exchange daemon. - -It will take a client key and certificate, the expected server certificate, -and a URL to the server (like ``kxd://server/host1/key1``), and it will print -on standard output the returned key (the contents of the corresponding key -file on the server). - -There are scripts to tie this with cryptsetup's infrastructure to make the -opening of encrypted devices automatic; see ``kxc-cryptsetup(1)`` for the -details. - - -OPTIONS -======= - ---client_key= - File containing the client private key (in PAM format). - ---client_cert= - File containing the client certificate that corresponds to the given key (in - PAM format). - ---server_cert= - File containing valid server certificate(s). - - -SEE ALSO -======== - -``kxc-cryptsetup(1)``, ``kxd(1)``. - - -BUGS -==== - -If you want to report bugs, or have any questions or comments, just let me -know. For more information, you can go to http://blitiri.com.ar/p/kxd. - diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxd.1 kxd-0.14/doc/man/kxd.1 --- kxd-0.13+git20170730.6182dc8/doc/man/kxd.1 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/kxd.1 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,231 @@ +.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +. ds C` +. ds C' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is >0, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX +.. +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{\ +. if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. if !\nF==2 \{\ +. nr % 0 +. nr F 2 +. \} +. \} +.\} +.rr rF +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "kxd 1" +.TH kxd 1 "2019-08-10" "" "" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +kxd \- Key exchange daemon +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +\&\fBkxd\fR [\fIoptions\fR...] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +kxd is a key exchange daemon, which serves blobs of data (keys) over https. +.PP +It can be used to get keys remotely instead of using local storage. +The main use case is to get keys to open dm-crypt devices automatically, +without having to store them on the local machine. +.SH "SETUP" +.IX Header "SETUP" +The server configuration is stored in a root directory (\fI/etc/kxd/data/\fR by +default), and within there, with per-key directories (e.g. +\&\fI/etc/kxd/data/host1/key1/\fR), each containing the following files: +.IP "\fIkey\fR" 8 +.IX Item "key" +Contains the key to give to the client. +.IP "\fIallowed_clients\fR" 8 +.IX Item "allowed_clients" +Contains one or more PEM-encoded client certificates that will be allowed to +request the key. If not present, then no clients will be allowed to access +this key. +.IP "\fIallowed_hosts\fR" 8 +.IX Item "allowed_hosts" +Contains one or more host names (one per line). If not present, then all hosts +will be allowed to access that key (as long as they are authorized with a +valid client certificate). +.IP "\fIemail_to\fR" 8 +.IX Item "email_to" +Contains one or more email destinations to notify (one per line). If not +present, then no notifications will be sent upon key accesses. +.SH "OPTIONS" +.IX Header "OPTIONS" +.IP "\fB\-\-key\fR=\fIfile\fR" 8 +.IX Item "--key=file" +Private key to use (in \s-1PAM\s0 format). Defaults to \fI/etc/kxd/key.pem\fR. +.IP "\fB\-\-cert\fR=\fIfile\fR" 8 +.IX Item "--cert=file" +Certificate to use (in \s-1PAM\s0 format); must match the given key. Defaults to +\&\fI/etc/kxd/cert.pem\fR. +.IP "\fB\-\-data_dir\fR=\fIdirectory\fR" 8 +.IX Item "--data_dir=directory" +Data directory, where the key and configuration live (see the \s-1SETUP\s0 section +above). Defaults to \fI/etc/kxd/data\fR. +.IP "\fB\-\-ip_addr\fR=\fIip-address\fR" 8 +.IX Item "--ip_addr=ip-address" +\&\s-1IP\s0 address to listen on. Defaults to all. +.IP "\fB\-\-logfile\fR=\fIfile\fR" 8 +.IX Item "--logfile=file" +File to write logs to, use \*(L"\-\*(R" for stdout. By default, the daemon will log to +syslog. +.IP "\fB\-\-port\fR=\fIport\fR" 8 +.IX Item "--port=port" +Port to listen on. The default port is 19840. +.IP "\fB\-\-email_from\fR=\fIemail-address\fR" 8 +.IX Item "--email_from=email-address" +Email address to send email from. +.IP "\fB\-\-smtp_addr\fR=\fIhost:port\fR" 8 +.IX Item "--smtp_addr=host:port" +Address of the \s-1SMTP\s0 server to use to send emails. If none is given, then +emails will not be sent. +.IP "\fB\-\-hook\fR=\fIfile\fR" 8 +.IX Item "--hook=file" +Script to run before authorizing keys. Skipped if it doesn't exist. Defaults +to \fI/etc/kxd/hook\fR. +.SH "FILES" +.IX Header "FILES" +.IP "\fI/etc/kxd/key.pem\fR" 8 +.IX Item "/etc/kxd/key.pem" +Private key to use (in \s-1PAM\s0 format). +.IP "\fI/etc/kxd/cert.pem\fR" 8 +.IX Item "/etc/kxd/cert.pem" +Certificate to use (in \s-1PAM\s0 format); must match the given key. +.IP "\fI/etc/kxd/hook\fR" 8 +.IX Item "/etc/kxd/hook" +Script to run before authorizing keys. Skipped if it doesn't exist. +.IP "\fI/etc/kxd/data/\fR" 8 +.IX Item "/etc/kxd/data/" +Data directory, where the keys and their configuration live. +.SH "CONTACT" +.IX Header "CONTACT" +Main website . +.PP +If you have any questions, comments or patches please send them to +\&\f(CW\*(C`albertito@blitiri.com.ar\*(C'\fR. +.SH "SEE ALSO" +.IX Header "SEE ALSO" +\&\fBkxc\fR\|(1), \fBkxc\-cryptsetup\fR\|(1). diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxd.1.pod kxd-0.14/doc/man/kxd.1.pod --- kxd-0.13+git20170730.6182dc8/doc/man/kxd.1.pod 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/man/kxd.1.pod 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,131 @@ +=head1 NAME + +kxd - Key exchange daemon + +=head1 SYNOPSIS + +B [I...] + + +=head1 DESCRIPTION + +kxd is a key exchange daemon, which serves blobs of data (keys) over https. + +It can be used to get keys remotely instead of using local storage. +The main use case is to get keys to open dm-crypt devices automatically, +without having to store them on the local machine. + +=head1 SETUP + +The server configuration is stored in a root directory (F by +default), and within there, with per-key directories (e.g. +F), each containing the following files: + +=over 8 + +=item F + +Contains the key to give to the client. + +=item F + +Contains one or more PEM-encoded client certificates that will be allowed to +request the key. If not present, then no clients will be allowed to access +this key. + +=item F + +Contains one or more host names (one per line). If not present, then all hosts +will be allowed to access that key (as long as they are authorized with a +valid client certificate). + +=item F + +Contains one or more email destinations to notify (one per line). If not +present, then no notifications will be sent upon key accesses. + +=back + + +=head1 OPTIONS + +=over 8 + +=item B<--key>=I + +Private key to use (in PAM format). Defaults to F. + +=item B<--cert>=I + +Certificate to use (in PAM format); must match the given key. Defaults to +F. + +=item B<--data_dir>=I + +Data directory, where the key and configuration live (see the SETUP section +above). Defaults to F. + +=item B<--ip_addr>=I + +IP address to listen on. Defaults to all. + +=item B<--logfile>=I + +File to write logs to, use "-" for stdout. By default, the daemon will log to +syslog. + +=item B<--port>=I + +Port to listen on. The default port is 19840. + +=item B<--email_from>=I + +Email address to send email from. + +=item B<--smtp_addr>=I + +Address of the SMTP server to use to send emails. If none is given, then +emails will not be sent. + +=item B<--hook>=I + +Script to run before authorizing keys. Skipped if it doesn't exist. Defaults +to F. + +=back + + +=head1 FILES + +=over 8 + +=item F + +Private key to use (in PAM format). + +=item F + +Certificate to use (in PAM format); must match the given key. + +=item F + +Script to run before authorizing keys. Skipped if it doesn't exist. + +=item F + +Data directory, where the keys and their configuration live. + +=back + + +=head1 CONTACT + +L
. + +If you have any questions, comments or patches please send them to +C. + + +=head1 SEE ALSO + +L, L. diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/kxd.rst kxd-0.14/doc/man/kxd.rst --- kxd-0.13+git20170730.6182dc8/doc/man/kxd.rst 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/doc/man/kxd.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ - -===== - kxd -===== - -------------------- -Key exchange daemon -------------------- - -:Author: Alberto Bertogli -:Manual section: 1 - - -SYNOPSIS -======== - -kxd [--key=] [--cert=] [--data_dir=] -[--email_from=] [--ip_addr=] [--logfile=] -[--port=] [--smtp_addr=] - - -DESCRIPTION -=========== - -kxd is a key exchange daemon, which serves blobs of data (keys) over https. - -It can be used to get keys remotely instead of using local storage. -The main use case is to get keys to open dm-crypt devices automatically, -without having to store them on the local machine. - - -SETUP -===== - -The server configuration is stored in a root directory (``/etc/kxd/data/`` by -default), and within there, with per-key directories (e.g. -``/etc/kxd/data/host1/key1/``), each containing the following files: - - - ``key``: Contains the key to give to the client. - - ``allowed_clients``: Contains one or more PEM-encoded client certificates - that will be allowed to request the key. - If not present, then no clients will be allowed to access this key. - - ``allowed_hosts``: Contains one or more host names (one per line). - If not present, then all hosts will be allowed to access that key (as long - as they are authorized with a valid client certificate). - - ``email_to``: Contains one or more email destinations to notify (one per - line). If not present, then no notifications will be sent upon key - accesses. - - -OPTIONS -======= - ---key= - Private key to use. - Defaults to /etc/kxd/key.pem. - ---cert= - Certificate to use; must match the given key. - Defaults to /etc/kxd/cert.pem. - ---data_dir= - Data directory, where the key and configuration live (see the SETUP section - above). - Defaults to /etc/kxd/data. - ---email_from= - Email address to send email from. - ---ip_addr= - IP address to listen on. - Defaults to 0.0.0.0, which means all. - ---logfile= - File to write logs to, use '-' for stdout. - By default, the daemon will log to syslog. - ---port= - Port to listen on. - The default port is 19840. - ---smtp_addr= - Address of the SMTP server to use to send emails. - If none is given, then emails will not be sent. - - -FILES -===== - -/etc/kxd/key.pem - Private key to use for SSL. - -/etc/kxd/cert.pem - Certificate to use for SSL. Must match the given private key. - -/etc/kxd/data/ - Directory where the keys and their configuration are stored. - - -SEE ALSO -======== - -``kxc(1)``, ``kxc-cryptsetup(1)``. - - -BUGS -==== - -If you want to report bugs, or have any questions or comments, just let me -know. For more information, you can go to http://blitiri.com.ar/p/kxd. - diff -Nru kxd-0.13+git20170730.6182dc8/doc/man/Makefile kxd-0.14/doc/man/Makefile --- kxd-0.13+git20170730.6182dc8/doc/man/Makefile 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/doc/man/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ - -default: manpages - -%.1: %.rst - rst2man < $^ > $@ - -manpages: kxd.1 kxc.1 kxc-cryptsetup.1 - -clean: - rm -f kxd.1 kxc.1 kxc-cryptsetup.1 - diff -Nru kxd-0.13+git20170730.6182dc8/doc/quick_start.md kxd-0.14/doc/quick_start.md --- kxd-0.13+git20170730.6182dc8/doc/quick_start.md 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/doc/quick_start.md 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,112 @@ + +# Quick start + +In this guide we show how to set up a [key exchange daemon][kxd] and client +on a typical scenario where the keys are used to open a device encrypted with +[dm-crypt] \(the standard Linux disk encryption). + +These steps have been checked on a Debian install, other distributions should +be similar but may differ on some of the details (specially on the +[Configuring crypttab] section). + +- `server` is the hostname of the server. +- `client` is the hostname of the client. +- `sda2` is the encrypted drive. + + +## Server setup + +Install [kxd] on the server, via your distribution packages (e.g. `apt install +kxd`), or directly from source. + +Then, run `create-kxd-config`, which will create the configuration +directories, and generate a [self-signed] key/cert pair for the server (valid +for 10 years). +Everything is in `/etc/kxd/`. + + +## Client setup + +Install [kxc][kxd] on the client machine, via your distribution packages (e.g. +`apt install kxc`), or directly from source. + +Then, run `kxc-add-key server sda2`, which will create the configuration +directories, generate the client key/cert pair (valid for 10 years), and also +create an entry for an `client/sda2` key to be fetched from the server. +Everything is in `/etc/kxc/`. + +Finally, copy the server public certificate over, using +`scp server:/etc/kxd/cert.pem /etc/kxc/sda2.server_cert.pem` (or something +equivalent). + + +## Adding the key to the server + +On the server, run `kxd-add-client-key client sda2` to generate the basic +configuration for that client's key, including the key itself (generated +randomly). + +Then, copy the client public certificate over, using +`scp client:/etc/kxc/cert.pem /etc/kxd/data/client/sda2/allowed_clients` +(or something equivalent). + +That allows the client to fetch the key. + + +## Updating the drive's key + +On the client, run `kxc-cryptsetup sda2 | wc -c` to double-check that the +output length is as expected (you could also compare it by running sha256 or +something equivalent). + +Assuming that goes well, all you need is to add that key to your drives' key +ring so it can be decrypted with it: + +```shell +# Note we copy to /dev/shm which should not be written to disk. +kxc-cryptsetup sda2 > /dev/shm/key + +cryptsetup luksAddKey /dev/sda2 /dev/shm/key + +rm /dev/shm/key +``` + +Note this *adds* a new key, but your existing ones are still valid. Always +have more than one key, so if something goes wrong with kxd, you can still +unlock the drive manually. + + +## Configuring crypttab + +In order to get kxc to be run automatically to fetch the key, we need to edit +`/etc/crypttab` and tell it to use a keyscript: + +``` +sda2_crypt UUID=blah-blah-blah sda2 luks,keyscript=/usr/bin/kxc-cryptsetup + ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +``` + +Note the `sda2` field corresponds to the name we've been passing around in +previous sections. The `keyscript=/usr/bin/kxc-cryptsetup` option is our way +of telling the cryptsetup infrastructure to use our script to fetch the key +for this target. + + +You can test that this works by using: + +```shell +cryptdisks_stop sda2_crypt +cryptdisks_start sda2_crypt +``` + +The second command should issue a request to your server to get the key. + +Consider running `update-initramfs -u` if your device is the root device, or +it is needed very early in the boot process. + + +[kxd]: https://blitiri.com.ar/p/kxd +[kxc]: https://blitiri.com.ar/p/kxd +[dm-crypt]: https://en.wikipedia.org/wiki/dm-crypt +[self-signed]: https://en.wikipedia.org/wiki/Self-signed_certificate + diff -Nru kxd-0.13+git20170730.6182dc8/doc/quick_start.rst kxd-0.14/doc/quick_start.rst --- kxd-0.13+git20170730.6182dc8/doc/quick_start.rst 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/doc/quick_start.rst 1970-01-01 00:00:00.000000000 +0000 @@ -1,115 +0,0 @@ - -=================================== - Key Exchange Daemon - Quick start -=================================== - -In this guide we show how to set up a `key exchange daemon`_ and client -on a typical scenario where the keys are used to open a device encrypted with -dm-crypt_ (the standard Linux disk encryption). - -These steps have been checked on a Debian install, other distributions should -be similar but may differ on some of the details (specially on the -"`Configuring crypttab`_" section). - -- ``server`` is the hostname of the server. -- ``client`` is the hostname of the client. -- ``sda2`` is the encrypted drive. - - -Initial server setup -==================== - -First of all, install kxd_ on the server, usually via your distribution -packages, or directly from source. - -Then, run ``create-kxd-config``, which will create the configuration -directories, and generate a self-signed_ key/cert pair for the server (valid -for 10 years). -Everything is in ``/etc/kxd/``. - - -Initial client setup -==================== - -Install kxc_ on the client machine, usually via your distribution packages, or -directly from source. - - -Then, run ``kxc-add-key server sda2``, which will create the configuration -directories, generate the client key/cert pair (valid for 10 years), and also -create an entry for an ``client/sda2`` key to be fetched from the server. -Everything is in ``/etc/kxc/``. - -Finally, copy the server public certificate over, using -``scp server:/etc/kxd/cert.pem /etc/kxc/sda2.server_cert.pem`` (or something -equivalent). - - -Adding the key to the server -============================ - -On the server, run ``kxd-add-client-key client sda2`` to generate the basic -configuration for that client's key, including the key itself (generated -randomly). - -Then, copy the client public certificate over, using -``scp client:/etc/kxc/cert.pem /etc/kxd/data/client/sda2/allowed_clients`` -(or something equivalent). - -That allows the client to fetch the key. - - -Updating the drive's key -======================== - -On the client, run ``kxc-cryptsetup sda2 | wc -c`` to double-check that the -output length is as expected (you could also compare it by running sha256 or -something equivalent). - -Assuming that goes well, all you need is to add that key to your drives' key -ring so it can be decrypted with it:: - - # Note we copy to /dev/shm which should not be written to disk. - kxc-cryptsetup sda2 > /dev/shm/key - - cryptsetup luksAddKey /dev/sda2 /dev/shm/key - - rm /dev/shm/key - -Note this *adds* a new key, but your existing ones are still valid. Always -have more than one key, so if something goes wrong with kxd, you can still -unlock the drive manually. - - -Configuring crypttab -==================== - -In order to get kxc to be run automatically to fetch the key, we need to edit -``/etc/crypttab`` and tell it to use a keyscript:: - - sda2_crypt UUID=blah-blah-blah sda2 luks,keyscript=/usr/bin/kxc-cryptsetup - ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Note the ``sda2`` field corresponds to the name we've been passing around in -previous sections. The ``keyscript=/usr/bin/kxc-cryptsetup`` option is our way -of telling the cryptsetup infrastructure to use our script to fetch the key -for this target. - - -You can test that this works by using:: - - cryptdisks_stop sda2_crypt - cryptdisks_start sda2_crypt - -The second command should issue a request to your server to get the key. - -Consider running ``update-initramfs -u`` if your device is the root device, or -it is needed very early in the boot process. - - -.. _key exchange daemon: http://blitiri.com.ar/p/kxd -.. _kxd: http://blitiri.com.ar/p/kxd -.. _kxc: http://blitiri.com.ar/p/kxd -.. _dm-crypt: https://en.wikipedia.org/wiki/dm-crypt -.. _self-signed: https://en.wikipedia.org/wiki/Self-signed_certificate - diff -Nru kxd-0.13+git20170730.6182dc8/.gitignore kxd-0.14/.gitignore --- kxd-0.13+git20170730.6182dc8/.gitignore 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/.gitignore 2019-08-31 16:28:15.000000000 +0000 @@ -1,5 +1,6 @@ out/ *.swp +.* # Just in case, we ignore all .pem so noone commits them by accident. *.pem diff -Nru kxd-0.13+git20170730.6182dc8/kxc/kxc.go kxd-0.14/kxc/kxc.go --- kxd-0.13+git20170730.6182dc8/kxc/kxc.go 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/kxc/kxc.go 2019-08-31 16:28:15.000000000 +0000 @@ -35,7 +35,7 @@ pool := x509.NewCertPool() if !pool.AppendCertsFromPEM(pemData) { - return nil, fmt.Errorf("Error appending certificates") + return nil, fmt.Errorf("error appending certificates") } return pool, nil @@ -61,7 +61,7 @@ case "http", "kxd": serverURL.Scheme = "https" default: - return nil, fmt.Errorf("Unsupported URL schema (try kxd://)") + return nil, fmt.Errorf("unsupported URL schema (try kxd://)") } // The path must begin with /v1/, although we hide that from the user diff -Nru kxd-0.13+git20170730.6182dc8/kxd/key_config.go kxd-0.14/kxd/key_config.go --- kxd-0.13+git20170730.6182dc8/kxd/key_config.go 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/kxd/key_config.go 2019-08-31 16:28:15.000000000 +0000 @@ -9,17 +9,8 @@ "strings" ) -func fileStat(path string) (os.FileInfo, error) { - fd, err := os.Open(path) - if err != nil { - return nil, err - } - - return fd.Stat() -} - func isDir(path string) (bool, error) { - fi, err := fileStat(path) + fi, err := os.Stat(path) if err != nil { return false, err } @@ -28,7 +19,7 @@ } func isRegular(path string) (bool, error) { - fi, err := fileStat(path) + fi, err := os.Stat(path) if err != nil { return false, err } @@ -99,7 +90,7 @@ } if !kc.allowedClientCerts.AppendCertsFromPEM(rawContents) { - return fmt.Errorf("Error parsing client certificate file") + return fmt.Errorf("error parsing client certificate file") } return nil @@ -171,7 +162,7 @@ } } - return fmt.Errorf("Host %q not allowed", host) + return fmt.Errorf("host %q not allowed", host) } // Key returns the private key. diff -Nru kxd-0.13+git20170730.6182dc8/kxd/kxd.go kxd-0.14/kxd/kxd.go --- kxd-0.13+git20170730.6182dc8/kxd/kxd.go 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/kxd/kxd.go 2019-08-31 16:28:15.000000000 +0000 @@ -65,7 +65,7 @@ // We expect the path to be "/v1/path/to/key". if len(s) < 2 || !(s[0] == "" || s[1] == "v1") { - return "", fmt.Errorf("Invalid path %q", s) + return "", fmt.Errorf("invalid path %q", s) } return strings.Join(s[2:], "/"), nil diff -Nru kxd-0.13+git20170730.6182dc8/Makefile kxd-0.14/Makefile --- kxd-0.13+git20170730.6182dc8/Makefile 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/Makefile 2019-08-31 16:28:15.000000000 +0000 @@ -17,10 +17,10 @@ gofmt -w . vet: - $(GO) tool vet . + $(GO) vet ./... test: kxd kxc - python tests/run_tests -b + tests/run_tests -b tests: test diff -Nru kxd-0.13+git20170730.6182dc8/.mkdocs.yml kxd-0.14/.mkdocs.yml --- kxd-0.13+git20170730.6182dc8/.mkdocs.yml 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/.mkdocs.yml 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,9 @@ +site_name: kxd +docs_dir: doc +theme: readthedocs + +markdown_extensions: + - codehilite: + guess_lang: false + - attr_list + diff -Nru kxd-0.13+git20170730.6182dc8/README kxd-0.14/README --- kxd-0.13+git20170730.6182dc8/README 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ - -kxd - Key exchange daemon -========================= - -kxd is a key exchange daemon, which serves blobs of data (keys) over https. - -It can be used to get keys remotely instead of using local storage. -The main use case is to get keys to open dm-crypt devices automatically, -without having to store them on the local machine. - - -Quick start ------------ - -The document at doc/quick_start.rst contains a step by step guide of a typical -server and client setups. - - -Server configuration --------------------- - -The server configuration is stored in a root directory (/etc/kxd/data), and -within there, with per-key directories (e.g. /etc/kxd/data/host1/key1), each -containing the following files: - - - key: Contains the key to give to the client. - - allowed_clients: Contains one or more PEM-encoded client certificates that - will be allowed to request the key. - If not present, then no clients will be allowed to access this key. - - allowed_hosts: Contains one or more host names (one per line). - If not present, then all hosts will be allowed to access that key (as long - as they are authorized with a valid client certificate). - - email_to: Contains one or more email destinations to notify (one per line). - If not present, then no notifications will be sent upon key accesses. - - -Client configuration --------------------- - -The basic command line client (kxc) will take the client key and certificate, -the expected server certificate, and a URL to the server (like -kxd://server/host1/key1), and it will print on standard output the returned -key (the contents of the corresponding key file). - -There are scripts to tie this with cryptsetup's infrastructure to make the -opening of encrypted devices automatic; see cryptsetup/ for the details. - - -Security --------- - -All traffic between the server and the clients goes over SSL, using the -provided server certificate. - -The clients are authenticated and authorized based on their SSL client -certificates matching the ones associated with the key in the server -configuration, not using a root of trust (for now). - -Likewise, the clients will authenticate the server based on a certificate -given on the command line, and will only accept keys from it. - - -Note the server will return reasonably detailed information on errors, for -example it will tell when a key is not found vs. when the client is not -allowed. While this leaks some information about existence of keys, it makes -troubleshooting much easier. - -The server itself makes no effort to protect the data internally; for example, -there is no on-disk encryption, and memory is not locked. We work under the -assumption that the server's host is secure and trusted. - - -Dependencies ------------- - -There are no runtime dependencies for the kxd and kxc binaries. - -Building requires Go 1.7. - -The configuration helper scripts (create-kxd-config, kxc-add-key, etc.) -depend on: bash, openssl (the binary), and core utilities (mkdir, dd, etc.). - -Testing needs Python 2.7, and openssl (the binary). - - -Bugs and contact ----------------- - -Please report bugs to albertito@blitiri.com.ar. - -The latest version can be found at http://blitiri.com.ar/p/kxd/. - diff -Nru kxd-0.13+git20170730.6182dc8/README.md kxd-0.14/README.md --- kxd-0.13+git20170730.6182dc8/README.md 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/README.md 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,90 @@ + +# Key exchange daemon + +[kxd](https://blitiri.com.ar/p/kxd) is a key exchange daemon, and +corresponding client, which serves blobs of data (keys) over https. + +It can be used to get keys remotely instead of using local storage. +The main use case is to get keys to open dm-crypt devices automatically, +without having to store them on the local machine. + +[![Travis-CI build status](https://travis-ci.org/albertito/kxd.svg?branch=master)](https://travis-ci.org/albertito/kxd) + + +## Quick start + +Please see the [quick start](https://blitiri.com.ar/p/kxd/docs/quick_start) +document for a step by step guide of a typical server and client setups. + + +## Server configuration + +The server configuration is stored in a root directory (`/etc/kxd/data`), and +within there, with per-key directories (e.g. `/etc/kxd/data/host1/key1`), each +containing the following files: + +- `key`: Contains the key to give to the client. +- `allowed_clients`: Contains one or more PEM-encoded client certificates + that will be allowed to request the key. If not present, then no clients + will be allowed to access this key. +- `allowed_hosts`: Contains one or more host names (one per line). If not + present, then all hosts will be allowed to access that key (as long as they + are authorized with a valid client certificate). +- `email_to`: Contains one or more email destinations to notify (one per + line). If not present, then no notifications will be sent upon key + accesses. + + +## Client configuration + +The basic command line client (*kxc*) will take the client key and +certificate, the expected server certificate, and a URL to the server (like +`kxd://server/host1/key1`), and it will print on standard output the returned +key (the contents of the corresponding key file). + +There are scripts to tie this with cryptsetup's infrastructure to make the +opening of encrypted devices automatic; see `cryptsetup/` for the details. + + +## Security + +All traffic between the server and the clients goes over SSL, using the +provided server certificate. + +The clients are authenticated and authorized based on their SSL client +certificates matching the ones associated with the key in the server +configuration, not using a root of trust (for now). + +Likewise, the clients will authenticate the server based on a certificate +given on the command line, and will only accept keys from it. + +Note the server will return reasonably detailed information on errors, for +example it will tell when a key is not found vs. when the client is not +allowed. While this leaks some information about existence of keys, it makes +troubleshooting much easier. + +The server itself makes no effort to protect the data internally; for example, +there is no on-disk encryption, and memory is not locked. We work under the +assumption that the server's host is secure and trusted. + + +## Dependencies + +There are no runtime dependencies for the kxd and kxc binaries. + +Building requires Go 1.11. + +The configuration helper scripts (`create-kxd-config`, `kxc-add-key`, etc.) +depend on: `bash`, `openssl` (the binary), and core utilities (`mkdir`, `dd`, +etc.). + +Testing needs Python 3, and openssl (the binary). + + +## Bugs and contact + +Please report bugs to albertito@blitiri.com.ar. + +The latest version can be found at +[https://blitiri.com.ar/p/kxd/](https://blitiri.com.ar/p/kxd/) + diff -Nru kxd-0.13+git20170730.6182dc8/scripts/hook kxd-0.14/scripts/hook --- kxd-0.13+git20170730.6182dc8/scripts/hook 1970-01-01 00:00:00.000000000 +0000 +++ kxd-0.14/scripts/hook 2019-08-31 16:28:15.000000000 +0000 @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Example kxd hook, which uses the system's sendmail to send a notification +# via email. +# +# Note that if the script fails, kxd will NOT send the key. +# + +echo "Date: $(date --rfc-2822) +From: $MAIL_FROM +To: $EMAIL_TO +Subject: Access to key $KEY_PATH + +Key: $KEY_PATH +Accessed by: $REMOTE_ADDR +On: $(date) + +Client certificate: + Signature: ${CLIENT_CERT_SIGNATURE:0:40}... + Subject: $CLIENT_CERT_SUBJECT + +Authorizing chains: + $CHAIN_0 + $CHAIN_1 + $CHAIN_2 + +" | sendmail -t + +exit $? + diff -Nru kxd-0.13+git20170730.6182dc8/tests/run_tests kxd-0.14/tests/run_tests --- kxd-0.13+git20170730.6182dc8/tests/run_tests 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/tests/run_tests 2019-08-31 16:28:15.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ Tests for kxd and kxc @@ -10,26 +10,26 @@ client under various conditions, to make sure they behave as intended. """ -# NOTE: Please run "pylint --rcfile=.pylintrc run_tests" after making changes, +# NOTE: Please run "pylint3 --rcfile=.pylintrc run_tests" after making changes, # to make sure the file has a reasonably uniform coding style. # You can also use "autopep8 -d --ignore=E301,E26 run_tests" to help with # this, but make sure the output looks sane. import contextlib -import httplib +import http.client import os -import platform import shutil import socket import ssl import subprocess -import sys import tempfile import textwrap import time +import tracemalloc import unittest +tracemalloc.start() ############################################################ # Test infrastructure. @@ -81,7 +81,7 @@ os.chdir(prev) -class Config(object): +class Config: def __init__(self, name): self.path = tempfile.mkdtemp(prefix="config-%s-" % name, dir=TEMPDIR) self.name = name @@ -92,7 +92,7 @@ "-out", "%s/key.pem" % self.path, "2048"] subprocess.check_output(cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: - print "openssl call failed, output: %r" % err.output + print("openssl call failed, output: %r" % err.output) raise ouname = "kxd-tests-%s" % self.name @@ -108,7 +108,7 @@ try: subprocess.check_output(req_args, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: - print "openssl call failed, output: %r" % err.output + print("openssl call failed, output: %r" % err.output) raise def cert_path(self): @@ -121,10 +121,10 @@ return self.path + "/cert.csr" def cert(self): - return open(self.path + "/cert.pem").read() + return read_all(self.path + "/cert.pem") -class CA(object): +class CA: def __init__(self): self.path = tempfile.mkdtemp(prefix="config-ca-", dir=TEMPDIR) os.makedirs(self.path + "/kxd-ca/newcerts/") @@ -132,8 +132,9 @@ try: # We need to run the CA commands from within the path. with pushd(self.path): - open("kxd-ca/index.txt", "w") - open("kxd-ca/serial", "w").write("1000\n") + open("kxd-ca/index.txt", "w").close() + with open("kxd-ca/serial", "w") as serial: + serial.write("1000\n") subprocess.check_output( ["openssl", "req", "-new", "-x509", "-batch", "-config", OPENSSL_CONF, @@ -144,7 +145,7 @@ "-out", "cacert.pem"], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: - print "openssl call failed, output: %r" % err.output + print("openssl call failed, output: %r" % err.output) raise def sign(self, csr): @@ -156,14 +157,14 @@ "-in", csr, "-out", "%s.pem" % os.path.splitext(csr)[0]], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: - print "openssl call failed, output: %r" % err.output + print("openssl call failed, output: %r" % err.output) raise def cert_path(self): return self.path + "/cacert.pem" def cert(self): - return open(self.path + "/cacert.pem").read() + return read_all(self.path + "/cacert.pem") class ServerConfig(Config): @@ -177,17 +178,18 @@ key_path = self.path + "/data/" + name + "/" if not os.path.isdir(key_path): os.makedirs(key_path) - open(key_path + "key", "w").write(self.keys[name]) + with open(key_path + "key", "bw") as key: + key.write(self.keys[name]) if allowed_clients is not None: - cfd = open(key_path + "/allowed_clients", "a") - for cli in allowed_clients: - cfd.write(cli) + with open(key_path + "/allowed_clients", "a") as cfd: + for cli in allowed_clients: + cfd.write(cli) if allowed_hosts is not None: - hfd = open(key_path + "/allowed_hosts", "a") - for host in allowed_hosts: - hfd.write(host + "\n") + with open(key_path + "/allowed_hosts", "a") as hfd: + for host in allowed_hosts: + hfd.write(host + "\n") class ClientConfig(Config): @@ -202,10 +204,10 @@ "--server_cert=%s" % server_cert, url] try: - print "Running client:", " ".join(args) + print("Running client:", " ".join(args)) return subprocess.check_output(args, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: - print "Client call failed, output: %r" % err.output + print("Client call failed, output: %r" % err.output) raise @@ -215,12 +217,16 @@ "--key=%s/key.pem" % cfg, "--cert=%s/cert.pem" % cfg, "--logfile=%s/log" % cfg, - "--hook=%s/hook" % cfg - ] - print "Launching server: ", " ".join(args) + "--hook=%s/hook" % cfg] + print("Launching server: ", " ".join(args)) return subprocess.Popen(args) +def read_all(fname): + with open(fname) as fd: # pylint: disable=invalid-name + return fd.read() + + class TestCase(unittest.TestCase): def setUp(self): self.server = ServerConfig() @@ -228,11 +234,11 @@ self.daemon = None self.ca = None # pylint: disable=invalid-name self.launch_server(self.server) - self.longMessage = True def tearDown(self): if self.daemon: self.daemon.kill() + self.daemon.wait() def launch_server(self, server): self.daemon = launch_daemon(server.path) @@ -241,8 +247,9 @@ deadline = time.time() + 5 while time.time() < deadline: try: - socket.create_connection(("localhost", 19840), timeout=5) - break + with socket.create_connection( + ("localhost", 19840), timeout=5): + break except socket.error: continue else: @@ -258,7 +265,7 @@ try: client.call(cert_path, url) except subprocess.CalledProcessError as err: - self.assertRegexpMatches(err.output, regexp) + self.assertRegex(err.output.decode(), regexp) else: self.fail("Client call did not fail as expected") @@ -280,7 +287,7 @@ allowed_clients=[self.client.cert()], allowed_hosts=["localhost"]) key = self.client.call(self.server.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) # Unknown key -> 404. self.assertClientFails("kxd://localhost/k2", "404 Not Found") @@ -324,17 +331,17 @@ self.client.cert(), self.client2.cert()], allowed_hosts=["localhost"]) key = self.client.call(self.server.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) key = self.client2.call(self.server.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) # Only one client allowed. self.server.new_key("k2", allowed_clients=[self.client.cert()], allowed_hosts=["localhost"]) key = self.client.call(self.server.cert_path(), "kxd://localhost/k2") - self.assertEquals(key, self.server.keys["k2"]) + self.assertEqual(key, self.server.keys["k2"]) self.assertClientFails("kxd://localhost/k2", "403 Forbidden.*No allowed certificate found", @@ -351,11 +358,11 @@ for key in keys: data = self.client.call(self.server.cert_path(), "kxd://localhost/%s" % key) - self.assertEquals(data, self.server.keys[key]) + self.assertEqual(data, self.server.keys[key]) data = self.client2.call(self.server.cert_path(), "kxd://localhost/%s" % key) - self.assertEquals(data, self.server.keys[key]) + self.assertEqual(data, self.server.keys[key]) self.assertClientFails("kxd://localhost/a/b", "404 Not Found") @@ -368,58 +375,56 @@ # Write a file containing the certs of both servers. server_certs_path = self.client.path + "/server_certs.pem" server_certs = open(server_certs_path, "w") - server_certs.write(open(server1.cert_path()).read()) - server_certs.write(open(server2.cert_path()).read()) + server_certs.write(read_all(server1.cert_path())) + server_certs.write(read_all(server2.cert_path())) server_certs.close() key = self.client.call(server_certs_path, "kxd://localhost/k1") - self.assertEquals(key, server1.keys["k1"]) + self.assertEqual(key, server1.keys["k1"]) self.daemon.kill() + self.daemon.wait() time.sleep(0.5) self.launch_server(server2) key = self.client.call(server_certs_path, "kxd://localhost/k1") - self.assertEquals(key, server2.keys["k1"]) + self.assertEqual(key, server2.keys["k1"]) class TrickyRequests(TestCase): """Tests for tricky requests.""" - def HTTPSConnection(self, host, port, key_file=None, cert_file=None): - # httplib.HTTPSConnection() wrapper that works with versions before - # and after Python 2.7.9, which introduced default server validation - # with no backwards-compatible way of turning it off. - if sys.hexversion < 0x2070900: - return httplib.HTTPSConnection( - host, port, key_file=key_file, cert_file=cert_file) - + def https_connection(self, host, port, key_file=None, cert_file=None): # Get an SSL context that can validate our server certificate. context = ssl.create_default_context(cafile=self.server.cert_path()) - return httplib.HTTPSConnection( - host, port, key_file=key_file, cert_file=cert_file, - context=context) - - def test_tricky(self): - # No local certificate. - conn = self.HTTPSConnection("localhost", 19840) + context.check_hostname = False + if cert_file: + context.load_cert_chain(cert_file, key_file) + return http.client.HTTPSConnection(host, port, context=context) + + def test_no_local_cert(self): + """No local certificate.""" + conn = self.https_connection("localhost", 19840) try: conn.request("GET", "/v1/") + conn.close() except ssl.SSLError as err: - self.assertRegexpMatches(str(err), "alert bad certificate") + self.assertEqual(err.reason, "SSLV3_ALERT_BAD_CERTIFICATE") else: self.fail("Client call did not fail as expected") - # Requests with '..'. - conn = self.HTTPSConnection("localhost", 19840, - key_file=self.client.key_path(), - cert_file=self.client.cert_path()) + def test_path_with_dotdot(self): + """Requests with '..'.""" + conn = self.https_connection("localhost", 19840, + key_file=self.client.key_path(), + cert_file=self.client.cert_path()) conn.request("GET", "/v1/a/../b") response = conn.getresponse() + conn.close() # Go's http server intercepts these and gives us a 301 Moved # Permanently. - self.assertEquals(response.status, 301) + self.assertEqual(response.status, 301) def test_server_cert(self): rawsock = socket.create_connection(("localhost", 19840)) @@ -433,7 +438,8 @@ server_cert = ssl.DER_cert_to_PEM_cert( sock.getpeercert(binary_form=True)) - self.assertEquals(server_cert, self.server.cert()) + self.assertEqual(server_cert, self.server.cert()) + sock.close() class BrokenServerConfig(TestCase): @@ -445,11 +451,9 @@ allowed_hosts=["localhost"]) # Corrupt the client certificate. - cfd = open(self.server.path + "/data/k1/allowed_clients", "r+") - for _ in range(5): - cfd.readline() - cfd.write('+/+BROKEN+/+') - cfd.close() + with open(self.server.path + "/data/k1/allowed_clients", "tr+") as cfd: + cfd.seek(30) + cfd.write('+/+BROKEN+/+') self.assertClientFails( "kxd://localhost/k1", @@ -498,16 +502,12 @@ # Successful request. key = self.client.call(self.ca.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) # The server is signed by the CA, but the CA is unknown to the client. # But the client knows the server directly, so it's allowed. - # - # NOTE: go <= 1.7 rejected this case, it was only allowed during the - # 1.8 development cycle (8ad70a5), so comment it out for now. - # - #key = self.client.call(self.server.cert_path(), "kxd://localhost/k1") - #self.assertEquals(key, self.server.keys["k1"]) + key = self.client.call(self.server.cert_path(), "kxd://localhost/k1") + self.assertEqual(key, self.server.keys["k1"]) # Same as above, but give the wrong CA. ca2 = CA() @@ -523,7 +523,7 @@ allowed_clients=[self.ca.cert()], allowed_hosts=["localhost"]) key = self.client.call(self.server.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) # The CA signing the client is unknown to the server. ca2 = CA() @@ -536,15 +536,11 @@ # The client is signed by the CA, but the CA is unknown to the server. # But the server it knows the client directly, so it's allowed. - # - # NOTE: go <= 1.7 rejected this case, it was only allowed during the - # 1.8 development cycle (8ad70a5), so comment it out for now. - # - #self.server.new_key("k3", - # allowed_clients=[self.client.cert()], - # allowed_hosts=["localhost"]) - #key = self.client.call(self.server.cert_path(), "kxd://localhost/k3") - #self.assertEquals(key, self.server.keys["k3"]) + self.server.new_key("k3", + allowed_clients=[self.client.cert()], + allowed_hosts=["localhost"]) + key = self.client.call(self.server.cert_path(), "kxd://localhost/k3") + self.assertEqual(key, self.server.keys["k3"]) def test_both_delegated(self): self.prepare(server_self_sign=False, client_self_sign=False) @@ -553,7 +549,7 @@ allowed_hosts=["localhost"]) key = self.client.call(self.ca.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) class Hook(TestCase): @@ -570,8 +566,9 @@ path = self.server.path + "/hook" script = self.HOOK_SCRIPT_TMPL.format(exit_code=exit_code) - open(path, "w").write(script) - os.chmod(path, 0770) + with open(path, "w") as hook: + hook.write(script) + os.chmod(path, 0o770) def test_simple(self): self.write_hook(exit_code=0) @@ -581,9 +578,9 @@ allowed_clients=[self.client.cert()], allowed_hosts=["localhost"]) key = self.client.call(self.server.cert_path(), "kxd://localhost/k1") - self.assertEquals(key, self.server.keys["k1"]) + self.assertEqual(key, self.server.keys["k1"]) - hook_out = open(self.server.path + "/data/hook-output").read() + hook_out = read_all(self.server.path + "/data/hook-output") self.assertIn("CLIENT_CERT_SUBJECT=OU=kxd-tests-client", hook_out) # Failure caused by the hook exiting with error. @@ -592,7 +589,7 @@ # Failure caused by the hook not being executable. self.write_hook(exit_code=0) - os.chmod(self.server.path + "/hook", 0660) + os.chmod(self.server.path + "/hook", 0o660) self.assertClientFails("kxd://localhost/k1", "Prevented by hook") diff -Nru kxd-0.13+git20170730.6182dc8/.travis.yml kxd-0.14/.travis.yml --- kxd-0.13+git20170730.6182dc8/.travis.yml 2017-07-30 17:05:34.000000000 +0000 +++ kxd-0.14/.travis.yml 2019-08-31 16:28:15.000000000 +0000 @@ -4,14 +4,13 @@ go_import_path: blitiri.com.ar/go/kxd go: - - 1.7 # Debian stable relies on this. - - 1.8 + - 1.11 # Debian stable. - tip addons: apt: packages: - - python + - python3 - openssl # Nothing to do for install, the tests will build the binaries anyway.