geom_gate userland utility improvements
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

397 lines
8.6 KiB

  1. # $FreeBSD$
  2. PIDFILE=ggatessh.pid
  3. TESTIMG="test.img"
  4. TEMPFILE="random.data"
  5. SFTPSERVER="/usr/libexec/sftp-server"
  6. PORT=2222
  7. atf_test_case ggatessh cleanup
  8. ggatessh_head()
  9. {
  10. atf_set "descr" "ggatessh can proxy to sftp"
  11. atf_set "require.progs" "ggatessh"
  12. atf_set "require.user" "root"
  13. atf_set "timeout" 10
  14. }
  15. ggatessh_body()
  16. {
  17. load_ggate
  18. us=$(alloc_ggate_dev)
  19. n1mchunks=3
  20. secsize=4096
  21. atf_check -e ignore -o ignore \
  22. dd if=/dev/random of="$TEMPFILE" bs=1m count=$n1mchunks conv=notrunc
  23. startup_sshd
  24. truncate -s ${n1mchunks}m "$TESTIMG"
  25. # sshd authenticates and switches to USER
  26. chown "$USER" "$TESTIMG"
  27. echo 'WARNING: ggatessh error messages goes to syslog' \
  28. '(aka /var/log/messages)'
  29. atf_check \
  30. ggatessh create -i "$(pwd)/id_rsa" -p "$PORT" -F "$PIDFILE" \
  31. -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG"
  32. ggate_dev=/dev/ggate${us}
  33. wait_for_ggate_device ${ggate_dev}
  34. # make sure it has correct size and sector sizekj
  35. read _dev _secsize _size _nsecs _stripesize _stripeoff <<EOF
  36. $(diskinfo /dev/ggate$us)
  37. EOF
  38. atf_check_equal "$_secsize" $secsize
  39. atf_check_equal "$_size" $(($n1mchunks * 1024 * 1024))
  40. atf_check_equal "$_nsecs" $(($n1mchunks * 1024 * 1024 / $secsize))
  41. # Test writing
  42. atf_check -e ignore -o ignore \
  43. dd if="$TEMPFILE" of=${ggate_dev} bs=1m count=$n1mchunks \
  44. conv=notrunc
  45. # Test reading
  46. atf_check -e ignore -o ignore \
  47. dd of="$TEMPFILE"2 if=${ggate_dev} bs=1m count=$n1mchunks \
  48. conv=notrunc
  49. # Verify that we read what we wrote
  50. atf_check cmp "$TEMPFILE" "$TEMPFILE"2
  51. # Verify that the image matches
  52. atf_check cmp "$TEMPFILE" "$TESTIMG"
  53. rm "$TEMPFILE" "$TEMPFILE"2
  54. }
  55. ggatessh_cleanup()
  56. {
  57. common_cleanup
  58. }
  59. atf_test_case ggatessh_resize cleanup
  60. ggatessh_resize_head()
  61. {
  62. atf_set "descr" "ggatessh will resize the devices"
  63. atf_set "require.progs" "ggatessh"
  64. atf_set "require.user" "root"
  65. atf_set "timeout" 20
  66. }
  67. ggatessh_resize_body()
  68. {
  69. n1mchunks=4
  70. secsize=4096
  71. us=$(alloc_ggate_dev)
  72. startup_sshd
  73. truncate -s ${n1mchunks}m "$TESTIMG"
  74. # sshd authenticates and switches to USER
  75. chown "$USER" "$TESTIMG"
  76. echo 'WARNING: ggatessh error messages goes to syslog' \
  77. '(aka /var/log/messages)'
  78. atf_check \
  79. ggatessh create -i "$(pwd)/id_rsa" -p "$PORT" -F "$PIDFILE" \
  80. -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG"
  81. ggate_dev=/dev/ggate${us}
  82. wait_for_ggate_device ${ggate_dev}
  83. # make sure it has correct size and sector sizekj
  84. read _dev _secsize _size _nsecs _stripesize _stripeoff <<EOF
  85. $(diskinfo /dev/ggate$us)
  86. EOF
  87. atf_check_equal "$_secsize" $secsize
  88. atf_check_equal "$_size" $(($n1mchunks * 1024 * 1024))
  89. atf_check_equal "$_nsecs" $(($n1mchunks * 1024 * 1024 / $secsize))
  90. # kill off old ggate
  91. pkill -F "$PIDFILE"
  92. # Test resizing
  93. n1mchunks=6
  94. truncate -s ${n1mchunks}m "$TESTIMG"
  95. ps auxwww | grep ggatessh
  96. cat "$PIDFILE"
  97. sleep 1
  98. # restart ggate
  99. atf_check \
  100. ggatessh rescue -v -i "$(pwd)/id_rsa" -p "$PORT" -F "$PIDFILE" \
  101. -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG" &
  102. sleep 1
  103. # make sure it has correct size and sector size
  104. read _dev _secsize _size _nsecs _stripesize _stripeoff <<EOF
  105. $(diskinfo /dev/ggate$us)
  106. EOF
  107. atf_check_equal "$_secsize" $secsize
  108. atf_check_equal "$_size" $(($n1mchunks * 1024 * 1024))
  109. atf_check_equal "$_nsecs" $(($n1mchunks * 1024 * 1024 / $secsize))
  110. dd if=/dev/ggate$us of=/dev/null bs=1m
  111. }
  112. ggatessh_resize_cleanup()
  113. {
  114. common_cleanup
  115. }
  116. atf_test_case ggatessh_rowotest cleanup
  117. ggatessh_rowotest_head()
  118. {
  119. atf_set "descr" "ggatessh properly handles the -o flag"
  120. atf_set "require.progs" "ggatessh"
  121. atf_set "require.user" "root"
  122. atf_set "timeout" 10
  123. }
  124. ggatessh_rowotest_body()
  125. {
  126. n1mchunks=4
  127. secsize=4096
  128. us=$(alloc_ggate_dev)
  129. startup_sshd
  130. truncate -s ${n1mchunks}m "$TESTIMG"
  131. # sshd authenticates and switches to USER
  132. chmod 444 "$TESTIMG"
  133. echo 'WARNING: ggatessh error messages goes to syslog' \
  134. '(aka /var/log/messages)'
  135. # make sure it fails in rw mode
  136. atf_check -s not-exit:0 \
  137. ggatessh create -i "$(pwd)/id_rsa" -p "$PORT" -F "$PIDFILE" \
  138. -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG"
  139. # open it in read-only mode
  140. atf_check \
  141. ggatessh create -o ro -i "$(pwd)/id_rsa" -p "$PORT" -F "$PIDFILE" \
  142. -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG"
  143. ggate_dev=/dev/ggate${us}
  144. wait_for_ggate_device ${ggate_dev}
  145. # make sure it has correct size and sector sizekj
  146. read _dev _secsize _size _nsecs _stripesize _stripeoff <<EOF
  147. $(diskinfo /dev/ggate$us)
  148. EOF
  149. atf_check_equal "$_secsize" $secsize
  150. atf_check_equal "$_size" $(($n1mchunks * 1024 * 1024))
  151. atf_check_equal "$_nsecs" $(($n1mchunks * 1024 * 1024 / $secsize))
  152. # that we can read a read-only ggate device
  153. atf_check -e ignore \
  154. dd if=${ggate_dev} of=/dev/null bs=1m count=$n1mchunks
  155. # that we can not write a read-only ggate device
  156. atf_check -e ignore -s not-exit:0 \
  157. dd of=${ggate_dev} if=/dev/zero bs=1m count=1
  158. # kill off old ggate
  159. pkill -F "$PIDFILE"
  160. ggatessh destroy -f -u $us >/dev/null
  161. # test write-only
  162. chmod 222 "$TESTIMG"
  163. # make sure it fails in rw mode
  164. atf_check -s not-exit:0 \
  165. ggatessh create -i "$(pwd)/id_rsa" -p "$PORT" -F "$PIDFILE" \
  166. -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG"
  167. # open it in write-only mode
  168. atf_check \
  169. ggatessh create -o wo -i "$(pwd)/id_rsa" -p "$PORT" \
  170. -F "$PIDFILE" -u $us -l "$USER" 127.0.0.1 "$(pwd)/$TESTIMG"
  171. ggate_dev=/dev/ggate${us}
  172. wait_for_ggate_device ${ggate_dev}
  173. # Note: diskinfo opens w/ read, can't verify device info
  174. # that we can not read a write-only ggate device
  175. atf_check -e ignore -s not-exit:0 \
  176. dd if=${ggate_dev} of=/dev/null bs=1m count=$n1mchunks
  177. # that we can write a write-only ggate device
  178. atf_check -e ignore \
  179. dd of=${ggate_dev} if=/dev/zero bs=1m count=1
  180. }
  181. ggatessh_rowotest_cleanup()
  182. {
  183. common_cleanup
  184. }
  185. atf_init_test_cases()
  186. {
  187. atf_add_test_case ggatessh
  188. atf_add_test_case ggatessh_resize
  189. atf_add_test_case ggatessh_rowotest
  190. }
  191. alloc_ggate_dev()
  192. {
  193. local us
  194. us=0
  195. while [ -c /dev/ggate${us} ]; do
  196. : $(( us += 1 ))
  197. done
  198. echo ${us} > ggate.devs
  199. echo ${us}
  200. }
  201. alloc_md()
  202. {
  203. local md
  204. md=$(mdconfig -a -t malloc -s 1M) || \
  205. atf_fail "failed to allocate md device"
  206. echo ${md} >> md.devs
  207. echo ${md}
  208. }
  209. # slightly modified from:
  210. # https://serverfault.com/questions/344295/is-it-possible-to-run-sshd-as-a-normal-user
  211. startup_sshd()
  212. {
  213. # ===============================================================
  214. # Note: using shorter keys to speed up tests, these are insecure.
  215. # ===============================================================
  216. # Host keys
  217. ssh-keygen -f ssh_host_rsa_key -b 1024 -N '' -t rsa > /dev/null
  218. # user key
  219. ssh-keygen -f id_rsa -b 1024 -N '' -t rsa > /dev/null
  220. (echo -n 'command="/usr/libexec/sftp-server" '; cat id_rsa.pub) > authorized_keys
  221. cat > sshd_config <<EOF
  222. ListenAddress 127.0.0.1:$PORT
  223. HostKey /home/freebsd/custom_ssh/ssh_host_rsa_key
  224. AuthorizedKeysFile $(pwd)/authorized_keys
  225. ChallengeResponseAuthentication no
  226. PasswordAuthentication no
  227. # to allow writable tmp w/ sticky bit
  228. StrictModes no
  229. UsePAM no
  230. Subsystem sftp ${SFTPSERVER}
  231. PidFile $(pwd)/sshd.pid
  232. EOF
  233. if ! :; then
  234. /usr/sbin/sshd -dD -f $(pwd)/sshd_config &
  235. sleep .2
  236. else
  237. /usr/sbin/sshd -f $(pwd)/sshd_config
  238. while ! [ -f sshd.pid ]; do
  239. sleep .2
  240. done
  241. fi
  242. }
  243. checksum()
  244. {
  245. local src work
  246. src=$1
  247. work=$2
  248. src_checksum=$(md5 -q $src)
  249. work_checksum=$(md5 -q $work)
  250. if [ "$work_checksum" != "$src_checksum" ]; then
  251. atf_fail "work md5 checksum didn't match"
  252. fi
  253. ggate_checksum=$(md5 -q /dev/ggate${us})
  254. if [ "$ggate_checksum" != "$src_checksum" ]; then
  255. atf_fail "ggate md5 checksum didn't match"
  256. fi
  257. }
  258. common_cleanup()
  259. {
  260. if [ -f "ggate.devs" ]; then
  261. while read test_ggate; do
  262. ggatessh destroy -f -u $test_ggate >/dev/null
  263. done < ggate.devs
  264. rm ggate.devs
  265. fi
  266. if [ -f "sshd.pid" ]; then
  267. pkill -F sshd.pid
  268. # clean up after startup_sshd
  269. rm ssh_host_rsa_key
  270. rm id_rsa id_rsa.pub
  271. rm authorized_keys
  272. fi
  273. if [ -f "$PIDFILE" ]; then
  274. pkill -F "$PIDFILE"
  275. rm $PIDFILE
  276. fi
  277. if [ -f "PLAINFILES" ]; then
  278. while read f; do
  279. rm -f ${f}
  280. done < ${PLAINFILES}
  281. rm ${PLAINFILES}
  282. fi
  283. if [ -f "md.devs" ]; then
  284. while read test_md; do
  285. mdconfig -d -u $test_md 2>/dev/null
  286. done < md.devs
  287. rm md.devs
  288. fi
  289. true
  290. }
  291. load_ggate()
  292. {
  293. local class=gate
  294. # If the geom class isn't already loaded, try loading it.
  295. if ! kldstat -q -m g_${class}; then
  296. if ! geom ${class} load; then
  297. atf_skip "could not load module for geom class=${class}"
  298. fi
  299. fi
  300. }
  301. # Bug 204616: ggatel(8) creates /dev/ggate* asynchronously if `ggatel create`
  302. # isn't called with `-v`.
  303. wait_for_ggate_device()
  304. {
  305. ggate_device=$1
  306. while [ ! -c $ggate_device ]; do
  307. sleep 0.5
  308. done
  309. }