Umgestellt auf OO-Perl. Wrapper fuer einfachen Aufruf gebastelt.
[ssh-keysync.git] / files / ssh-keysync-merge
1 #!/bin/bash
2 #
3 # ssh-keysync-merge
4 #
5 # Merge the client ssh host keys to one file
6 #
7 # Maximilian Wilhelm <mwilhelm@math.uni-paderborn.de>
8 #  -- Sat, 17 Apr 2004 17:21:09 +0200
9 #
10
11
12 # Be verbose by default
13 debug=1
14
15 # Environment (to be checked!)
16 CONFIG_FILE="/etc/rbm/ssh-keysync-server.conf"
17 BASE_DIR="/var/cache/ssh-keysync"
18 KEY_FILES_DIR="${BASE_DIR}/keys"
19 KNOWN_HOSTS="${BASE_DIR}/ssh_known_hosts"
20 KNOWN_HOSTS_OLD="${KNOWN_HOSTS}.old"
21
22 VALID_USER="skeysync"
23
24 # Check some things
25 init()
26 {
27         if [ -f ${CONFIG_FILE} -a -r ${CONFIG_FILE} ]; then
28                 if ! source ${CONFIG_FILE}; then
29                         echo "Failed to load config file \"${CONFIG_FILE}\", exiting." >&2
30                         exit 1
31                 fi
32         else
33                 echo "Unable to load config file \"${CONFIG_FILE}\". File does not exist or is not accessable, exiting." >&2
34                 exit 1;
35         fi
36
37
38         # Who has called us?
39         if [ `whoami` != "${VALID_USER}" ]; then
40                 echo "Script `basename $0` can only be run as user \"${VALID_USER}\"." >&2
41                 exit 1;
42         fi
43
44         # Is there room for us?
45         for dir in "${BASE_DIR}" "${KEY_FILES_DIR}"; do
46                 if [ ! -d "${dir}" ]; then
47                         echo "The directory ${dir} does not exist, but is neccessary for this script to work!" >&2
48                         echo -n "Please create ${dir}" >&2
49                         [ "${dir}" == "${BASE_DIR}" ] && echo " and allow user '${VALID_USER}' to write there." >&2
50                         echo ""
51                         exit 1;
52                 fi
53         done
54
55         # DOMAIN_LIST given?
56         if [ -z "${DOMAIN_LIST}" ]; then
57                 echo "Error: DOMAIN_LIST not set in $0!" >&2
58                 echo "Please edit ${CONFIG_FILE} an set DOMAIN_LIST to the correct value." >&2
59                 exit 1
60         fi
61 }
62
63
64 # Merge all client host keys
65 merge()
66 {
67         if [ `ls "${KEY_FILES_DIR}"/*.key 2>/dev/null | wc -l` == 0 ]; then
68                 echo "No client host keys available, aborting" >&2
69                 exit 0;
70         else
71
72                 [ "${debug}" ] && echo -n "Merging client hosts keys "
73
74
75                 # create an empty file, if there is no known_hosts file
76                 [ ! -f "${KNOWN_HOSTS}" ] && touch "${KNOWN_HOSTS}"
77                 # Make backup of old ssh_known_hosts file
78                 mv "${KNOWN_HOSTS}" "${KNOWN_HOSTS_OLD}"
79                 [ "${debug}" ] && echo -n "."
80
81
82                 # Go to the working directory
83                 cd "${KEY_FILES_DIR}"
84                 [ "${debug}" ] && echo -n ". "
85
86
87                 echo "# ssh_known_hosts generated by ssh-keysync-merge at "$(date +%d.%m.%Y) > ${KNOWN_HOSTS}
88                 echo "# " >> "${KNOWN_HOSTS}"
89
90                 # Building new one
91                 for file in *.key; do
92                         convert_file "${file}" >> "${KNOWN_HOSTS}"
93                         [ "${debug}" ] && echo -n "."
94                 done
95
96                 [ "${debug}" ] && echo " done."
97         fi
98 }
99
100
101
102 # convert host key into the right format
103 #
104 # convert_file <hostname>.<keytype>
105 convert_file()
106 {
107         if [ $# == 1 ]; then
108                 # get all needed information
109                 HOST=$(echo $1 | cut -d. -f1);
110                 IP=`host ${HOST} | awk '{ print $NF }'`
111
112                 expr="s/,/,${HOST}./g"
113 #               HOSTNAMES="${HOST},${HOST}."`echo ${DOMAIN_LIST} | tr -d '[:space:]' | sed -e "${expr}"`",${IP}"
114                 HOSTNAMES="${HOST},${HOST}.`echo ${DOMAIN_LIST} | sed -e ${expr}`,${IP}"
115
116                 # make sure that ${HOSTNAMES} does not include any white spaces
117                 # and appand one white space at the end of ${HOSTNAMES}, to
118                 # seperate the following key
119                 echo -n ${HOSTNAMES} | tr -d '[:space:]'
120                 echo -n " "
121                 cat "${1}"
122         else
123                 echo "Usage: convert_file <hostname>.<type>" >&2
124         fi
125 }
126
127 # Compare present and last version of ssh_known_hosts
128 diff_files()
129 {
130         [ "${debug}" ] && echo -n "Comparing present and last version of knonw_hosts: "
131
132         # Create a tempfile
133         TEMPFILE=`tempfile -d /tmp -s skeysync`
134         touch "${TEMPFILE}"
135
136         # one first run, there will not be an old file
137         if [ ! -f "${KNOWN_HOSTS_OLD}" ]; then
138                 touch "${KNOWN_HOSTS_OLD}"
139         fi
140
141         diff -u "${KNOWN_HOSTS_OLD}" "${KNOWN_HOSTS}" > "${TEMPFILE}"
142
143         if [ -s "${TEMPFILE}" ]; then
144         # There are differences...
145             if [ `grep -c '^-# ssh_known_hosts\|^+# ssh_known_hosts' "${TEMPFILE}"` == 2 ]; then
146                 echo "Attention: Files are different!"
147                 echo "==============================="
148                 echo ""
149                 cat "${TEMPFILE}"
150                 rm "${TEMPFILE}"
151                 return 1
152             fi
153         else
154         # Nothing changed
155                 [ "${debug}" ] && echo "equal."
156                 "rm ${TEMPFILE}"
157                 return 0
158         fi
159
160 }
161
162
163 # Put ssh_known_hosts file in public web dir
164 publish()
165 {
166         [ "${debug}" ] && echo -n "Putting ssh_known_hosts into web directory: "
167         cp "${KNOWN_HOSTS}" "${BASE_DIR}/pub"
168         [ "${debug}" ] && echo " done."
169 }
170
171
172 # Print a little help message
173 help()
174 {
175         echo "Usage: $0 [ -quiet ] [ -help ]"
176         echo " -quiet   Only show warnings"
177         echo " -help    Print this help"
178         exit 0
179 }
180
181 # What to do
182 while [ $# -gt 0 ]; do
183     case "$1" in
184         -quiet) unset debug ;;
185         -help)  help ;;
186         *)      help;;
187     esac
188     shift
189 done
190
191 #
192 # Let the show begin
193 #
194
195 # everything ok?
196 init
197
198 # build the file
199 merge
200
201 # publish it 
202 publish
203
204 # if file has changed, send mail
205 diff_files