1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#!/bin/bash
die() { printf 'Error: %s\n' "$*" >&2; exit 1; }
warn() { printf 'Warning: %s\n' "$*" >&2; }
sql_string()
{
printf '%s' "'${1//\'/\'\'}'"
}
powerdns_sqlite_add_replace_record()
{
local sql_record_type="$(sql_string "$2")"
local sql_ip_address="$(sql_string "$3")"
zone=cryptonomic.net
new_name=${label:+$label.}${1: -64 : 64}
local sql_new_name="$(sql_string "$new_name")"
local sql_zone="$(sql_string "$zone")"
local sql_sshfp="$(sql_string "$SSH_CLIENT_SSHFP_DATA")"
if false
then
pdnsutil create-zone "$zone"
pdnsutil add-record "$zone" "$new_name" "$2" "$3"
return
fi
DBDIR=/etc/powerdns
DBNAME=powerdns.sqlite3
DB=$DBDIR/$DBNAME
test -r $DB && test -w $DB || die "Wrong permissions on $DB"
test -r $DBDIR && test -w $DBDIR || die "Wrong permissions on $DBDIR"
sqlite3 $DB <<END
${SQL_ECHO:+.echo on}
BEGIN;
DELETE FROM records WHERE name=$sql_new_name;
INSERT INTO records
(domain_id,
name,
type,
content,
ttl,
prio)
SELECT
id,
$sql_new_name,
$sql_record_type,
$sql_ip_address,
600,
0
FROM domains
WHERE name=$sql_zone;
INSERT INTO records
(domain_id,
name,
type,
content,
ttl,
prio)
SELECT
id,
$sql_new_name,
'SSHFP',
$sql_sshfp,
600,
0
FROM domains
WHERE name=$sql_zone;
COMMIT;
END
r=$?
[ $r = 0 ] || return $r
printf '%s %s\n' "$new_name" "$3"
}
add()
{
local label=
if [ $# = 3 ]
then
label=$1
shift
fi
local record_type ip="$2"
case "$ip" in
*.*.*.*) record_type=A ;;
*:*) record_type=AAAA ;;
*) exit 1 ;;
esac
powerdns_sqlite_add_replace_record "$domain" "$record_type" "$ip"
}
validate_ssh_server()
{
e=$(mktemp)
ssh-keyscan -t "$SSH_CLIENT_KEYTYPE" "$ip_address" | grep -q " $SSH_CLIENT_KEYDATA\$" 2>"$e"
if [ $? = 0 ]
then
rm "$e"
return 0
else
cat "$e" >&2
rm "$e"
false
fi
}
validate_dns_label()
{
if [ $#1 -gt 64 ]
then
warn "ignored DNS label: too long"
return 1
fi
case "$1" in
-*|*--*|*-)
warn 'ignored DNS label: invalid use of hyphens'
return 2
;;
*[^-A-Za-z0-9]*)
warn 'ignored DNS label: invalid character'
return 3
;;
esac
true
}
main()
{
validate_ssh_server "$ip_address" || return
add "$domain" "$ip_address"
for label in $SSH_ORIGINAL_COMMAND
do
validate_dns_label "$label" || continue
add "$label" "$domain" "$ip_address"
done
}
PEM_DEST=$HOME/public_rsync
eval "$(samizdat-ssh-uid --copy-pem "$PEM_DEST")"
[ "$SSH_CLIENT_SSHFP_DATA" ] || die wtf
domain=${SSH_CLIENT_DOMAIN}
ip_address=${SSH_CLIENT%% *}
main "$@"
|