1#!/bin/sh
2#
3#  "$Id: bonjour-tests.sh 12142 2014-08-30 02:35:43Z msweet $"
4#
5# IPP Everywhere Printer Self-Certification Manual 1.0: Section 5: Bonjour Tests.
6#
7# Copyright 2014 by The Printer Working Group.
8#
9# This program may be copied and furnished to others, and derivative works
10# that comment on, or otherwise explain it or assist in its implementation may
11# be prepared, copied, published and distributed, in whole or in part, without
12# restriction of any kind, provided that the above copyright notice and this
13# paragraph are included on all such copies and derivative works.
14#
15# The IEEE-ISTO and the Printer Working Group DISCLAIM ANY AND ALL WARRANTIES,
16# WHETHER EXPRESS OR IMPLIED INCLUDING (WITHOUT LIMITATION) ANY IMPLIED
17# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18#
19# Usage:
20#
21#   ./bonjour-tests.sh "Printer Name"
22#
23
24if test -x ../test/ippfind-static; then
25	IPPFIND="../test/ippfind-static"
26elif test -x ./ippfind; then
27	IPPFIND="./ippfind"
28else
29	IPPFIND="ippfind"
30fi
31
32if test -x ../test/ipptool-static; then
33	IPPTOOL="../test/ipptool-static"
34elif test -x ./ipptool; then
35	IPPTOOL="./ipptool"
36else
37	IPPTOOL="ipptool"
38fi
39
40PLIST="$1 Bonjour Results.plist"
41
42#
43# Figure out the proper echo options...
44#
45
46if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
47        ac_n=-n
48        ac_c=
49else
50        ac_n=
51        ac_c='\c'
52fi
53
54# Special case "_failN" name to show bad/missing TXT keys
55if test "$2" = _fail2 -o "$2" = _fail4 -o "$2" = _fail5.3 -o "$2" = _fail5.5; then
56	echo "FAIL"
57	echo "<key>Errors</key><array>" >>"$PLIST"
58	if test "${IPPFIND_TXT_ADMINURL:-NOTSET}" = NOTSET; then
59		echo "   adminurl is not set."
60		echo "<string>adminurl is not set.</string>" >>"$PLIST"
61	elif test "$2" = _fail4 -o "$2" = _fail5.5; then
62		case "$IPPFIND_TXT_ADMINURL" in
63			http://* | https://*)
64				;;
65			*)
66				echo "   adminurl has bad value '$IPPFIND_TXT_ADMINURL'."
67				echo "<string>adminurl has bad value '$IPPFIND_TXT_ADMINURL'.</string>" >>"$PLIST"
68				;;
69		esac
70	fi
71
72	if test "${IPPFIND_TXT_PDL:-NOTSET}" = NOTSET; then
73		echo "   pdl is not set."
74		echo "<string>pdl is not set.</string>" >>"$PLIST"
75	elif test "$2" = _fail4 -o "$2" = _fail5.5; then
76		case "$IPPFIND_TXT_PDL" in
77			*image/jpeg*)
78				;;
79			*)
80				echo "   pdl is missing image/jpeg: '$IPPFIND_TXT_PDL'"
81				echo "<string>pdl is missing image/jpeg: '$IPPFIND_TXT_PDL'.</string>" >>"$PLIST"
82				;;
83		esac
84
85		case "$IPPFIND_TXT_PDL" in
86			*image/pwg-raster*)
87				;;
88			*)
89				echo "   pdl is missing image/pwg-raster: '$IPPFIND_TXT_PDL'"
90				echo "<string>pdl is missing image/pwg-raster: '$IPPFIND_TXT_PDL'.</string>" >>"$PLIST"
91				;;
92		esac
93	fi
94
95	if test "${IPPFIND_TXT_RP:-NOTSET}" = NOTSET; then
96		echo "   rp is not set."
97		echo "<string>rp is not set.</string>" >>"$PLIST"
98	elif test "$2" = _fail4 -o "$2" = _fail5.5; then
99		case "$IPPFIND_TXT_RP" in
100			ipp/print | ipp/print/*)
101				;;
102			*)
103				echo "   rp has bad value '$IPPFIND_TXT_RP'"
104				echo "<string>rp has bad value '$IPPFIND_TXT_RP'.</string>" >>"$PLIST"
105				;;
106		esac
107	fi
108
109	if test "${IPPFIND_TXT_UUID:-NOTSET}" = NOTSET; then
110		echo "   UUID is not set."
111		echo "<string>UUID is not set.</string>" >>"$PLIST"
112	elif test "$2" = _fail4 -o "$2" = _fail5.5; then
113		case "$IPPFIND_TXT_UUID" in
114			[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
115				;;
116			*)
117				echo "   UUID has bad value '$IPPFIND_TXT_UUID'"
118				echo "<string>UUID has bad value '$IPPFIND_TXT_UUID'.</string>" >>"$PLIST"
119				;;
120		esac
121	fi
122
123	if test "$2" = _fail4 -o "$2" = _fail5.5; then
124		$IPPTOOL -t -d "ADMINURL=$IPPFIND_TXT_ADMINURL" -d "UUID=$IPPFIND_TXT_UUID" $IPPFIND_SERVICE_URI bonjour-value-tests.test
125		$IPPTOOL -t -d "ADMINURL=$IPPFIND_TXT_ADMINURL" -d "UUID=$IPPFIND_TXT_UUID" $IPPFIND_SERVICE_URI bonjour-value-tests.test | egrep '(GOT|EXPECTED):' | sed -e '1,$s/^[ 	]*//' | awk '{print "<string>" $0 "</string>" }' >>"$PLIST"
126	fi
127
128	echo "</array>" >>"$PLIST"
129	echo "<key>Successful</key><false />" >>"$PLIST"
130	echo "</dict>" >>"$PLIST"
131
132	exit 0
133fi
134
135
136# Write the standard XML plist header...
137cat >"$PLIST" <<EOF
138<?xml version="1.0" encoding="UTF-8"?>
139<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
140<plist version="1.0">
141<dict>
142<key>Tests</key><array>
143EOF
144
145total=0
146pass=0
147fail=0
148skip=0
149
150# start_test "name"
151start_test() {
152	total=`expr $total + 1`
153	echo $ac_n "$1: $ac_c"
154	echo "<dict><key>Name</key><string>$1</string>" >>"$PLIST"
155	echo "<key>FileId</key><string>org.pwg.ipp-everywhere.20140826.bonjour</string>" >>"$PLIST"
156}
157# end_test PASS/FAIL/SKIP
158end_test() {
159	echo $1
160	if test $1 = FAIL; then
161		echo "<key>Successful</key><false />" >>"$PLIST"
162	elif test $1 = SKIP; then
163		echo "<key>Successful</key><true />" >>"$PLIST"
164		echo "<key>Skipped</key><true />" >>"$PLIST"
165	else
166		echo "<key>Successful</key><true />" >>"$PLIST"
167	fi
168	echo "</dict>" >>"$PLIST"
169}
170
171# B-1. IPP Browse test: Printers appear in a search for "_ipp._tcp,_print" services?
172start_test "B-1. IPP Browse test"
173$IPPFIND _ipp._tcp,_print.local. --name "$1" --quiet
174if test $? = 0; then
175	pass=`expr $pass + 1`
176	end_test PASS
177else
178	fail=`expr $fail + 1`
179	end_test FAIL
180fi
181
182# B-2. IPP TXT keys test: The IPP TXT record contains all required keys.
183start_test "B-2. IPP TXT keys test"
184$IPPFIND "$1._ipp._tcp.local." --txt adminurl --txt pdl --txt rp --txt UUID --quiet
185if test $? = 0; then
186	pass=`expr $pass + 1`
187	end_test PASS
188else
189	fail=`expr $fail + 1`
190	$IPPFIND "$1._ipp._tcp.local." -x ./bonjour-tests.sh '{service_name}' _fail2 \;
191fi
192
193# B-3. IPP Resolve test: Printer responds to an IPP Get-Printer-Attributes request using the resolved hostname, port, and resource path.
194start_test "B-3. IPP Resolve test"
195$IPPFIND "$1._ipp._tcp.local." --ls >/dev/null
196if test $? = 0; then
197	pass=`expr $pass + 1`
198	end_test PASS
199else
200	fail=`expr $fail + 1`
201	echo "<key>Errors</key><array>" >>"$PLIST"
202	$IPPFIND "$1._ipp._tcp.local." --ls | awk '{ print "<string>" $0 "</string>" }' >>"$PLIST"
203	echo "</array>" >>"$PLIST"
204	end_test FAIL
205fi
206
207# B-4. IPP TXT values test: The IPP TXT record values match the reported IPP attribute values.
208start_test "B-4. IPP TXT values test"
209$IPPFIND "$1._ipp._tcp.local." --txt-adminurl '^(http:|https:)//' --txt-pdl 'image/pwg-raster' --txt-pdl 'image/jpeg' --txt-rp '^ipp/(print|print/[^/]+)$' --txt-UUID '^[0-9a-fA-F]{8,8}-[0-9a-fA-F]{4,4}-[0-9a-fA-F]{4,4}-[0-9a-fA-F]{4,4}-[0-9a-fA-F]{12,12}$' -x $IPPTOOL -q -d 'ADMINURL={txt_adminurl}' -d 'UUID={txt_uuid}' '{}' bonjour-value-tests.test \;
210if test $? = 0; then
211	pass=`expr $pass + 1`
212	end_test PASS
213else
214	fail=`expr $fail + 1`
215	$IPPFIND "$1._ipp._tcp.local." -x ./bonjour-tests.sh '{service_name}' _fail4 \;
216fi
217
218# B-5. TLS tests: Performed only if TLS is supported
219start_test "B-5. TLS tests"
220$IPPFIND "$1._ipp._tcp.local." --txt tls --quiet
221if test $? = 0; then
222	pass=`expr $pass + 1`
223	HAVE_TLS=1
224	end_test PASS
225else
226	skip=`expr $skip + 1`
227	HAVE_TLS=0
228	end_test SKIP
229fi
230
231# B-5.1 HTTP Upgrade test: Printer responds to an IPP Get-Printer-Attributes request after doing an HTTP Upgrade to TLS.
232start_test "B-5.1 HTTP Upgrade test"
233if test $HAVE_TLS = 1; then
234	error=`$IPPFIND "$1._ipp._tcp.local." -x $IPPTOOL -E -q '{}' bonjour-access-tests.test \; 2>&1`
235	if test $? = 0; then
236		pass=`expr $pass + 1`
237		end_test PASS
238	else
239		fail=`expr $fail + 1`
240		echo "<key>Errors</key><array><string>$error</string></array>" >>"$PLIST"
241
242		end_test FAIL
243		echo "    $error"
244	fi
245else
246	skip=`expr $skip + 1`
247	end_test SKIP
248fi
249
250# B-5.2 IPPS Browse test: Printer appears in a search for "_ipps._tcp,_print" services.
251start_test "B-5.2 IPPS Browse test"
252if test $HAVE_TLS = 1; then
253	$IPPFIND _ipps._tcp,_print.local. --name "$1" --quiet
254	if test $? = 0; then
255		pass=`expr $pass + 1`
256		end_test PASS
257	else
258		fail=`expr $fail + 1`
259		end_test FAIL
260	fi
261else
262	skip=`expr $skip + 1`
263	end_test SKIP
264fi
265
266# B-5.3 IPPS TXT keys test: The TXT record for IPPS contains all required keys
267start_test "B-5.3 IPPS TXT keys test"
268if test $HAVE_TLS = 1; then
269	$IPPFIND "$1._ipps._tcp.local." --txt adminurl --txt pdl --txt rp --txt TLS --txt UUID --quiet
270	if test $? = 0; then
271		pass=`expr $pass + 1`
272		end_test PASS
273	else
274		fail=`expr $fail + 1`
275		$IPPFIND "$1._ipps._tcp.local." -x ./bonjour-tests.sh '{service_name}' _fail5.3 \;
276	fi
277else
278	skip=`expr $skip + 1`
279	end_test SKIP
280fi
281
282# B-5.4 IPPS Resolve test: Printer responds to an IPPS Get-Printer-Attributes request using the resolved hostname, port, and resource path.
283start_test "B-5.4 IPPS Resolve test"
284if test $HAVE_TLS = 1; then
285	$IPPFIND "$1._ipps._tcp.local." --ls >/dev/null
286	if test $? = 0; then
287		pass=`expr $pass + 1`
288		end_test PASS
289	else
290		fail=`expr $fail + 1`
291		echo "<key>Errors</key><array>" >>"$PLIST"
292		$IPPFIND "$1._ipps._tcp.local." --ls | awk '{ print "<string>" $0 "</string>" }' >>"$PLIST"
293		echo "</array>" >>"$PLIST"
294		end_test FAIL
295	fi
296else
297	skip=`expr $skip + 1`
298	end_test SKIP
299fi
300
301# B-5.5 IPPS TXT values test: The TXT record values for IPPS match the reported IPPS attribute values.
302start_test "B-5.5 IPPS TXT values test"
303if test $HAVE_TLS = 1; then
304	$IPPFIND "$1._ipps._tcp.local." --txt-adminurl '^(http:|https:)//' --txt-pdl 'image/pwg-raster' --txt-pdl 'image/jpeg' --txt-rp '^ipp/(print|print/[^/]+)$' --txt-UUID '^[0-9a-fA-F]{8,8}-[0-9a-fA-F]{4,4}-[0-9a-fA-F]{4,4}-[0-9a-fA-F]{4,4}-[0-9a-fA-F]{12,12}$' -x $IPPTOOL -q -d 'ADMINURL={txt_adminurl}' -d 'UUID={txt_uuid}' '{}' bonjour-value-tests.test \;
305	if test $? = 0; then
306		pass=`expr $pass + 1`
307		end_test PASS
308	else
309		fail=`expr $fail + 1`
310		$IPPFIND "$1._ipps._tcp.local." -x ./bonjour-tests.sh '{service_name}' _fail5.5 \;
311	fi
312else
313	skip=`expr $skip + 1`
314	end_test SKIP
315fi
316
317# Finish up...
318if test $fail -gt 0; then
319	cat >>"$PLIST" <<EOF
320</array>
321<key>Successful</key>
322<false />
323EOF
324else
325	cat >>"$PLIST" <<EOF
326</array>
327<key>Successful</key>
328<true />
329EOF
330fi
331
332cat >>"$PLIST" <<EOF
333</dict>
334</plist>
335EOF
336
337score=`expr $pass + $skip`
338score=`expr 100 \* $score / $total`
339echo "Summary: $total tests, $pass passed, $fail failed, $skip skipped"
340echo "Score: ${score}%"
341
342#
343# End of "$Id: bonjour-tests.sh 12142 2014-08-30 02:35:43Z msweet $".
344#
345