14-dynsec-role-invalid.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #!/usr/bin/env python3
  2. # Check invalid inputs for role commands
  3. from mosq_test_helper import *
  4. import json
  5. import shutil
  6. def write_config(filename, port):
  7. with open(filename, 'w') as f:
  8. f.write("listener %d\n" % (port))
  9. f.write("allow_anonymous true\n")
  10. f.write("plugin ../../plugins/dynamic-security/mosquitto_dynamic_security.so\n")
  11. f.write("plugin_opt_config_file %d/dynamic-security.json\n" % (port))
  12. def command_check(sock, command_payload, expected_response, msg=""):
  13. command_packet = mosq_test.gen_publish(topic="$CONTROL/dynamic-security/v1", qos=0, payload=json.dumps(command_payload))
  14. sock.send(command_packet)
  15. response = json.loads(mosq_test.read_publish(sock))
  16. if response != expected_response:
  17. print(expected_response)
  18. print(response)
  19. if msg != "":
  20. print(msg)
  21. raise ValueError(response)
  22. port = mosq_test.get_port()
  23. conf_file = os.path.basename(__file__).replace('.py', '.conf')
  24. write_config(conf_file, port)
  25. # Create client for modifying
  26. create_client0_command = { 'commands': [{'command': 'createClient', 'username':'validclient' }] }
  27. create_client0_response = {'responses': [{'command': 'createClient'}]}
  28. # Create group for modifying
  29. create_group0_command = { 'commands': [{'command': 'createGroup', 'groupname':'validgroup' }] }
  30. create_group0_response = {'responses': [{'command': 'createGroup'}]}
  31. # Create role for modifying
  32. create_role0_command = { 'commands': [{'command': 'createRole', 'rolename':'validrole' }] }
  33. create_role0_response = {'responses': [{'command': 'createRole'}]}
  34. # Add ACL for modifying
  35. add_role_acl0_command = { 'commands': [{'command': 'addRoleACL', 'rolename':'validrole', 'acltype':'unsubscribePattern', 'topic':'validtopic', 'allow':True }] }
  36. add_role_acl0_response = {'responses': [{'command': 'addRoleACL'}]}
  37. # ==========================================================================
  38. # Create role
  39. # ==========================================================================
  40. # No rolename
  41. create_role1_command = { 'commands': [{'command': 'createRole' }] }
  42. create_role1_response = {'responses': [{'command': 'createRole', 'error': 'Invalid/missing rolename'}]}
  43. # Rolename not a string
  44. create_role2_command = { 'commands': [{'command': 'createRole', 'rolename':5 }] }
  45. create_role2_response = {'responses': [{'command': 'createRole', 'error': 'Invalid/missing rolename'}]}
  46. # Rolename not UTF-8
  47. create_role3_command = { 'commands': [{'command': 'createRole', 'rolename': '￿LO' }] }
  48. create_role3_response = {'responses': [{'command': 'createRole', 'error': 'Role name not valid UTF-8'}]}
  49. # textname not a string
  50. create_role4_command = { 'commands': [{'command': 'createRole', 'rolename':'g', 'textname':5 }] }
  51. create_role4_response = {'responses': [{'command': 'createRole', 'error': 'Invalid/missing textname'}]}
  52. # textdescription not a string
  53. create_role5_command = { 'commands': [{'command': 'createRole', 'rolename':'g', 'textdescription':5 }] }
  54. create_role5_response = {'responses': [{'command': 'createRole', 'error': 'Invalid/missing textdescription'}]}
  55. # Role already exists
  56. create_role6_command = { 'commands': [{'command': 'createRole', 'rolename': 'validrole'}]}
  57. create_role6_response = {'responses': [{'command': 'createRole', 'error': 'Role already exists'}]}
  58. # Bad ACLs
  59. #create_role7_command = { 'commands': [{'command': 'createRole', 'rolename': 'role', 'roles':[{'rolename':'notfound'}]}] }
  60. #create_role7_response = {'responses': [{'command': 'createRole', 'error': 'Role not found'}]}
  61. # ==========================================================================
  62. # Delete role
  63. # ==========================================================================
  64. # No rolename
  65. delete_role1_command = { 'commands': [{'command': 'deleteRole' }] }
  66. delete_role1_response = {'responses': [{'command': 'deleteRole', 'error': 'Invalid/missing rolename'}]}
  67. # Rolename not a string
  68. delete_role2_command = { 'commands': [{'command': 'deleteRole', 'rolename':5 }] }
  69. delete_role2_response = {'responses': [{'command': 'deleteRole', 'error': 'Invalid/missing rolename'}]}
  70. # Rolename not UTF-8
  71. delete_role3_command = { 'commands': [{'command': 'deleteRole', 'rolename': '￿LO' }] }
  72. delete_role3_response = {'responses': [{'command': 'deleteRole', 'error': 'Role name not valid UTF-8'}]}
  73. # Role not found
  74. delete_role4_command = { 'commands': [{'command': 'deleteRole', 'rolename': 'role'}]}
  75. delete_role4_response = {'responses': [{'command': 'deleteRole', 'error': 'Role not found'}]}
  76. # ==========================================================================
  77. # Get role
  78. # ==========================================================================
  79. # No rolename
  80. get_role1_command = { 'commands': [{'command': 'getRole'}] }
  81. get_role1_response = {'responses': [{'command': 'getRole', 'error': 'Invalid/missing rolename'}]}
  82. # rolename not a string
  83. get_role2_command = { 'commands': [{'command': 'getRole', 'rolename':5}] }
  84. get_role2_response = {'responses': [{'command': 'getRole', 'error': 'Invalid/missing rolename'}]}
  85. # rolename not UTF-8
  86. get_role3_command = { 'commands': [{'command': 'getRole', 'rolename': '￿LO' }] }
  87. get_role3_response = {'responses': [{'command': 'getRole', 'error': 'Role name not valid UTF-8'}]}
  88. # role not found
  89. get_role4_command = { 'commands': [{'command': 'getRole', 'rolename':"notfound"}] }
  90. get_role4_response = {'responses': [{'command': 'getRole', 'error': 'Role not found'}]}
  91. # ==========================================================================
  92. # Add role ACL
  93. # ==========================================================================
  94. add_role_acl1_command = { 'commands': [{'command': 'addRoleACL'}]}
  95. add_role_acl1_response = {'responses': [{'command': 'addRoleACL', 'error': 'Invalid/missing rolename'}]}
  96. add_role_acl2_command = { 'commands': [{'command': 'addRoleACL', 'rolename':5}]}
  97. add_role_acl2_response = {'responses': [{'command': 'addRoleACL', 'error': 'Invalid/missing rolename'}]}
  98. add_role_acl3_command = { 'commands': [{'command': 'addRoleACL', 'rolename': '￿LO' }] }
  99. add_role_acl3_response = {'responses': [{'command': 'addRoleACL', 'error': 'Role name not valid UTF-8'}]}
  100. add_role_acl4_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'notvalid' }] }
  101. add_role_acl4_response = {'responses': [{'command': 'addRoleACL', 'error': 'Role not found'}]}
  102. add_role_acl5_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'validrole' }] }
  103. add_role_acl5_response = {'responses': [{'command': 'addRoleACL', 'error': 'Invalid/missing acltype'}]}
  104. add_role_acl6_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'validrole', 'acltype':'notvalid' }] }
  105. add_role_acl6_response = {'responses': [{'command': 'addRoleACL', 'error': 'Unknown acltype'}]}
  106. add_role_acl7_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'validrole', 'acltype':'unsubscribePattern' }] }
  107. add_role_acl7_response = {'responses': [{'command': 'addRoleACL', 'error': 'Invalid/missing topic'}]}
  108. add_role_acl8_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'validrole', 'acltype':'subscribePattern', 'topic':5 }] }
  109. add_role_acl8_response = {'responses': [{'command': 'addRoleACL', 'error': 'Invalid/missing topic'}]}
  110. add_role_acl9_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'validrole', 'acltype':'unsubscribeLiteral', 'topic':'￿LO' }] }
  111. add_role_acl9_response = {'responses': [{'command': 'addRoleACL', 'error': 'Topic not valid UTF-8'}]}
  112. add_role_acl10_command = { 'commands': [{'command': 'addRoleACL', 'rolename': 'validrole', 'acltype':'unsubscribeLiteral', 'topic':'not/#/valid' }] }
  113. add_role_acl10_response = {'responses': [{'command': 'addRoleACL', 'error': 'Invalid ACL topic'}]}
  114. # ==========================================================================
  115. # Remove role ACL
  116. # ==========================================================================
  117. remove_role_acl1_command = { 'commands': [{'command': 'removeRoleACL'}]}
  118. remove_role_acl1_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Invalid/missing rolename'}]}
  119. remove_role_acl2_command = { 'commands': [{'command': 'removeRoleACL', 'rolename':5}]}
  120. remove_role_acl2_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Invalid/missing rolename'}]}
  121. remove_role_acl3_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': '￿LO' }] }
  122. remove_role_acl3_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Role name not valid UTF-8'}]}
  123. remove_role_acl4_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': 'notvalid' }] }
  124. remove_role_acl4_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Role not found'}]}
  125. remove_role_acl5_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': 'validrole' }] }
  126. remove_role_acl5_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Invalid/missing acltype'}]}
  127. remove_role_acl6_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': 'validrole', 'acltype':'notvalid' }] }
  128. remove_role_acl6_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Unknown acltype'}]}
  129. remove_role_acl7_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': 'validrole', 'acltype':'unsubscribePattern' }] }
  130. remove_role_acl7_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Invalid/missing topic'}]}
  131. remove_role_acl8_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': 'validrole', 'acltype':'unsubscribePattern', 'topic':5 }] }
  132. remove_role_acl8_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Invalid/missing topic'}]}
  133. remove_role_acl9_command = { 'commands': [{'command': 'removeRoleACL', 'rolename': 'validrole', 'acltype':'unsubscribePattern', 'topic':'￿LO' }] }
  134. remove_role_acl9_response = {'responses': [{'command': 'removeRoleACL', 'error': 'Topic not valid UTF-8'}]}
  135. # ==========================================================================
  136. # Modify role
  137. # ==========================================================================
  138. # No groupname
  139. modify_group1_command = { 'commands': [{'command': 'modifyRole'}]}
  140. modify_group1_response = {'responses': [{'command': 'modifyRole', 'error': 'Invalid/missing groupname'}]}
  141. # Username not a string
  142. modify_group2_command = { 'commands': [{'command': 'modifyRole', 'groupname':5}]}
  143. modify_group2_response = {'responses': [{'command': 'modifyRole', 'error': 'Invalid/missing groupname'}]}
  144. # Username not UTF-8
  145. modify_group3_command = { 'commands': [{'command': 'modifyRole', 'rolename': '￿LO' }] }
  146. modify_group3_response = {'responses': [{'command': 'modifyRole', 'error': 'Role name not valid UTF-8'}]}
  147. # roles not a list
  148. modify_group4_command = { 'commands': [{'command': 'modifyRole', 'groupname':'validgroup', 'password':'test', 'roles':'string'}]}
  149. modify_group4_response = {'responses': [{'command': 'modifyRole', 'error': "'roles' not an array or missing/invalid rolename"}]}
  150. # No rolename
  151. modify_group5_command = { 'commands': [{'command': 'modifyRole', 'groupname':'validgroup', 'roles':[{}]}]}
  152. modify_group5_response = {'responses': [{'command': 'modifyRole', 'error': "'roles' not an array or missing/invalid rolename"}]}
  153. # rolename not a string
  154. modify_group6_command = { 'commands': [{'command': 'modifyRole', 'groupname':'validgroup', 'roles':[{'rolename':5}]}]}
  155. modify_group6_response = {'responses': [{'command': 'modifyRole', 'error': "'roles' not an array or missing/invalid rolename"}]}
  156. # rolename not UTF-8
  157. modify_group3_command = { 'commands': [{'command': 'modifyRole', 'rolename': '￿LO' }] }
  158. #modify_group7_command = { 'commands': [{'command': 'modifyRole', 'groupname':'validgroup'}]}
  159. #modify_group7_response = {'responses': [{'command': 'modifyRole', 'error': 'Invalid/missing rolename'}]}
  160. # Role not found
  161. modify_group8_command = { 'commands': [{'command': 'modifyRole', 'groupname':'notfound', 'rolename':'notfound'}]}
  162. modify_group8_response = {'responses': [{'command': 'modifyRole', 'error': 'Role not found'}]}
  163. # Role not found
  164. modify_group9_command = { 'commands': [{'command': 'modifyRole', 'groupname':'validgroup', 'roles':[{'rolename':'notfound'}]}]}
  165. modify_group9_response = {'responses': [{'command': 'modifyRole', 'error': 'Role not found'}]}
  166. rc = 1
  167. keepalive = 10
  168. connect_packet = mosq_test.gen_connect("ctrl-test", keepalive=keepalive, username="admin", password="admin")
  169. connack_packet = mosq_test.gen_connack(rc=0)
  170. mid = 2
  171. subscribe_packet = mosq_test.gen_subscribe(mid, "$CONTROL/dynamic-security/#", 1)
  172. suback_packet = mosq_test.gen_suback(mid, 1)
  173. try:
  174. os.mkdir(str(port))
  175. shutil.copyfile("dynamic-security-init.json", "%d/dynamic-security.json" % (port))
  176. except FileExistsError:
  177. pass
  178. broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
  179. try:
  180. sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=5, port=port)
  181. mosq_test.do_send_receive(sock, subscribe_packet, suback_packet, "suback")
  182. command_check(sock, create_client0_command, create_client0_response, "0")
  183. command_check(sock, create_group0_command, create_group0_response, "0")
  184. command_check(sock, create_role0_command, create_role0_response, "0")
  185. command_check(sock, add_role_acl0_command, add_role_acl0_response, "0")
  186. command_check(sock, create_role1_command, create_role1_response, "1")
  187. command_check(sock, create_role2_command, create_role2_response, "2")
  188. command_check(sock, create_role3_command, create_role3_response, "3")
  189. command_check(sock, create_role4_command, create_role4_response, "4")
  190. command_check(sock, create_role5_command, create_role5_response, "5")
  191. command_check(sock, create_role6_command, create_role6_response, "6")
  192. #command_check(sock, create_role7_command, create_role7_response, "7")
  193. command_check(sock, delete_role1_command, delete_role1_response, "1")
  194. command_check(sock, delete_role2_command, delete_role2_response, "2")
  195. command_check(sock, delete_role3_command, delete_role3_response, "3")
  196. command_check(sock, delete_role4_command, delete_role4_response, "4")
  197. command_check(sock, get_role1_command, get_role1_response, "1")
  198. command_check(sock, get_role2_command, get_role2_response, "2")
  199. command_check(sock, get_role3_command, get_role3_response, "3")
  200. command_check(sock, get_role4_command, get_role4_response, "4")
  201. command_check(sock, add_role_acl1_command, add_role_acl1_response, "1")
  202. command_check(sock, add_role_acl2_command, add_role_acl2_response, "2")
  203. command_check(sock, add_role_acl3_command, add_role_acl3_response, "3")
  204. command_check(sock, add_role_acl4_command, add_role_acl4_response, "4")
  205. command_check(sock, add_role_acl5_command, add_role_acl5_response, "5")
  206. command_check(sock, add_role_acl6_command, add_role_acl6_response, "6")
  207. command_check(sock, add_role_acl7_command, add_role_acl7_response, "7")
  208. command_check(sock, add_role_acl8_command, add_role_acl8_response, "8")
  209. command_check(sock, add_role_acl9_command, add_role_acl9_response, "9")
  210. command_check(sock, add_role_acl10_command, add_role_acl10_response, "10")
  211. command_check(sock, remove_role_acl1_command, remove_role_acl1_response, "1")
  212. command_check(sock, remove_role_acl2_command, remove_role_acl2_response, "2")
  213. command_check(sock, remove_role_acl3_command, remove_role_acl3_response, "3")
  214. command_check(sock, remove_role_acl4_command, remove_role_acl4_response, "4")
  215. command_check(sock, remove_role_acl5_command, remove_role_acl5_response, "5")
  216. command_check(sock, remove_role_acl6_command, remove_role_acl6_response, "6")
  217. command_check(sock, remove_role_acl7_command, remove_role_acl7_response, "7")
  218. command_check(sock, remove_role_acl8_command, remove_role_acl8_response, "8")
  219. command_check(sock, remove_role_acl9_command, remove_role_acl9_response, "9")
  220. #command_check(sock, modify_role1_command, modify_role1_response, "1")
  221. #command_check(sock, modify_role2_command, modify_role2_response, "2")
  222. ##command_check(sock, modify_role3_command, modify_role3_response, "3")
  223. #command_check(sock, modify_role4_command, modify_role4_response, "4")
  224. #command_check(sock, modify_role5_command, modify_role5_response, "5")
  225. #command_check(sock, modify_role6_command, modify_role6_response, "6")
  226. ##command_check(sock, modify_role7_command, modify_role7_response, "7")
  227. #command_check(sock, modify_role8_command, modify_role8_response, "8")
  228. #command_check(sock, modify_role9_command, modify_role9_response, "9")
  229. rc = 0
  230. sock.close()
  231. except mosq_test.TestError:
  232. pass
  233. finally:
  234. os.remove(conf_file)
  235. try:
  236. os.remove(f"{port}/dynamic-security.json")
  237. except FileNotFoundError:
  238. pass
  239. os.rmdir(f"{port}")
  240. broker.terminate()
  241. broker.wait()
  242. (stdo, stde) = broker.communicate()
  243. if rc:
  244. print(stde.decode('utf-8'))
  245. exit(rc)