09-pwfile-parse-invalid.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/usr/bin/env python3
  2. # Test for CVE-2018-xxxxx.
  3. from mosq_test_helper import *
  4. import signal
  5. def write_config(filename, port, per_listener):
  6. with open(filename, 'w') as f:
  7. f.write("per_listener_settings %s\n" % (per_listener))
  8. f.write("port %d\n" % (port))
  9. f.write("password_file %s\n" % (filename.replace('.conf', '.pwfile')))
  10. f.write("allow_anonymous false")
  11. def write_pwfile(filename, bad_line1, bad_line2):
  12. with open(filename, 'w') as f:
  13. if bad_line1 is not None:
  14. f.write('%s\n' % (bad_line1))
  15. # Username test, password test
  16. f.write('test:$6$njERlZMi/7DzNB9E$iiavfuXvUm8iyDZArTy7smTxh07GXXOrOsqxfW6gkOYVXHGk+W+i/8d3xDxrMwEPygEBhoA8A/gjQC0N2M4Lkw==\n')
  17. # Username empty, password 0 length
  18. f.write('empty:$6$o+53eGXtmlfHeYrg$FY7X9DNQ4uU1j0NiPmGOOSU05ZSzhqNmNhXIof/0nLpVb1zDhcRHdaC72E3YryH7dtTiG/r6jH6C8J+30cZBgA==\n')
  19. if bad_line2 is not None:
  20. f.write('%s\n' % (bad_line2))
  21. def do_test(port, connack_rc, username, password):
  22. rc = 1
  23. keepalive = 60
  24. connect_packet = mosq_test.gen_connect("username-password-check", keepalive=keepalive, username=username, password=password)
  25. connack_packet = mosq_test.gen_connack(rc=connack_rc)
  26. try:
  27. sock = mosq_test.do_client_connect(connect_packet, connack_packet, port=port)
  28. rc = 0
  29. sock.close()
  30. except mosq_test.TestError:
  31. pass
  32. finally:
  33. if rc:
  34. raise AssertionError
  35. def username_password_tests(port):
  36. broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
  37. try:
  38. do_test(port, connack_rc=0, username='test', password='test')
  39. do_test(port, connack_rc=5, username='test', password='bad')
  40. do_test(port, connack_rc=5, username='test', password='')
  41. do_test(port, connack_rc=5, username='test', password=None)
  42. do_test(port, connack_rc=5, username='empty', password='test')
  43. do_test(port, connack_rc=5, username='empty', password='bad')
  44. do_test(port, connack_rc=5, username='empty', password='')
  45. do_test(port, connack_rc=5, username='empty', password=None)
  46. do_test(port, connack_rc=5, username='bad', password='test')
  47. do_test(port, connack_rc=5, username='bad', password='bad')
  48. do_test(port, connack_rc=5, username='bad', password='')
  49. do_test(port, connack_rc=5, username='bad', password=None)
  50. do_test(port, connack_rc=5, username='', password='test')
  51. do_test(port, connack_rc=5, username='', password='bad')
  52. do_test(port, connack_rc=5, username='', password='')
  53. do_test(port, connack_rc=5, username='', password=None)
  54. do_test(port, connack_rc=5, username=None, password='test')
  55. do_test(port, connack_rc=5, username=None, password='bad')
  56. do_test(port, connack_rc=5, username=None, password='')
  57. do_test(port, connack_rc=5, username=None, password=None)
  58. except ValueError:
  59. pass
  60. finally:
  61. broker.terminate()
  62. broker.wait()
  63. def all_tests(port):
  64. # Valid file, single user
  65. write_pwfile(pw_file, bad_line1=None, bad_line2=None)
  66. username_password_tests(port)
  67. # Invalid file, first line blank
  68. write_pwfile(pw_file, bad_line1='', bad_line2=None)
  69. username_password_tests(port)
  70. # Invalid file, last line blank
  71. write_pwfile(pw_file, bad_line1=None, bad_line2='')
  72. username_password_tests(port)
  73. # Invalid file, first and last line blank
  74. write_pwfile(pw_file, bad_line1='', bad_line2='')
  75. username_password_tests(port)
  76. # Invalid file, first line 'comment'
  77. write_pwfile(pw_file, bad_line1='#comment', bad_line2=None)
  78. username_password_tests(port)
  79. # Invalid file, last line 'comment'
  80. write_pwfile(pw_file, bad_line1=None, bad_line2='#comment')
  81. username_password_tests(port)
  82. # Invalid file, first and last line 'comment'
  83. write_pwfile(pw_file, bad_line1='#comment', bad_line2='#comment')
  84. username_password_tests(port)
  85. # Invalid file, first line blank and last line 'comment'
  86. write_pwfile(pw_file, bad_line1='', bad_line2='#comment')
  87. username_password_tests(port)
  88. # Invalid file, first line incomplete
  89. write_pwfile(pw_file, bad_line1='bad:', bad_line2=None)
  90. username_password_tests(port)
  91. # Invalid file, first line incomplete, but with "password"
  92. write_pwfile(pw_file, bad_line1='bad:bad', bad_line2=None)
  93. username_password_tests(port)
  94. # Invalid file, first line incomplete, partial password hash
  95. write_pwfile(pw_file, bad_line1='bad:$', bad_line2=None)
  96. username_password_tests(port)
  97. # Invalid file, first line incomplete, partial password hash
  98. write_pwfile(pw_file, bad_line1='bad:$6', bad_line2=None)
  99. username_password_tests(port)
  100. # Invalid file, first line incomplete, partial password hash
  101. write_pwfile(pw_file, bad_line1='bad:$6$', bad_line2=None)
  102. username_password_tests(port)
  103. # Valid file, first line incomplete, has valid salt but no password hash
  104. write_pwfile(pw_file, bad_line1='bad:$6$njERlZMi/7DzNB9E', bad_line2=None)
  105. username_password_tests(port)
  106. # Valid file, first line incomplete, has valid salt but no password hash
  107. write_pwfile(pw_file, bad_line1='bad:$6$njERlZMi/7DzNB9E$', bad_line2=None)
  108. username_password_tests(port)
  109. # Valid file, first line has invalid hash designator
  110. write_pwfile(pw_file, bad_line1='bad:$5$njERlZMi/7DzNB9E$iiavfuXvUm8iyDZArTy7smTxh07GXXOrOsqxfW6gkOYVXHGk+W+i/8d3xDxrMwEPygEBhoA8A/gjQC0N2M4Lkw==', bad_line2=None)
  111. username_password_tests(port)
  112. # Invalid file, missing username but valid password hash
  113. write_pwfile(pw_file, bad_line1=':$6$njERlZMi/7DzNB9E$iiavfuXvUm8iyDZArTy7smTxh07GXXOrOsqxfW6gkOYVXHGk+W+i/8d3xDxrMwEPygEBhoA8A/gjQC0N2M4Lkw==', bad_line2=None)
  114. username_password_tests(port)
  115. # Valid file, valid username but password salt not base64
  116. write_pwfile(pw_file, bad_line1='bad:$6$njER{ZMi/7DzNB9E$iiavfuXvUm8iyDZArTy7smTxh07GXXOrOsqxfW6gkOYVXHGk+W+i/8d3xDxrMwEPygEBhoA8A/gjQC0N2M4Lkw==', bad_line2=None)
  117. username_password_tests(port)
  118. # Valid file, valid username but password hash not base64
  119. write_pwfile(pw_file, bad_line1='bad:$6$njERlZMi/7DzNB9E$iiavfuXv{}8iyDZArTy7smTxh07GXXOrOsqxfW6gkOYVXHGk+W+i/8d3xDxrMwEPygEBhoA8A/gjQC0N2M4Lkw==', bad_line2=None)
  120. username_password_tests(port)
  121. port = mosq_test.get_port()
  122. conf_file = os.path.basename(__file__).replace('.py', '.conf')
  123. pw_file = os.path.basename(__file__).replace('.py', '.pwfile')
  124. try:
  125. write_config(conf_file, port, "false")
  126. all_tests(port)
  127. write_config(conf_file, port, "true")
  128. all_tests(port)
  129. finally:
  130. os.remove(conf_file)
  131. os.remove(pw_file)
  132. sys.exit(0)