PageRenderTime 69ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 1ms

/openvas-client-3.0.3/openvas/cli.c

#
C | 636 lines | 482 code | 74 blank | 80 comment | 65 complexity | bc6b0fc17c344034de9db5c8c5ef459b MD5 | raw file
Possible License(s): GPL-2.0
  1. /* OpenVAS Client
  2. * Copyright (C) 1998 - 2001 Renaud Deraison
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2,
  6. * as published by the Free Software Foundation
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. *
  17. * cli.c - Command Line Interface manager
  18. *
  19. * modified by Axel Nennker <axel@nennker.de> 20020418
  20. * do not need gtk here
  21. * removed gcc -Wall complaints, NULL pointer checks
  22. */
  23. #include <includes.h>
  24. #include "globals.h"
  25. #ifdef LIBOPENVAS_OLD_INCLUDE_PATH
  26. #include <openvas/plugutils.h> /* for addslashes */
  27. #include <openvas/network.h> /* for openvas_get_socket_from_connection,
  28. close_stream_connection */
  29. #else
  30. #include <openvas/misc/plugutils.h> /* for addslashes */
  31. #include <openvas/misc/network.h> /* for openvas_get_socket_from_connection,
  32. close_stream_connection */
  33. #endif
  34. #include "openvas-client.h"
  35. #include "context.h"
  36. #include "preferences.h"
  37. #include "parser.h"
  38. #include "parseutils.h"
  39. #include "openvas_plugin.h"
  40. #include "cli.h"
  41. #undef USE_GTK
  42. #include "read_target_file.h"
  43. #include "nbe_output.h"
  44. #include "text_output.h"
  45. #include "latex_output.h"
  46. #include "xml_output_ng.h"
  47. #include "html_output.h"
  48. #include "html_graph_output.h"
  49. #include "attack.h"
  50. #include "auth.h"
  51. #include "comm.h"
  52. #include "backend.h"
  53. static struct cli_args * g_cli = NULL;
  54. /*---------------------------------------------------
  55. Private functions
  56. -----------------------------------------------------*/
  57. static int
  58. is_server_present (int soc)
  59. {
  60. fd_set rd;
  61. struct timeval tv = {2,0};
  62. int fd = openvas_get_socket_from_connection(soc);
  63. FD_ZERO(&rd);
  64. FD_SET(fd, &rd);
  65. if(select(fd+1, &rd, NULL, NULL, &tv) > 0)
  66. {
  67. int len = -1;
  68. ioctl(fd, FIONREAD, &len);
  69. if(!len){
  70. fprintf(stderr, "Communication closed by server\n");
  71. return 0;
  72. }
  73. }
  74. return 1;
  75. }
  76. void
  77. cli_sigterm (int s)
  78. {
  79. cli_report(g_cli);
  80. exit(5);
  81. }
  82. /**
  83. * @brief Monitor the test - read data from the client, and process it.
  84. */
  85. static void
  86. cli_test_monitor (struct cli_args * cli)
  87. {
  88. int type, finished = 0;
  89. static char buf [16384], msg [16384];
  90. int backend = backend_init(NULL);
  91. signal(SIGTERM, cli_sigterm);
  92. g_cli = cli;
  93. cli->backend = backend;
  94. while(!finished)
  95. {
  96. /* I don't think buf[0] == 0 is a case that will happen, but just
  97. * to be safe, as it was the previous semantics
  98. */
  99. if(network_gets(Context->socket, buf, sizeof(buf) - 1) < 0 || buf[0] == '\0')
  100. {
  101. if(!is_server_present(Context->socket))
  102. {
  103. fprintf(stderr, "OpenVAS-Client: The server abruptly shut the communication down - the test may be incomplete\n");
  104. finished = 1;
  105. }
  106. continue;
  107. }
  108. buf[strlen(buf)-1]=0;
  109. if((type = parse_server_message(Context, buf, backend, msg))==MSG_BYE)
  110. finished = 1;
  111. if(cli->verbose)
  112. {
  113. switch(type)
  114. {
  115. case MSG_STAT2:
  116. {
  117. char * hostname;
  118. char * action;
  119. char * current;
  120. int max;
  121. char * plug = NULL;
  122. parse_scanner_short_status(&(buf[2]), &hostname, &action, &current, &max);
  123. if(!strcmp(action, "portscan"))plug="";
  124. printf ("%s|%s|%s|%d\n", action,hostname,current,max);
  125. efree(&hostname);
  126. efree (&action);
  127. efree(&current);
  128. }
  129. break;
  130. case MSG_STAT:
  131. {
  132. char * hostname;
  133. char * action;
  134. char* current;
  135. int max;
  136. parse_scanner_status(buf, &hostname, &action, &current, &max);
  137. printf ("%s|%s|%s|%d|foo\n", action,hostname,current,max);
  138. efree(&hostname);
  139. efree (&action);
  140. efree(&current);
  141. }
  142. break;
  143. case MSG_FINISHED:
  144. printf("finished|%s||||\n", msg);
  145. break;
  146. }
  147. }
  148. fflush(stdout);
  149. msg[0] = '\0';
  150. }
  151. }
  152. /*---------------------------------------------------
  153. CLI arguments management
  154. ----------------------------------------------------*/
  155. struct cli_args *
  156. cli_args_new()
  157. {
  158. return emalloc(sizeof(struct cli_args));
  159. }
  160. void
  161. cli_args_server (struct cli_args * args, char * server)
  162. {
  163. if (args->server)
  164. free(args->server);
  165. args->server = strdup (server);
  166. }
  167. void
  168. cli_args_port (struct cli_args * args, int port)
  169. {
  170. args->port = port;
  171. }
  172. void
  173. cli_args_login (struct cli_args * args, char * login)
  174. {
  175. if (args->login)
  176. free (args->login);
  177. args->login = strdup (login);
  178. }
  179. void
  180. cli_args_password (struct cli_args * args, char * pwd)
  181. {
  182. if (args->password)
  183. free (args->password);
  184. args->password = strdup (pwd);
  185. }
  186. void
  187. cli_args_target (struct cli_args * args, char * target)
  188. {
  189. if (args->target)
  190. free (args->target);
  191. args->target = strdup (target);
  192. }
  193. void
  194. cli_args_results (struct cli_args * args, char * results)
  195. {
  196. char* ftype;
  197. if(args->results)free(args->results);
  198. args->results = strdup(results);
  199. if(args->extension)free(args->extension);
  200. /* choose output file type based on fname */
  201. ftype = strrchr(args->results, '.');
  202. if(!ftype)
  203. {
  204. if(args->results[strlen(args->results)-1]=='/')
  205. {
  206. args->results[strlen(args->results)-1]=0;
  207. ftype = "html_pie";
  208. }
  209. else
  210. {
  211. ftype = "nbe";
  212. }
  213. }
  214. else
  215. ftype++;
  216. args->extension = strdup(ftype);
  217. }
  218. void
  219. cli_args_verbose (struct cli_args * args, int verbose)
  220. {
  221. args->verbose = verbose;
  222. }
  223. /**
  224. * Sets the output function pointer in an cli_args.
  225. * The output function is chosen according to the type, and currently one of
  226. * - backend_to_nbe (type: "nbe", NULL)
  227. * - arglist_to_html_graph ("html_graph", "html_pie")
  228. * - arglist_to_html ("html")
  229. * - arglist_to_latex ("tex", "latex")
  230. * - arglist_to_text ("txt", "txt")
  231. * - backend_to_xml_ng ("xml")
  232. *
  233. * @param args The cli_args of interest.
  234. * @param type Sets the type of output created when calling the output function
  235. * ("xml", "nbe" etc).
  236. * @see backend_to_nbe
  237. * @see backend_to_xml_ng
  238. * @see arglist_to_latex
  239. * @see arglist_to_html
  240. * @see arglist_to_html_graph
  241. * @see arglist_to_text
  242. */
  243. void
  244. cli_args_output (struct cli_args * args, char * type)
  245. {
  246. char * ftype = args->extension;
  247. if(type)ftype = type;
  248. if(!ftype)
  249. {
  250. args->output = (output_func_t)backend_to_nbe;
  251. args->backend_output_func = 1;
  252. return;
  253. }
  254. #ifndef NO_GDCHART
  255. if(!strncmp(ftype, "html_pie", 8)||
  256. !strncmp(ftype, "html_graph", 10)) {
  257. args->output = arglist_to_html_graph;
  258. }
  259. else
  260. #endif /* NO_GDCHART */
  261. if (!strncmp(ftype, "html", 4)) {
  262. args->output = arglist_to_html;
  263. } else if (!strcmp(ftype, "latex") ||
  264. !strcmp(ftype, "tex")) {
  265. args->output = arglist_to_latex;
  266. } else if(!strcmp(ftype, "txt")||
  267. !strcmp(ftype, "text")) {
  268. args->output = arglist_to_text;
  269. }
  270. else if(!strcmp(ftype, "nbe"))
  271. {
  272. args->output = (output_func_t)backend_to_nbe;
  273. args->backend_output_func = 1;
  274. }
  275. else if(!strcmp(ftype, "xml"))
  276. {
  277. args->output = (output_func_t)backend_to_xml_ng;
  278. args->backend_output_func = 1;
  279. }
  280. else {
  281. fprintf(stderr, "'%s' is not a valid report type\n", ftype);
  282. exit(1);
  283. }
  284. }
  285. /*---------------------------------------------------------
  286. * Auditing now
  287. *--------------------------------------------------------*/
  288. int
  289. cli_connect_to_scanner (struct cli_args * cli)
  290. {
  291. const char * err;
  292. prefs_set_string(Context, "nessusd_host", cli->server);
  293. prefs_set_int(Context, "nessusd_port", cli->port);
  294. prefs_set_string(Context, "nessusd_user", cli->login);
  295. Context->passwd = cli->password;
  296. err = connect_to_scanner(Context);
  297. if(err)
  298. {
  299. fprintf(stderr, "OpenVAS-Client : %s\n", err);
  300. return -1;
  301. }
  302. return 0;
  303. }
  304. /**
  305. * @return -1 If targetfile could not be converted to a list or attack failed,
  306. * 0 otherwise.
  307. */
  308. int
  309. cli_test_network (struct cli_args * cli)
  310. {
  311. /* If we fail to turn the target file into a list then
  312. * We should _NOT_ try to attack anything */
  313. char * target_list = target_file_to_list(cli->target);
  314. if (target_list == NULL) {
  315. /* report the error */
  316. fprintf(stderr, "OpenVAS-Client : error turning targetfile (%s) to list\n", cli->target);
  317. return -1;
  318. }
  319. if(attack_host(target_list, Context))
  320. {
  321. cli_test_monitor(cli);
  322. return 0;
  323. }
  324. else
  325. return -1;
  326. }
  327. /**
  328. * @brief Exports a report with the output function set.
  329. */
  330. void
  331. cli_report (struct cli_args * cli)
  332. {
  333. if(!cli->backend_output_func)
  334. cli->output(backend_convert(cli->backend), cli->results);
  335. else
  336. cli->output((struct arglist*)GSIZE_TO_POINTER(cli->backend), cli->results);
  337. }
  338. /* Only difference to addslashes from addslashes.c is that single "'"s are escaped, too.
  339. Should verify if that is of any use and merge. */
  340. static char*
  341. sql_addslashes (char *in)
  342. {
  343. char * ret;
  344. char * out;
  345. if ( in == NULL ) return NULL;
  346. out = malloc(strlen(in) * 2 + 1);
  347. bzero(out, strlen(in) * 2 + 1);
  348. ret = out;
  349. while(in[0])
  350. {
  351. if(in[0] == '\\')
  352. {
  353. out[0] = '\\'; out++;
  354. out[0] = '\\'; out++;
  355. }
  356. else if(in[0] == '\n')
  357. {
  358. out[0] = '\\'; out++;
  359. out[0] = 'n'; out++;
  360. }
  361. else if(in[0] == '\r')
  362. {
  363. out[0] = '\\'; out++;
  364. out[0] = 'r'; out++;
  365. }
  366. else if(in[0] == '\'')
  367. {
  368. out[0] = '\\'; out++;
  369. out[0] = '\''; out++;
  370. }
  371. else {
  372. out[0] = in[0];
  373. out++;
  374. }
  375. in++;
  376. }
  377. return realloc(ret, strlen(ret) + 1);
  378. }
  379. /**
  380. * @brief Prints SQL statements to insert plugin informations into a plugins
  381. * @brief table to stdout.
  382. */
  383. static void
  384. _cli_sql_dump_plugins (struct openvas_plugin * p)
  385. {
  386. while (p != NULL )
  387. {
  388. char * m, * n;
  389. printf("INSERT INTO plugins VALUES ('%s', ", p->oid);
  390. m = sql_addslashes(nvti_name(p->ni));
  391. printf("'%s', ", m);
  392. efree(&m);
  393. m = sql_addslashes(nvti_family(p->ni));
  394. printf("'%s', ", m);
  395. efree(&m);
  396. m = sql_addslashes(p->category);
  397. printf("'%s', ", m);
  398. efree(&m);
  399. m = sql_addslashes(nvti_copyright(p->ni));
  400. printf("'%s', ", m);
  401. efree(&m);
  402. m = sql_addslashes(nvti_summary(p->ni));
  403. printf("'%s', ", m);
  404. efree(&m);
  405. n = nvti_description(p->ni);
  406. m = sql_addslashes(n);
  407. printf("'%s',", m);
  408. efree(&m);
  409. m = sql_addslashes(nvti_version(p->ni));
  410. printf("'%s',", m);
  411. efree(&m);
  412. if( nvti_cve(p->ni) != NULL )
  413. {
  414. m = sql_addslashes(nvti_cve(p->ni));
  415. printf("'%s',", m);
  416. efree(&m);
  417. }
  418. else printf("'',");
  419. if(nvti_bid(p->ni) != NULL)
  420. {
  421. m = sql_addslashes(nvti_bid(p->ni));
  422. printf("'%s',", m);
  423. efree(&m);
  424. }
  425. else printf("'',");
  426. if(nvti_xref(p->ni) != NULL)
  427. {
  428. m = sql_addslashes(nvti_xref(p->ni));
  429. printf("'%s');\n", m);
  430. efree(&m);
  431. }
  432. else printf("'');\n");
  433. p = p->next;
  434. }
  435. }
  436. static void
  437. _cli_dump_plugins (struct openvas_plugin * p)
  438. {
  439. while( p != NULL )
  440. {
  441. char * var = p->oid;
  442. char * n;
  443. printf("%s|", var);
  444. var = addslashes(nvti_family(p->ni));
  445. printf("%s|", var);
  446. efree(&var);
  447. var = addslashes(nvti_name(p->ni));
  448. printf("%s|", var);
  449. efree(&var);
  450. var = addslashes(p->category);
  451. printf("%s|", var);
  452. efree(&var);
  453. var = addslashes(nvti_copyright(p->ni));
  454. printf("%s|", var);
  455. efree(&var);
  456. var = addslashes(nvti_summary(p->ni));
  457. printf("%s|", var);
  458. efree(&var);
  459. var = addslashes(nvti_version(p->ni));
  460. printf("%s|", var);
  461. efree(&var);
  462. var = addslashes(nvti_cve(p->ni));
  463. printf("%s|", var);
  464. efree(&var);
  465. var = addslashes(nvti_bid(p->ni));
  466. printf("%s|", var);
  467. efree(&var);
  468. var = addslashes(nvti_xref(p->ni));
  469. printf("%s|", var);
  470. efree(&var);
  471. n = nvti_description(p->ni);
  472. var = addslashes(n);
  473. printf("%s\n", var);
  474. efree(&var);
  475. p = p->next;
  476. }
  477. }
  478. /**
  479. * @brief Prints SQL statements to delete and recreate a plugins table and fill
  480. * @brief it with plugin information to stdout.
  481. */
  482. void
  483. cli_sql_dump_plugins (struct cli_args * cli)
  484. {
  485. printf("DROP TABLE IF EXISTS plugins;\n");
  486. printf("CREATE TABLE plugins (\n");
  487. printf(" oid varchar(50) NOT NULL,\n");
  488. printf(" name varchar(255),\n");
  489. printf(" family varchar(255),\n");
  490. printf(" category varchar(255),\n");
  491. printf(" copyright varchar(255),\n");
  492. printf(" summary varchar(255),\n");
  493. printf(" description blob,\n");
  494. printf(" version varchar(255),\n");
  495. printf(" cve_id varchar(255),\n");
  496. printf(" bugtraq_id varchar(255),\n");
  497. printf(" xref blob,\n");
  498. printf(" primary key (oid));\n");
  499. _cli_sql_dump_plugins(Context->plugins);
  500. _cli_sql_dump_plugins(Context->scanners);
  501. }
  502. void
  503. cli_dump_plugins (struct cli_args * cli)
  504. {
  505. _cli_dump_plugins (Context->plugins);
  506. _cli_dump_plugins (Context->scanners);
  507. }
  508. static void
  509. _cli_dump_pprefs ()
  510. {
  511. struct arglist * p = arg_get_value(Context->prefs, "PLUGINS_PREFS");
  512. if(!p)
  513. return;
  514. while(p->next)
  515. {
  516. switch(p->type)
  517. {
  518. case ARG_STRING:
  519. printf("%s = %s\n", p->name, (char*)p->value);
  520. break;
  521. case ARG_INT:
  522. printf("%s = %s\n", p->name, p->value ? "yes":"no");
  523. break;
  524. default:
  525. break;
  526. }
  527. p = p->next;
  528. }
  529. }
  530. void
  531. cli_sql_dump_prefs (struct cli_args * cli)
  532. {
  533. cli_dump_prefs (cli);
  534. }
  535. void
  536. cli_dump_prefs (struct cli_args * cli)
  537. {
  538. struct arglist * p = arg_get_value(Context->prefs, "SERVER_PREFS");
  539. if(!p)
  540. return;
  541. while(p->next)
  542. {
  543. switch(p->type)
  544. {
  545. case ARG_INT :
  546. printf("%s = %d\n", p->name, (int)GPOINTER_TO_SIZE(p->value));
  547. break;
  548. case ARG_STRING:
  549. printf("%s = %s\n", p->name, (char*)p->value);
  550. break;
  551. }
  552. p = p->next;
  553. }
  554. if(Context->plugins)_cli_dump_pprefs(Context->plugins);
  555. if(Context->scanners)_cli_dump_pprefs(Context->scanners);
  556. return;
  557. }
  558. int
  559. cli_close_connection (struct cli_args * cli)
  560. {
  561. return close_stream_connection(Context->socket);
  562. }