wifi_marauder_script.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "../wifi_marauder_app_i.h"
  2. #include "wifi_marauder_script.h"
  3. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN 15
  4. #define WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON 60
  5. WifiMarauderScript *wifi_marauder_script_alloc() {
  6. WifiMarauderScript *script = (WifiMarauderScript *) malloc(sizeof(WifiMarauderScript));
  7. if (script == NULL) {
  8. return NULL;
  9. }
  10. script->name = NULL;
  11. script->first_stage = NULL;
  12. script->repeat = 1;
  13. return script;
  14. }
  15. void _wifi_marauder_script_load_meta(WifiMarauderScript *script, cJSON *meta_section) {
  16. if (meta_section != NULL) {
  17. // Script name
  18. cJSON* name = cJSON_GetObjectItem(meta_section, "name");
  19. if (name != NULL) {
  20. script->name = strdup(name->valuestring);
  21. }
  22. // Times the script will be repeated
  23. cJSON* repeat = cJSON_GetObjectItem(meta_section, "repeat");
  24. if (repeat != NULL) {
  25. script->repeat = repeat->valueint;
  26. }
  27. }
  28. if (script->name == NULL) {
  29. script->name = "New script";
  30. }
  31. }
  32. WifiMarauderScriptStageScan* _wifi_marauder_script_get_stage_scan(cJSON *stages) {
  33. cJSON* stage_scan = cJSON_GetObjectItem(stages, "scan");
  34. if (stage_scan == NULL) {
  35. return NULL;
  36. }
  37. cJSON* type = cJSON_GetObjectItem(stage_scan, "type");
  38. if (type == NULL) {
  39. return NULL;
  40. }
  41. WifiMarauderScriptScanType scan_type;
  42. if (strcmp(type->valuestring, "ap") == 0) {
  43. scan_type = WifiMarauderScriptScanTypeAp;
  44. } else if (strcmp(type->valuestring, "station") == 0) {
  45. scan_type = WifiMarauderScriptScanTypeStation;
  46. } else {
  47. return NULL;
  48. }
  49. cJSON* timeout = cJSON_GetObjectItem(stage_scan, "timeout");
  50. int scan_timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN;
  51. WifiMarauderScriptStageScan *scan_stage = (WifiMarauderScriptStageScan*) malloc(sizeof(WifiMarauderScriptStageScan));
  52. scan_stage->type = scan_type;
  53. scan_stage->timeout = scan_timeout;
  54. return scan_stage;
  55. }
  56. WifiMarauderScriptStageSelect* _wifi_marauder_script_get_stage_select(cJSON *stages) {
  57. cJSON *select_stage_json = cJSON_GetObjectItemCaseSensitive(stages, "select");
  58. if (select_stage_json == NULL) {
  59. return NULL;
  60. }
  61. cJSON *type_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "type");
  62. cJSON *filter_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "filter");
  63. cJSON *allow_repeat_json = cJSON_GetObjectItemCaseSensitive(select_stage_json, "allow_repeat");
  64. if (!cJSON_IsString(type_json) || !cJSON_IsString(filter_json)) {
  65. return NULL;
  66. }
  67. WifiMarauderScriptSelectType select_type;
  68. if (strcmp(type_json->valuestring, "ap") == 0) {
  69. select_type = WifiMarauderScriptSelectTypeAp;
  70. } else if (strcmp(type_json->valuestring, "station") == 0) {
  71. select_type = WifiMarauderScriptSelectTypeStation;
  72. } else if (strcmp(type_json->valuestring, "ssid") == 0) {
  73. select_type = WifiMarauderScriptSelectTypeSsid;
  74. } else {
  75. return NULL;
  76. }
  77. char *filter_str = strdup(filter_json->valuestring);
  78. WifiMarauderScriptStageSelect *stage_select = (WifiMarauderScriptStageSelect*) malloc(sizeof(WifiMarauderScriptStageSelect));
  79. stage_select->type = select_type;
  80. stage_select->filter = filter_str;
  81. stage_select->allow_repeat = cJSON_IsBool(allow_repeat_json) ? allow_repeat_json->valueint : true;
  82. return stage_select;
  83. }
  84. WifiMarauderScriptStageBeaconList* _wifi_marauder_script_get_stage_beacon_list(cJSON *stages) {
  85. cJSON* stage_beaconlist = cJSON_GetObjectItem(stages, "beaconlist");
  86. if (stage_beaconlist == NULL) {
  87. return NULL;
  88. }
  89. WifiMarauderScriptStageBeaconList *beaconlist_stage = (WifiMarauderScriptStageBeaconList*) malloc(sizeof(WifiMarauderScriptStageBeaconList));
  90. if (beaconlist_stage == NULL) {
  91. return NULL;
  92. }
  93. cJSON* ssids = cJSON_GetObjectItem(stage_beaconlist, "ssids");
  94. if (ssids == NULL) {
  95. return NULL;
  96. }
  97. // SSID count
  98. int ssid_count = cJSON_GetArraySize(ssids);
  99. if (ssid_count == 0) {
  100. return NULL;
  101. }
  102. beaconlist_stage->ssid_count = ssid_count;
  103. // SSIDs
  104. beaconlist_stage->ssids = (char**) malloc(sizeof(char*) * ssid_count);
  105. if (beaconlist_stage->ssids == NULL) {
  106. return NULL;
  107. }
  108. for (int i = 0; i < ssid_count; i++) {
  109. cJSON* ssid = cJSON_GetArrayItem(ssids, i);
  110. if (ssid == NULL) {
  111. continue;
  112. }
  113. char* ssid_string = cJSON_GetStringValue(ssid);
  114. if (ssid_string == NULL) {
  115. continue;
  116. }
  117. beaconlist_stage->ssids[i] = (char*) malloc(sizeof(char) * (strlen(ssid_string) + 1));
  118. strcpy(beaconlist_stage->ssids[i], ssid_string);
  119. }
  120. // Timeout
  121. cJSON* timeout = cJSON_GetObjectItem(stage_beaconlist, "timeout");
  122. beaconlist_stage->timeout = timeout != NULL ? (int)cJSON_GetNumberValue(timeout) : WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
  123. return beaconlist_stage;
  124. }
  125. WifiMarauderScriptStage* _wifi_marauder_script_create_stage(WifiMarauderScriptStageType type, void* stage_data) {
  126. WifiMarauderScriptStage* stage = (WifiMarauderScriptStage*) malloc(sizeof(WifiMarauderScriptStage));
  127. stage->type = type;
  128. stage->stage = stage_data;
  129. stage->next_stage = NULL;
  130. return stage;
  131. }
  132. void _wifi_marauder_script_add_stage(WifiMarauderScript *script, WifiMarauderScriptStage *stage, WifiMarauderScriptStage **prev_stage) {
  133. if (*prev_stage != NULL) {
  134. (*prev_stage)->next_stage = stage;
  135. } else {
  136. script->first_stage = stage;
  137. }
  138. *prev_stage = stage;
  139. }
  140. void _wifi_marauder_script_load_stages(WifiMarauderScript *script, cJSON *stages) {
  141. WifiMarauderScriptStage *prev_stage = NULL;
  142. // Scan stage
  143. WifiMarauderScriptStageScan *stage_scan = _wifi_marauder_script_get_stage_scan(stages);
  144. if (stage_scan != NULL) {
  145. _wifi_marauder_script_add_stage(
  146. script,
  147. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeScan, stage_scan),
  148. &prev_stage
  149. );
  150. }
  151. // Select stage
  152. WifiMarauderScriptStageSelect *stage_select = _wifi_marauder_script_get_stage_select(stages);
  153. if (stage_select != NULL) {
  154. _wifi_marauder_script_add_stage(
  155. script,
  156. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSelect, stage_select),
  157. &prev_stage
  158. );
  159. }
  160. // Beacon List stage
  161. WifiMarauderScriptStageBeaconList *stage_beacon_list = _wifi_marauder_script_get_stage_beacon_list(stages);
  162. if (stage_beacon_list != NULL) {
  163. _wifi_marauder_script_add_stage(
  164. script,
  165. _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeBeaconList, stage_beacon_list),
  166. &prev_stage
  167. );
  168. }
  169. }
  170. WifiMarauderScript *wifi_marauder_script_parse_raw(const char* json_raw) {
  171. WifiMarauderScript *script = wifi_marauder_script_alloc();
  172. if (script == NULL) {
  173. return NULL;
  174. }
  175. cJSON* json = cJSON_Parse(json_raw);
  176. if (json == NULL) {
  177. return NULL;
  178. }
  179. cJSON* meta = cJSON_GetObjectItem(json, "meta");
  180. _wifi_marauder_script_load_meta(script, meta);
  181. cJSON* stages = cJSON_GetObjectItem(json, "stages");
  182. _wifi_marauder_script_load_stages(script, stages);
  183. return script;
  184. }
  185. WifiMarauderScript *wifi_marauder_script_parse_file(const char* file_path, Storage* storage) {
  186. WifiMarauderScript *script = NULL;
  187. File* script_file = storage_file_alloc(storage);
  188. if (storage_file_open(script_file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
  189. uint32_t file_size = storage_file_size(script_file);
  190. char* json_buffer = (char*)malloc(file_size + 1);
  191. uint16_t bytes_read = storage_file_read(script_file, json_buffer, file_size);
  192. json_buffer[bytes_read] = '\0';
  193. script = wifi_marauder_script_parse_raw(json_buffer);
  194. storage_file_close(script_file);
  195. }
  196. storage_file_free(script_file);
  197. return script;
  198. }
  199. void wifi_marauder_script_free(WifiMarauderScript *script) {
  200. if (script == NULL) {
  201. return;
  202. }
  203. WifiMarauderScriptStage *current_stage = script->first_stage;
  204. while (current_stage != NULL) {
  205. WifiMarauderScriptStage *next_stage = current_stage->next_stage;
  206. switch (current_stage->type) {
  207. case WifiMarauderScriptStageTypeScan:
  208. free(current_stage->stage);
  209. break;
  210. case WifiMarauderScriptStageTypeSelect:
  211. free(((WifiMarauderScriptStageSelect *) current_stage->stage)->filter);
  212. free(current_stage->stage);
  213. break;
  214. case WifiMarauderScriptStageTypeSniffPmkid:
  215. free(current_stage->stage);
  216. break;
  217. case WifiMarauderScriptStageTypeBeaconList:
  218. for (int i = 0; i < ((WifiMarauderScriptStageBeaconList *) current_stage->stage)->ssid_count; i++) {
  219. free(((WifiMarauderScriptStageBeaconList *) current_stage->stage)->ssids[i]);
  220. }
  221. free(((WifiMarauderScriptStageBeaconList *) current_stage->stage)->ssids);
  222. free(current_stage->stage);
  223. break;
  224. }
  225. free(current_stage);
  226. current_stage = next_stage;
  227. }
  228. free(script->name);
  229. free(script);
  230. }