Greenbone Vulnerability Management Libraries  11.0.1
kb.c
Go to the documentation of this file.
1 /* Copyright (C) 2014-2019 Greenbone Networks GmbH
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
25 #define _GNU_SOURCE
26 
27 #include "kb.h"
28 
29 #include <errno.h> /* for ENOMEM, EINVAL, EPROTO, EALREADY, ECONN... */
30 #include <glib.h> /* for g_log, g_free */
31 #include <hiredis/hiredis.h> /* for redisReply, freeReplyObject, redisCommand */
32 #include <stdbool.h> /* for bool, true, false */
33 #include <stdio.h>
34 #include <stdlib.h> /* for atoi */
35 #include <string.h> /* for strlen, strerror, strncpy, memset */
36 
37 #undef G_LOG_DOMAIN
38 #define G_LOG_DOMAIN "lib kb"
39 
50 #define GLOBAL_DBINDEX_NAME "GVM.__GlobalDBIndex"
51 
52 static const struct kb_operations KBRedisOperations;
53 
59 struct kb_redis
60 {
61  struct kb kb;
62  unsigned int max_db;
63  unsigned int db;
64  redisContext *rctx;
65  char path[0];
66 };
67 #define redis_kb(__kb) ((struct kb_redis *) (__kb))
68 
69 static int
70 redis_delete_all (struct kb_redis *);
71 static int redis_lnk_reset (kb_t);
72 static int
73 redis_flush_all (kb_t, const char *);
74 static redisReply *
75 redis_cmd (struct kb_redis *kbr, const char *fmt, ...);
76 
82 static int
83 try_database_index (struct kb_redis *kbr, int index)
84 {
85  redisContext *ctx = kbr->rctx;
86  redisReply *rep;
87  int rc = 0;
88 
89  rep = redisCommand (ctx, "HSETNX %s %d 1", GLOBAL_DBINDEX_NAME, index);
90  if (rep == NULL)
91  return -ENOMEM;
92 
93  if (rep->type != REDIS_REPLY_INTEGER)
94  rc = -EPROTO;
95  else if (rep->integer == 0)
96  rc = -EALREADY;
97  else
98  kbr->db = index;
99 
100  freeReplyObject (rep);
101 
102  return rc;
103 }
104 
113 static int
115 {
116  int rc = 0;
117  redisContext *ctx = kbr->rctx;
118  redisReply *rep = NULL;
119 
120  rep = redisCommand (ctx, "CONFIG GET databases");
121  if (rep == NULL)
122  {
123  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
124  "%s: redis command failed with '%s'", __func__, ctx->errstr);
125  rc = -1;
126  goto err_cleanup;
127  }
128 
129  if (rep->type != REDIS_REPLY_ARRAY)
130  {
131  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
132  "%s: cannot retrieve max DB number: %s", __func__, rep->str);
133  rc = -1;
134  goto err_cleanup;
135  }
136 
137  if (rep->elements == 2)
138  {
139  kbr->max_db = (unsigned) atoi (rep->element[1]->str);
140  }
141  else
142  {
143  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
144  "%s: unexpected reply length (%zd)", __func__, rep->elements);
145  rc = -1;
146  goto err_cleanup;
147  }
148 
149  g_debug ("%s: maximum DB number: %u", __func__, kbr->max_db);
150 
151 err_cleanup:
152  if (rep != NULL)
153  freeReplyObject (rep);
154 
155  return rc;
156 }
157 
168 static int
170 {
171  int rc;
172  redisContext *ctx = kbr->rctx;
173  redisReply *rep = NULL;
174 
175  if (kbr->db == 0)
176  {
177  unsigned i;
178 
179  if (kbr->max_db == 0)
180  fetch_max_db_index (kbr);
181 
182  for (i = 1; i < kbr->max_db; i++)
183  {
184  rc = try_database_index (kbr, i);
185  if (rc == 0)
186  break;
187  }
188  }
189 
190  /* No DB available, give up. */
191  if (kbr->db == 0)
192  {
193  rc = -1;
194  goto err_cleanup;
195  }
196 
197  rep = redisCommand (ctx, "SELECT %u", kbr->db);
198  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
199  {
200  rc = -1;
201  goto err_cleanup;
202  }
203 
204  rc = 0;
205 
206 err_cleanup:
207  if (rep != NULL)
208  freeReplyObject (rep);
209 
210  return rc;
211 }
212 
220 static int
222 {
223  int rc;
224  redisContext *ctx = kbr->rctx;
225  redisReply *rep;
226 
227  if (ctx == NULL)
228  return -EINVAL;
229 
230  rep = redisCommand (ctx, "SELECT 0"); /* Management database*/
231  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
232  {
233  rc = -1;
234  goto err_cleanup;
235  }
236  freeReplyObject (rep);
237 
238  rep = redisCommand (ctx, "HDEL %s %d", GLOBAL_DBINDEX_NAME, kbr->db);
239  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER)
240  {
241  rc = -1;
242  goto err_cleanup;
243  }
244 
245  rc = 0;
246 
247 err_cleanup:
248  if (rep != NULL)
249  freeReplyObject (rep);
250 
251  return rc;
252 }
253 
263 static int
264 get_redis_ctx (struct kb_redis *kbr)
265 {
266  int rc;
267 
268  if (kbr->rctx != NULL)
269  return 0;
270 
271  kbr->rctx = redisConnectUnix (kbr->path);
272  if (kbr->rctx == NULL || kbr->rctx->err)
273  {
274  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
275  "%s: redis connection error to %s: %s", __func__, kbr->path,
276  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
277  redisFree (kbr->rctx);
278  kbr->rctx = NULL;
279  return -1;
280  }
281 
282  rc = select_database (kbr);
283  if (rc)
284  {
285  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "No redis DB available");
286  redisFree (kbr->rctx);
287  kbr->rctx = NULL;
288  return -2;
289  }
290 
291  g_debug ("%s: connected to redis://%s/%d", __func__, kbr->path, kbr->db);
292  return 0;
293 }
294 
302 static int
304 {
305  int rc = 0;
306  redisReply *rep;
307 
308  rep = redis_cmd (kbr, "PING");
309  if (rep == NULL)
310  {
311  /* not 100% relevant but hiredis doesn't provide us with proper error
312  * codes. */
313  rc = -ECONNREFUSED;
314  goto out;
315  }
316 
317  if (rep->type != REDIS_REPLY_STATUS)
318  {
319  rc = -EINVAL;
320  goto out;
321  }
322 
323  if (g_ascii_strcasecmp (rep->str, "PONG"))
324  {
325  rc = -EPROTO;
326  goto out;
327  }
328 
329 out:
330  if (rep != NULL)
331  freeReplyObject (rep);
332 
333  return rc;
334 }
335 
343 static int
345 {
346  struct kb_redis *kbr;
347 
348  kbr = redis_kb (kb);
349 
350  redis_delete_all (kbr);
351  redis_release_db (kbr);
352 
353  if (kbr->rctx != NULL)
354  {
355  redisFree (kbr->rctx);
356  kbr->rctx = NULL;
357  }
358 
359  g_free (kb);
360  return 0;
361 }
362 
370 static int
372 {
373  int i;
374  i = ((struct kb_redis *) kb)->db;
375  if (i > 0)
376  return i;
377  return -1;
378 }
379 
388 static int
389 redis_new (kb_t *kb, const char *kb_path)
390 {
391  struct kb_redis *kbr;
392  int rc = 0;
393 
394  kbr = g_malloc0 (sizeof (struct kb_redis) + strlen (kb_path) + 1);
395  kbr->kb.kb_ops = &KBRedisOperations;
396  strcpy (kbr->path, kb_path);
397 
398  if ((rc = get_redis_ctx (kbr)) < 0)
399  return rc;
400  if (redis_test_connection (kbr))
401  {
402  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
403  "%s: cannot access redis at '%s'", __func__, kb_path);
404  redis_delete ((kb_t) kbr);
405  kbr = NULL;
406  rc = -1;
407  }
408 
409  *kb = (kb_t) kbr;
410  return rc;
411 }
412 
421 static kb_t
422 redis_direct_conn (const char *kb_path, const int kb_index)
423 {
424  struct kb_redis *kbr;
425  redisReply *rep;
426 
427  kbr = g_malloc0 (sizeof (struct kb_redis) + strlen (kb_path) + 1);
428  kbr->kb.kb_ops = &KBRedisOperations;
429  strcpy (kbr->path, kb_path);
430 
431  kbr->rctx = redisConnectUnix (kbr->path);
432  if (kbr->rctx == NULL || kbr->rctx->err)
433  {
434  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
435  "%s: redis connection error to %s: %s", __func__, kbr->path,
436  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
437  redisFree (kbr->rctx);
438  g_free (kbr);
439  return NULL;
440  }
441  kbr->db = kb_index;
442  rep = redisCommand (kbr->rctx, "SELECT %d", kb_index);
443  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
444  {
445  if (rep != NULL)
446  freeReplyObject (rep);
447  redisFree (kbr->rctx);
448  kbr->rctx = NULL;
449  return NULL;
450  }
451  freeReplyObject (rep);
452  return (kb_t) kbr;
453 }
454 
463 static kb_t
464 redis_find (const char *kb_path, const char *key)
465 {
466  struct kb_redis *kbr;
467  unsigned int i = 1;
468 
469  kbr = g_malloc0 (sizeof (struct kb_redis) + strlen (kb_path) + 1);
470  kbr->kb.kb_ops = &KBRedisOperations;
471  strcpy (kbr->path, kb_path);
472 
473  do
474  {
475  redisReply *rep;
476 
477  kbr->rctx = redisConnectUnix (kbr->path);
478  if (kbr->rctx == NULL || kbr->rctx->err)
479  {
480  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
481  "%s: redis connection error to %s: %s", __func__, kbr->path,
482  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
483  redisFree (kbr->rctx);
484  g_free (kbr);
485  return NULL;
486  }
487 
488  if (kbr->max_db == 0)
489  fetch_max_db_index (kbr);
490 
491  kbr->db = i;
492  rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
493  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
494  {
495  if (rep != NULL)
496  freeReplyObject (rep);
497  i++;
498  redisFree (kbr->rctx);
499  kbr->rctx = NULL;
500  continue;
501  }
502  freeReplyObject (rep);
503  rep = redisCommand (kbr->rctx, "SELECT %u", i);
504  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
505  {
506  redisFree (kbr->rctx);
507  kbr->rctx = NULL;
508  }
509  else
510  {
511  freeReplyObject (rep);
512  if (key)
513  {
514  char *tmp = kb_item_get_str (&kbr->kb, key);
515  if (tmp)
516  {
517  g_free (tmp);
518  return (kb_t) kbr;
519  }
520  }
521  redisFree (kbr->rctx);
522  }
523  i++;
524  }
525  while (i < kbr->max_db);
526 
527  g_free (kbr);
528  return NULL;
529 }
530 
536 void
537 kb_item_free (struct kb_item *item)
538 {
539  while (item != NULL)
540  {
541  struct kb_item *next;
542 
543  next = item->next;
544  if (item->type == KB_TYPE_STR && item->v_str != NULL)
545  g_free (item->v_str);
546  g_free (item);
547  item = next;
548  }
549 }
550 
560 static struct kb_item *
561 redis2kbitem_single (const char *name, const redisReply *elt, int force_int)
562 {
563  struct kb_item *item;
564  size_t namelen;
565 
566  if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
567  return NULL;
568 
569  namelen = strlen (name) + 1;
570 
571  item = g_malloc0 (sizeof (struct kb_item) + namelen);
572  if (elt->type == REDIS_REPLY_INTEGER)
573  {
574  item->type = KB_TYPE_INT;
575  item->v_int = elt->integer;
576  }
577  else if (force_int)
578  {
579  item->type = KB_TYPE_INT;
580  item->v_int = atoi (elt->str);
581  }
582  else
583  {
584  item->type = KB_TYPE_STR;
585  item->v_str = g_memdup (elt->str, elt->len + 1);
586  item->len = elt->len;
587  }
588 
589  item->next = NULL;
590  item->namelen = namelen;
591  strncpy (item->name, name, namelen);
592 
593  return item;
594 }
595 
604 static struct kb_item *
605 redis2kbitem (const char *name, const redisReply *rep)
606 {
607  struct kb_item *kbi;
608 
609  kbi = NULL;
610 
611  switch (rep->type)
612  {
613  unsigned int i;
614 
615  case REDIS_REPLY_STRING:
616  case REDIS_REPLY_INTEGER:
617  kbi = redis2kbitem_single (name, rep, 0);
618  break;
619 
620  case REDIS_REPLY_ARRAY:
621  for (i = 0; i < rep->elements; i++)
622  {
623  struct kb_item *tmpitem;
624 
625  tmpitem = redis2kbitem_single (name, rep->element[i], 0);
626  if (tmpitem == NULL)
627  break;
628 
629  if (kbi != NULL)
630  {
631  tmpitem->next = kbi;
632  kbi = tmpitem;
633  }
634  else
635  kbi = tmpitem;
636  }
637  break;
638 
639  case REDIS_REPLY_NIL:
640  case REDIS_REPLY_STATUS:
641  case REDIS_REPLY_ERROR:
642  default:
643  break;
644  }
645 
646  return kbi;
647 }
648 
657 static redisReply *
658 redis_cmd (struct kb_redis *kbr, const char *fmt, ...)
659 {
660  redisReply *rep;
661  va_list ap, aq;
662  int retry = 0;
663 
664  va_start (ap, fmt);
665  do
666  {
667  if (get_redis_ctx (kbr) < 0)
668  {
669  va_end (ap);
670  return NULL;
671  }
672 
673  va_copy (aq, ap);
674  rep = redisvCommand (kbr->rctx, fmt, aq);
675  va_end (aq);
676 
677  if (kbr->rctx->err)
678  {
679  if (rep != NULL)
680  freeReplyObject (rep);
681 
682  redis_lnk_reset ((kb_t) kbr);
683  retry = !retry;
684  }
685  else
686  retry = 0;
687  }
688  while (retry);
689 
690  va_end (ap);
691 
692  return rep;
693 }
694 
705 static struct kb_item *
707 {
708  struct kb_item *kbi;
709  struct kb_redis *kbr;
710  redisReply *rep;
711 
712  kbr = redis_kb (kb);
713  kbi = NULL;
714 
715  rep = redis_cmd (kbr, "LINDEX %s -1", name);
716  if (rep == NULL || rep->type != REDIS_REPLY_STRING)
717  {
718  kbi = NULL;
719  goto out;
720  }
721 
722  kbi = redis2kbitem_single (name, rep, type == KB_TYPE_INT);
723 
724 out:
725  if (rep != NULL)
726  freeReplyObject (rep);
727 
728  return kbi;
729 }
730 
740 static char *
741 redis_get_str (kb_t kb, const char *name)
742 {
743  struct kb_item *kbi;
744 
746  if (kbi != NULL)
747  {
748  char *res;
749 
750  res = kbi->v_str;
751  kbi->v_str = NULL;
752  kb_item_free (kbi);
753  return res;
754  }
755  return NULL;
756 }
757 
767 static int
768 redis_push_str (kb_t kb, const char *name, const char *value)
769 {
770  struct kb_redis *kbr;
771  redisReply *rep = NULL;
772  int rc = 0;
773 
774  kbr = redis_kb (kb);
775  rep = redis_cmd (kbr, "LPUSH %s %s", name, value);
776  if (!rep || rep->type == REDIS_REPLY_ERROR)
777  rc = -1;
778 
779  if (rep)
780  freeReplyObject (rep);
781 
782  return rc;
783 }
784 
793 static char *
794 redis_pop_str (kb_t kb, const char *name)
795 {
796  struct kb_redis *kbr;
797  redisReply *rep;
798  char *value = NULL;
799 
800  kbr = redis_kb (kb);
801  rep = redis_cmd (kbr, "RPOP %s", name);
802  if (!rep)
803  return NULL;
804 
805  if (rep->type == REDIS_REPLY_STRING)
806  value = g_strdup (rep->str);
807  freeReplyObject (rep);
808 
809  return value;
810 }
811 
821 static int
822 redis_get_int (kb_t kb, const char *name)
823 {
824  struct kb_item *kbi;
825 
827  if (kbi != NULL)
828  {
829  int res;
830 
831  res = kbi->v_int;
832  kb_item_free (kbi);
833  return res;
834  }
835  return -1;
836 }
837 
847 static char *
848 redis_get_nvt (kb_t kb, const char *oid, enum kb_nvt_pos position)
849 {
850  struct kb_redis *kbr;
851  redisReply *rep;
852  char *res = NULL;
853 
854  kbr = redis_kb (kb);
855  if (position >= NVT_TIMESTAMP_POS)
856  rep = redis_cmd (kbr, "LINDEX filename:%s %d", oid,
857  position - NVT_TIMESTAMP_POS);
858  else
859  rep = redis_cmd (kbr, "LINDEX nvt:%s %d", oid, position);
860  if (!rep)
861  return NULL;
862  if (rep->type == REDIS_REPLY_INTEGER)
863  res = g_strdup_printf ("%lld", rep->integer);
864  else if (rep->type == REDIS_REPLY_STRING)
865  res = g_strdup (rep->str);
866  freeReplyObject (rep);
867 
868  return res;
869 }
870 
879 static nvti_t *
880 redis_get_nvt_all (kb_t kb, const char *oid)
881 {
882  struct kb_redis *kbr;
883  redisReply *rep;
884 
885  kbr = redis_kb (kb);
886  rep =
887  redis_cmd (kbr, "LRANGE nvt:%s %d %d", oid, NVT_FILENAME_POS, NVT_NAME_POS);
888  if (!rep)
889  return NULL;
890  if (rep->type != REDIS_REPLY_ARRAY || rep->elements != NVT_NAME_POS + 1)
891  {
892  freeReplyObject (rep);
893  return NULL;
894  }
895  else
896  {
897  nvti_t *nvti = nvti_new ();
898 
899  nvti_set_oid (nvti, oid);
900  nvti_set_required_keys (nvti, rep->element[NVT_REQUIRED_KEYS_POS]->str);
902  nvti_set_excluded_keys (nvti, rep->element[NVT_EXCLUDED_KEYS_POS]->str);
904  nvti, rep->element[NVT_REQUIRED_UDP_PORTS_POS]->str);
906  nvti_set_dependencies (nvti, rep->element[NVT_DEPENDENCIES_POS]->str);
907  nvti_set_tag (nvti, rep->element[NVT_TAGS_POS]->str);
908  nvti_add_refs (nvti, "cve", rep->element[NVT_CVES_POS]->str, "");
909  nvti_add_refs (nvti, "bid", rep->element[NVT_BIDS_POS]->str, "");
910  nvti_add_refs (nvti, NULL, rep->element[NVT_XREFS_POS]->str, "");
911  nvti_set_category (nvti, atoi (rep->element[NVT_CATEGORY_POS]->str));
912  nvti_set_timeout (nvti, atoi (rep->element[NVT_TIMEOUT_POS]->str));
913  nvti_set_family (nvti, rep->element[NVT_FAMILY_POS]->str);
914  nvti_set_name (nvti, rep->element[NVT_NAME_POS]->str);
915 
916  freeReplyObject (rep);
917  return nvti;
918  }
919 }
920 
930 static struct kb_item *
931 redis_get_all (kb_t kb, const char *name)
932 {
933  struct kb_redis *kbr;
934  struct kb_item *kbi;
935  redisReply *rep;
936 
937  kbr = redis_kb (kb);
938 
939  rep = redis_cmd (kbr, "LRANGE %s 0 -1", name);
940  if (rep == NULL)
941  return NULL;
942 
943  kbi = redis2kbitem (name, rep);
944 
945  freeReplyObject (rep);
946 
947  return kbi;
948 }
949 
959 static struct kb_item *
960 redis_get_pattern (kb_t kb, const char *pattern)
961 {
962  struct kb_redis *kbr;
963  struct kb_item *kbi = NULL;
964  redisReply *rep;
965  unsigned int i;
966 
967  kbr = redis_kb (kb);
968  rep = redis_cmd (kbr, "KEYS %s", pattern);
969  if (!rep)
970  return NULL;
971  if (rep->type != REDIS_REPLY_ARRAY)
972  {
973  freeReplyObject (rep);
974  return NULL;
975  }
976 
977  if (get_redis_ctx (kbr) < 0)
978  return NULL;
979  for (i = 0; i < rep->elements; i++)
980  redisAppendCommand (kbr->rctx, "LRANGE %s 0 -1", rep->element[i]->str);
981 
982  for (i = 0; i < rep->elements; i++)
983  {
984  struct kb_item *tmp;
985  redisReply *rep_range;
986 
987  redisGetReply (kbr->rctx, (void **) &rep_range);
988  if (!rep)
989  continue;
990  tmp = redis2kbitem (rep->element[i]->str, rep_range);
991  if (!tmp)
992  {
993  freeReplyObject (rep_range);
994  continue;
995  }
996 
997  if (kbi)
998  {
999  struct kb_item *tmp2;
1000 
1001  tmp2 = tmp;
1002  while (tmp->next)
1003  tmp = tmp->next;
1004  tmp->next = kbi;
1005  kbi = tmp2;
1006  }
1007  else
1008  kbi = tmp;
1009  freeReplyObject (rep_range);
1010  }
1011 
1012  freeReplyObject (rep);
1013  return kbi;
1014 }
1015 
1023 static GSList *
1025 {
1026  struct kb_redis *kbr;
1027  redisReply *rep;
1028  GSList *list = NULL;
1029  size_t i;
1030 
1031  kbr = redis_kb (kb);
1032  rep = redis_cmd (kbr, "KEYS nvt:*");
1033  if (!rep)
1034  return NULL;
1035 
1036  if (rep->type != REDIS_REPLY_ARRAY)
1037  {
1038  freeReplyObject (rep);
1039  return NULL;
1040  }
1041 
1042  /* Fetch OID values from key names nvt:OID. */
1043  for (i = 0; i < rep->elements; i++)
1044  list = g_slist_prepend (list, g_strdup (rep->element[i]->str + 4));
1045  freeReplyObject (rep);
1046 
1047  return list;
1048 }
1049 
1058 static size_t
1059 redis_count (kb_t kb, const char *pattern)
1060 {
1061  struct kb_redis *kbr;
1062  redisReply *rep;
1063  size_t count;
1064 
1065  kbr = redis_kb (kb);
1066 
1067  rep = redis_cmd (kbr, "KEYS %s", pattern);
1068  if (rep == NULL)
1069  return 0;
1070 
1071  if (rep->type != REDIS_REPLY_ARRAY)
1072  {
1073  freeReplyObject (rep);
1074  return 0;
1075  }
1076 
1077  count = rep->elements;
1078  freeReplyObject (rep);
1079  return count;
1080 }
1081 
1090 static int
1091 redis_del_items (kb_t kb, const char *name)
1092 {
1093  struct kb_redis *kbr;
1094  redisReply *rep;
1095  int rc = 0;
1096 
1097  kbr = redis_kb (kb);
1098 
1099  rep = redis_cmd (kbr, "DEL %s", name);
1100  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1101  rc = -1;
1102 
1103  if (rep != NULL)
1104  freeReplyObject (rep);
1105 
1106  return rc;
1107 }
1108 
1119 static int
1120 redis_add_str_unique (kb_t kb, const char *name, const char *str, size_t len)
1121 {
1122  struct kb_redis *kbr;
1123  redisReply *rep = NULL;
1124  int rc = 0;
1125  redisContext *ctx;
1126 
1127  kbr = redis_kb (kb);
1128  if (get_redis_ctx (kbr) < 0)
1129  return -1;
1130  ctx = kbr->rctx;
1131 
1132  /* Some VTs still rely on values being unique (ie. a value inserted multiple
1133  * times, will only be present once.)
1134  * Once these are fixed, the LREM becomes redundant and should be removed.
1135  */
1136  if (len == 0)
1137  {
1138  redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
1139  redisAppendCommand (ctx, "RPUSH %s %s", name, str);
1140  redisGetReply (ctx, (void **) &rep);
1141  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1142  g_debug ("Key '%s' already contained value '%s'", name, str);
1143  freeReplyObject (rep);
1144  redisGetReply (ctx, (void **) &rep);
1145  }
1146  else
1147  {
1148  redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
1149  redisAppendCommand (ctx, "RPUSH %s %b", name, str, len);
1150  redisGetReply (ctx, (void **) &rep);
1151  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1152  g_debug ("Key '%s' already contained string '%s'", name, str);
1153  freeReplyObject (rep);
1154  redisGetReply (ctx, (void **) &rep);
1155  }
1156  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1157  rc = -1;
1158 
1159  if (rep != NULL)
1160  freeReplyObject (rep);
1161 
1162  return rc;
1163 }
1164 
1175 static int
1176 redis_add_str (kb_t kb, const char *name, const char *str, size_t len)
1177 {
1178  struct kb_redis *kbr;
1179  redisReply *rep;
1180  int rc = 0;
1181 
1182  kbr = redis_kb (kb);
1183  if (len == 0)
1184  rep = redis_cmd (kbr, "RPUSH %s %s", name, str);
1185  else
1186  rep = redis_cmd (kbr, "RPUSH %s %b", name, str, len);
1187  if (!rep || rep->type == REDIS_REPLY_ERROR)
1188  rc = -1;
1189 
1190  if (rep)
1191  freeReplyObject (rep);
1192  return rc;
1193 }
1194 
1205 static int
1206 redis_set_str (kb_t kb, const char *name, const char *val, size_t len)
1207 {
1208  struct kb_redis *kbr;
1209  redisReply *rep = NULL;
1210  redisContext *ctx;
1211  int rc = 0, i = 4;
1212 
1213  kbr = redis_kb (kb);
1214  if (get_redis_ctx (kbr) < 0)
1215  return -1;
1216  ctx = kbr->rctx;
1217  redisAppendCommand (ctx, "MULTI");
1218  redisAppendCommand (ctx, "DEL %s", name);
1219  if (len == 0)
1220  redisAppendCommand (ctx, "RPUSH %s %s", name, val);
1221  else
1222  redisAppendCommand (ctx, "RPUSH %s %b", name, val, len);
1223  redisAppendCommand (ctx, "EXEC");
1224  while (i--)
1225  {
1226  redisGetReply (ctx, (void **) &rep);
1227  if (!rep || rep->type == REDIS_REPLY_ERROR)
1228  rc = -1;
1229  if (rep)
1230  freeReplyObject (rep);
1231  }
1232 
1233  return rc;
1234 }
1235 
1245 static int
1246 redis_add_int_unique (kb_t kb, const char *name, int val)
1247 {
1248  struct kb_redis *kbr;
1249  redisReply *rep;
1250  int rc = 0;
1251  redisContext *ctx;
1252 
1253  kbr = redis_kb (kb);
1254  if (get_redis_ctx (kbr) < 0)
1255  return -1;
1256  ctx = kbr->rctx;
1257  redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
1258  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1259  redisGetReply (ctx, (void **) &rep);
1260  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1261  g_debug ("Key '%s' already contained integer '%d'", name, val);
1262  freeReplyObject (rep);
1263  redisGetReply (ctx, (void **) &rep);
1264  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1265  {
1266  rc = -1;
1267  goto out;
1268  }
1269 
1270 out:
1271  if (rep != NULL)
1272  freeReplyObject (rep);
1273 
1274  return rc;
1275 }
1276 
1286 static int
1287 redis_add_int (kb_t kb, const char *name, int val)
1288 {
1289  redisReply *rep;
1290  int rc = 0;
1291 
1292  rep = redis_cmd (redis_kb (kb), "RPUSH %s %d", name, val);
1293  if (!rep || rep->type == REDIS_REPLY_ERROR)
1294  rc = -1;
1295  if (rep)
1296  freeReplyObject (rep);
1297 
1298  return rc;
1299 }
1300 
1310 static int
1311 redis_set_int (kb_t kb, const char *name, int val)
1312 {
1313  struct kb_redis *kbr;
1314  redisReply *rep = NULL;
1315  redisContext *ctx;
1316  int rc = 0, i = 4;
1317 
1318  kbr = redis_kb (kb);
1319  if (get_redis_ctx (redis_kb (kb)) < 0)
1320  return -1;
1321  ctx = kbr->rctx;
1322  redisAppendCommand (ctx, "MULTI");
1323  redisAppendCommand (ctx, "DEL %s", name);
1324  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1325  redisAppendCommand (ctx, "EXEC");
1326  while (i--)
1327  {
1328  redisGetReply (ctx, (void **) &rep);
1329  if (!rep || rep->type == REDIS_REPLY_ERROR)
1330  rc = -1;
1331  if (rep)
1332  freeReplyObject (rep);
1333  }
1334 
1335  return rc;
1336 }
1337 
1347 static int
1348 redis_add_nvt (kb_t kb, const nvti_t *nvt, const char *filename)
1349 {
1350  struct kb_redis *kbr;
1351  redisReply *rep = NULL;
1352  int rc = 0;
1353  unsigned int i;
1354  gchar *cves, *bids, *xrefs;
1355 
1356  if (!nvt || !filename)
1357  return -1;
1358 
1359  cves = nvti_refs (nvt, "cve", "", 0);
1360  bids = nvti_refs (nvt, "bid", "", 0);
1361  xrefs = nvti_refs (nvt, NULL, "cve,bid", 1);
1362 
1363  kbr = redis_kb (kb);
1364  rep = redis_cmd (
1365  kbr, "RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %d %s %s",
1366  nvti_oid (nvt), filename, nvti_required_keys (nvt) ?: "",
1367  nvti_mandatory_keys (nvt) ?: "", nvti_excluded_keys (nvt) ?: "",
1368  nvti_required_udp_ports (nvt) ?: "", nvti_required_ports (nvt) ?: "",
1369  nvti_dependencies (nvt) ?: "", nvti_tag (nvt) ?: "", cves ?: "",
1370  bids ?: "", xrefs ?: "", nvti_category (nvt),
1371  nvti_timeout (nvt), nvti_family (nvt), nvti_name (nvt));
1372  g_free (cves);
1373  g_free (bids);
1374  g_free (xrefs);
1375  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1376  rc = -1;
1377  if (rep != NULL)
1378  freeReplyObject (rep);
1379 
1380  if (nvti_pref_len (nvt))
1381  redis_cmd (kbr, "DEL oid:%s:prefs", nvti_oid (nvt));
1382  for (i = 0; i < nvti_pref_len (nvt); i++)
1383  {
1384  const nvtpref_t *pref = nvti_pref (nvt, i);
1385 
1386  rep = redis_cmd (kbr, "RPUSH oid:%s:prefs %d|||%s|||%s|||%s",
1387  nvti_oid (nvt), nvtpref_id (pref), nvtpref_name (pref),
1388  nvtpref_type (pref), nvtpref_default (pref));
1389  if (!rep || rep->type == REDIS_REPLY_ERROR)
1390  rc = -1;
1391  if (rep)
1392  freeReplyObject (rep);
1393  }
1394  rep = redis_cmd (kbr, "RPUSH filename:%s %lu %s", filename, time (NULL),
1395  nvti_oid (nvt));
1396  if (!rep || rep->type == REDIS_REPLY_ERROR)
1397  rc = -1;
1398  if (rep)
1399  freeReplyObject (rep);
1400  return rc;
1401 }
1402 
1411 static int
1413 {
1414  struct kb_redis *kbr;
1415 
1416  kbr = redis_kb (kb);
1417 
1418  if (kbr->rctx != NULL)
1419  {
1420  redisFree (kbr->rctx);
1421  kbr->rctx = NULL;
1422  }
1423 
1424  return 0;
1425 }
1426 
1435 static int
1436 redis_flush_all (kb_t kb, const char *except)
1437 {
1438  unsigned int i = 1;
1439  struct kb_redis *kbr;
1440 
1441  kbr = redis_kb (kb);
1442  if (kbr->rctx)
1443  redisFree (kbr->rctx);
1444 
1445  g_debug ("%s: deleting all DBs at %s except %s", __func__, kbr->path, except);
1446  do
1447  {
1448  redisReply *rep;
1449 
1450  kbr->rctx = redisConnectUnix (kbr->path);
1451  if (kbr->rctx == NULL || kbr->rctx->err)
1452  {
1453  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1454  "%s: redis connection error to %s: %s", __func__, kbr->path,
1455  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
1456  redisFree (kbr->rctx);
1457  kbr->rctx = NULL;
1458  return -1;
1459  }
1460 
1461  kbr->db = i;
1462  rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
1463  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
1464  {
1465  freeReplyObject (rep);
1466  redisFree (kbr->rctx);
1467  i++;
1468  continue;
1469  }
1470  freeReplyObject (rep);
1471  rep = redisCommand (kbr->rctx, "SELECT %u", i);
1472  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1473  {
1474  freeReplyObject (rep);
1475  redisFree (kbr->rctx);
1476  kbr->rctx = NULL;
1477  }
1478  else
1479  {
1480  freeReplyObject (rep);
1481  /* Don't remove DB if it has "except" key. */
1482  if (except)
1483  {
1484  char *tmp = kb_item_get_str (kb, except);
1485  if (tmp)
1486  {
1487  g_free (tmp);
1488  i++;
1489  redisFree (kbr->rctx);
1490  continue;
1491  }
1492  }
1493  redis_delete_all (kbr);
1494  redis_release_db (kbr);
1495  redisFree (kbr->rctx);
1496  }
1497  i++;
1498  }
1499  while (i < kbr->max_db);
1500 
1501  g_free (kb);
1502  return 0;
1503 }
1504 
1512 int
1514 {
1515  int rc;
1516  redisReply *rep;
1517  struct kb_redis *kbr;
1518 
1519  kbr = redis_kb (kb);
1520  g_debug ("%s: saving all elements from KB #%u", __func__, kbr->db);
1521  rep = redis_cmd (kbr, "SAVE");
1522  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1523  {
1524  rc = -1;
1525  goto err_cleanup;
1526  }
1527 
1528  rc = 0;
1529 
1530 err_cleanup:
1531  if (rep != NULL)
1532  freeReplyObject (rep);
1533 
1534  return rc;
1535 }
1536 
1544 int
1546 {
1547  int rc;
1548  redisReply *rep;
1549  struct sigaction new_action, original_action;
1550 
1551  /* Ignore SIGPIPE, in case of a lost connection. */
1552  new_action.sa_flags = 0;
1553  if (sigemptyset (&new_action.sa_mask))
1554  return -1;
1555  new_action.sa_handler = SIG_IGN;
1556  if (sigaction (SIGPIPE, &new_action, &original_action))
1557  return -1;
1558 
1559  g_debug ("%s: deleting all elements from KB #%u", __func__, kbr->db);
1560  rep = redis_cmd (kbr, "FLUSHDB");
1561  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1562  {
1563  rc = -1;
1564  goto err_cleanup;
1565  }
1566 
1567  rc = 0;
1568 
1569 err_cleanup:
1570  if (sigaction (SIGPIPE, &original_action, NULL))
1571  return -1;
1572  if (rep != NULL)
1573  freeReplyObject (rep);
1574 
1575  return rc;
1576 }
1577 
1584 static const struct kb_operations KBRedisOperations = {
1585  .kb_new = redis_new,
1586  .kb_find = redis_find,
1587  .kb_delete = redis_delete,
1588  .kb_get_single = redis_get_single,
1589  .kb_get_str = redis_get_str,
1590  .kb_get_int = redis_get_int,
1591  .kb_get_nvt = redis_get_nvt,
1592  .kb_get_nvt_all = redis_get_nvt_all,
1593  .kb_get_nvt_oids = redis_get_oids,
1594  .kb_push_str = redis_push_str,
1595  .kb_pop_str = redis_pop_str,
1596  .kb_get_all = redis_get_all,
1597  .kb_get_pattern = redis_get_pattern,
1598  .kb_count = redis_count,
1599  .kb_add_str = redis_add_str,
1600  .kb_add_str_unique = redis_add_str_unique,
1601  .kb_set_str = redis_set_str,
1602  .kb_add_int = redis_add_int,
1603  .kb_add_int_unique = redis_add_int_unique,
1604  .kb_set_int = redis_set_int,
1605  .kb_add_nvt = redis_add_nvt,
1606  .kb_del_items = redis_del_items,
1607  .kb_lnk_reset = redis_lnk_reset,
1608  .kb_save = redis_save,
1609  .kb_flush = redis_flush_all,
1610  .kb_direct_conn = redis_direct_conn,
1611  .kb_get_kb_index = redis_get_kb_index,
1612 };
1613 
nvti_pref
const nvtpref_t * nvti_pref(const nvti_t *n, guint p)
Get the n'th preferences of the NVT.
Definition: nvti.c:929
NVT_EXCLUDED_KEYS_POS
@ NVT_EXCLUDED_KEYS_POS
Definition: kb.h:63
redis_kb
#define redis_kb(__kb)
Definition: kb.c:67
nvti_set_required_udp_ports
int nvti_set_required_udp_ports(nvti_t *n, const gchar *required_udp_ports)
Set the required udp ports of a NVT.
Definition: nvti.c:1422
kb.h
Knowledge base management API - Redis backend.
NVT_BIDS_POS
@ NVT_BIDS_POS
Definition: kb.h:69
kb_item_get_str
static char * kb_item_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.h:327
redis_get_all
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
Definition: kb.c:931
redis_cmd
static redisReply * redis_cmd(struct kb_redis *kbr, const char *fmt,...)
Execute a redis command and get a redis reply.
Definition: kb.c:658
nvti_set_required_keys
int nvti_set_required_keys(nvti_t *n, const gchar *required_keys)
Set the required keys of a NVT.
Definition: nvti.c:1322
nvti_family
gchar * nvti_family(const nvti_t *n)
Get the family name.
Definition: nvti.c:901
redis_save
int redis_save(kb_t kb)
Save all the elements from the KB.
Definition: kb.c:1513
NVT_NAME_POS
@ NVT_NAME_POS
Definition: kb.h:74
kb_operations
KB interface. Functions provided by an implementation. All functions have to be provided,...
Definition: kb.h:121
nvti_oid
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition: nvti.c:503
redis_push_str
static int redis_push_str(kb_t kb, const char *name, const char *value)
Push a new entry under a given key.
Definition: kb.c:768
kb_item::name
char name[0]
Definition: kb.h:97
redis_direct_conn
static kb_t redis_direct_conn(const char *kb_path, const int kb_index)
Connect to a Knowledge Base object with the given kb_index.
Definition: kb.c:422
redis_del_items
static int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
Definition: kb.c:1091
redis_get_str
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.c:741
kb_item::len
size_t len
Definition: kb.h:93
redis_get_oids
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
Definition: kb.c:1024
redis_new
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
Definition: kb.c:389
redis_get_pattern
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
Definition: kb.c:960
redis2kbitem_single
static struct kb_item * redis2kbitem_single(const char *name, const redisReply *elt, int force_int)
Give a single KB item.
Definition: kb.c:561
KBDefaultOperations
const struct kb_operations * KBDefaultOperations
Default KB operations. No selection mechanism is provided yet since there's only one implementation (...
Definition: kb.c:1614
try_database_index
static int try_database_index(struct kb_redis *kbr, int index)
Attempt to atomically acquire ownership of a database.
Definition: kb.c:83
redis_add_str_unique
static int redis_add_str_unique(kb_t kb, const char *name, const char *str, size_t len)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1120
kb_redis::kb
struct kb kb
Definition: kb.c:61
NVT_FILENAME_POS
@ NVT_FILENAME_POS
Definition: kb.h:60
NVT_TIMEOUT_POS
@ NVT_TIMEOUT_POS
Definition: kb.h:72
nvtpref_id
int nvtpref_id(const nvtpref_t *np)
Get the ID of a NVT Preference.
Definition: nvti.c:398
redis_delete_all
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
Definition: kb.c:1545
nvti_set_name
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
Definition: nvti.c:992
redis_lnk_reset
static int redis_lnk_reset(kb_t)
Reset connection to the KB. This is called after each fork() to make sure connections aren't shared b...
Definition: kb.c:1412
kb_item
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
Definition: kb.h:83
nvti_refs
gchar * nvti_refs(const nvti_t *n, const gchar *type, const gchar *exclude_types, guint use_types)
Get references as string.
Definition: nvti.c:658
nvti_required_udp_ports
gchar * nvti_required_udp_ports(const nvti_t *n)
Get the required udp ports list.
Definition: nvti.c:859
nvti
The structure of a information record that corresponds to a NVT.
Definition: nvti.c:270
nvti_required_ports
gchar * nvti_required_ports(const nvti_t *n)
Get the required ports list.
Definition: nvti.c:845
NVT_REQUIRED_UDP_PORTS_POS
@ NVT_REQUIRED_UDP_PORTS_POS
Definition: kb.h:64
nvti_category
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
Definition: nvti.c:956
NVT_TIMESTAMP_POS
@ NVT_TIMESTAMP_POS
Definition: kb.h:75
nvti_set_excluded_keys
int nvti_set_excluded_keys(nvti_t *n, const gchar *excluded_keys)
Set the excluded keys of a NVT.
Definition: nvti.c:1372
redis_get_kb_index
static int redis_get_kb_index(kb_t kb)
Return the kb index.
Definition: kb.c:371
kb_item::v_int
int v_int
Definition: kb.h:90
kb_item::v_str
char * v_str
Definition: kb.h:89
NVT_XREFS_POS
@ NVT_XREFS_POS
Definition: kb.h:70
kb_item_free
void kb_item_free(struct kb_item *item)
Release a KB item (or a list).
Definition: kb.c:537
redis_get_int
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
Definition: kb.c:822
nvti_add_refs
int nvti_add_refs(nvti_t *n, const gchar *type, const gchar *ref_ids, const gchar *ref_text)
Add many new vtref from a comma-separated list.
Definition: nvti.c:1557
redis_add_str
static int redis_add_str(kb_t kb, const char *name, const char *str, size_t len)
Insert (append) a new entry under a given name.
Definition: kb.c:1176
nvtpref
The structure for a preference of a NVT.
Definition: nvti.c:333
get_redis_ctx
static int get_redis_ctx(struct kb_redis *kbr)
Get redis context if it is already connected or do a a connection.
Definition: kb.c:264
nvti_set_timeout
int nvti_set_timeout(nvti_t *n, const gint timeout)
Set the timeout of a NVT Info.
Definition: nvti.c:1513
redis_set_str
static int redis_set_str(kb_t kb, const char *name, const char *val, size_t len)
Set (replace) a new entry under a given name.
Definition: kb.c:1206
nvti_pref_len
guint nvti_pref_len(const nvti_t *n)
Get the number of preferences of the NVT.
Definition: nvti.c:914
NVT_CATEGORY_POS
@ NVT_CATEGORY_POS
Definition: kb.h:71
redis_release_db
static int redis_release_db(struct kb_redis *kbr)
Release DB.
Definition: kb.c:221
kb_redis::max_db
unsigned int max_db
Definition: kb.c:62
NVT_DEPENDENCIES_POS
@ NVT_DEPENDENCIES_POS
Definition: kb.h:66
kb::kb_ops
const struct kb_operations * kb_ops
Definition: kb.h:107
nvti_set_dependencies
int nvti_set_dependencies(nvti_t *n, const gchar *dependencies)
Set the dependencies of a NVT.
Definition: nvti.c:1297
redis_add_nvt
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Definition: kb.c:1348
KB_TYPE_STR
@ KB_TYPE_STR
Definition: kb.h:50
kb_item::next
struct kb_item * next
Definition: kb.h:94
kb_redis::db
unsigned int db
Definition: kb.c:63
kb_redis
Subclass of struct kb, it contains the redis-specific fields, such as the redis context,...
Definition: kb.c:59
redis_flush_all
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
Definition: kb.c:1436
NVT_FAMILY_POS
@ NVT_FAMILY_POS
Definition: kb.h:73
redis_delete
static int redis_delete(kb_t kb)
Delete all entries and release ownership on the namespace.
Definition: kb.c:344
nvti_tag
gchar * nvti_tag(const nvti_t *n)
Get the tags.
Definition: nvti.c:761
nvti_set_tag
int nvti_set_tag(nvti_t *n, const gchar *tag)
Set the tags of a NVT.
Definition: nvti.c:1248
redis_get_nvt
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
Definition: kb.c:848
redis_pop_str
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Definition: kb.c:794
kb
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:105
nvtpref_name
gchar * nvtpref_name(const nvtpref_t *np)
Get the Name of a NVT Preference.
Definition: nvti.c:412
nvti_mandatory_keys
gchar * nvti_mandatory_keys(const nvti_t *n)
Get the mandatory keys list.
Definition: nvti.c:817
nvti_timeout
gint nvti_timeout(const nvti_t *n)
Get the timeout for this NVT.
Definition: nvti.c:943
nvti_dependencies
gchar * nvti_dependencies(const nvti_t *n)
Get the dependencies list.
Definition: nvti.c:789
redis2kbitem
static struct kb_item * redis2kbitem(const char *name, const redisReply *rep)
Fetch a KB item or list from a redis Reply.
Definition: kb.c:605
NVT_CVES_POS
@ NVT_CVES_POS
Definition: kb.h:68
NVT_MANDATORY_KEYS_POS
@ NVT_MANDATORY_KEYS_POS
Definition: kb.h:62
nvti_name
gchar * nvti_name(const nvti_t *n)
Get the name.
Definition: nvti.c:517
redis_count
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
Definition: kb.c:1059
select_database
static int select_database(struct kb_redis *kbr)
Select DB.
Definition: kb.c:169
KBRedisOperations
static const struct kb_operations KBRedisOperations
Default KB operations.
Definition: kb.c:52
kb_item_type
kb_item_type
Possible type of a kb_item.
Definition: kb.h:46
kb_redis::rctx
redisContext * rctx
Definition: kb.c:64
kb_operations::kb_new
int(* kb_new)(kb_t *, const char *)
Definition: kb.h:124
redis_get_single
static struct kb_item * redis_get_single(kb_t kb, const char *name, enum kb_item_type type)
Get a single KB element.
Definition: kb.c:706
nvti_excluded_keys
gchar * nvti_excluded_keys(const nvti_t *n)
Get the excluded keys list.
Definition: nvti.c:831
redis_find
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
Definition: kb.c:464
redis_add_int_unique
static int redis_add_int_unique(kb_t kb, const char *name, int val)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1246
nvti_set_required_ports
int nvti_set_required_ports(nvti_t *n, const gchar *required_ports)
Set the required ports of a NVT.
Definition: nvti.c:1397
kb_item::namelen
size_t namelen
Definition: kb.h:96
NVT_REQUIRED_KEYS_POS
@ NVT_REQUIRED_KEYS_POS
Definition: kb.h:61
nvtpref_default
gchar * nvtpref_default(const nvtpref_t *np)
Get the Default of a NVT Preference.
Definition: nvti.c:440
kb_redis::path
char path[0]
Definition: kb.c:65
GLOBAL_DBINDEX_NAME
#define GLOBAL_DBINDEX_NAME
Name of the namespace usage bitmap in redis.
Definition: kb.c:50
nvti_new
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition: nvti.c:454
NVT_TAGS_POS
@ NVT_TAGS_POS
Definition: kb.h:67
nvtpref_type
gchar * nvtpref_type(const nvtpref_t *np)
Get the Type of a NVT Preference.
Definition: nvti.c:426
KB_TYPE_INT
@ KB_TYPE_INT
Definition: kb.h:49
nvti_set_family
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
Definition: nvti.c:1492
kb_t
struct kb * kb_t
type abstraction to hide KB internals.
Definition: kb.h:113
nvti_set_category
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
Definition: nvti.c:1532
G_LOG_DOMAIN
#define G_LOG_DOMAIN
Definition: kb.c:38
NVT_REQUIRED_PORTS_POS
@ NVT_REQUIRED_PORTS_POS
Definition: kb.h:65
redis_get_nvt_all
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
Definition: kb.c:880
nvti_set_oid
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
Definition: nvti.c:971
redis_test_connection
static int redis_test_connection(struct kb_redis *kbr)
Test redis connection.
Definition: kb.c:303
fetch_max_db_index
static int fetch_max_db_index(struct kb_redis *kbr)
Set the number of databases have been configured into kbr struct.
Definition: kb.c:114
nvti_set_mandatory_keys
int nvti_set_mandatory_keys(nvti_t *n, const gchar *mandatory_keys)
Set the mandatory keys of a NVT.
Definition: nvti.c:1347
redis_add_int
static int redis_add_int(kb_t kb, const char *name, int val)
Insert (append) a new entry under a given name.
Definition: kb.c:1287
kb_nvt_pos
kb_nvt_pos
Possible positions of nvt values in cache list.
Definition: kb.h:58
kb_item::type
enum kb_item_type type
Definition: kb.h:85
redis_set_int
static int redis_set_int(kb_t kb, const char *name, int val)
Set (replace) a new entry under a given name.
Definition: kb.c:1311
nvti_required_keys
gchar * nvti_required_keys(const nvti_t *n)
Get the required keys list.
Definition: nvti.c:803