Greenbone Vulnerability Management Libraries  10.0.0
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 #include <unistd.h> /* for sleep */
37 
38 #undef G_LOG_DOMAIN
39 #define G_LOG_DOMAIN "lib kb"
40 
51 #define GLOBAL_DBINDEX_NAME "GVM.__GlobalDBIndex"
52 
57 #define KB_RETRY_DELAY 60
58 
59 static const struct kb_operations KBRedisOperations;
60 
66 struct kb_redis
67 {
68  struct kb kb;
69  unsigned int max_db;
70  unsigned int db;
71  redisContext *rctx;
72  char path[0];
73 };
74 #define redis_kb(__kb) ((struct kb_redis *) (__kb))
75 
76 static int
77 redis_delete_all (struct kb_redis *);
78 static int redis_lnk_reset (kb_t);
79 static int
80 redis_flush_all (kb_t, const char *);
81 static redisReply *
82 redis_cmd (struct kb_redis *kbr, const char *fmt, ...);
83 
88 static int
89 try_database_index (struct kb_redis *kbr, int index)
90 {
91  redisContext *ctx = kbr->rctx;
92  redisReply *rep;
93  int rc = 0;
94 
95  rep = redisCommand (ctx, "HSETNX %s %d 1", GLOBAL_DBINDEX_NAME, index);
96  if (rep == NULL)
97  return -ENOMEM;
98 
99  if (rep->type != REDIS_REPLY_INTEGER)
100  rc = -EPROTO;
101  else if (rep->integer == 0)
102  rc = -EALREADY;
103  else
104  kbr->db = index;
105 
106  freeReplyObject (rep);
107 
108  return rc;
109 }
110 
111 /* Redis 2.4.* compatibility mode.
112  *
113  * Before 2.6.* redis won't tell its clients how many databases have been
114  * configured. We can find it empirically by attempting to select a given
115  * DB and seeing whether we get an error or not.
116  */
120 #define MAX_DB_INDEX__24 1000
121 
128 static int
130 {
131  redisContext *ctx = kbr->rctx;
132  redisReply *rep;
133  int min, max;
134  int rc = 0;
135 
136  min = 1;
137  max = MAX_DB_INDEX__24;
138 
139  while (min < max)
140  {
141  int current;
142 
143  current = min + ((max - min) / 2);
144 
145  rep = redisCommand (ctx, "SELECT %d", current);
146  if (rep == NULL)
147  {
148  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
149  "%s: redis command failed with '%s'", __func__, ctx->errstr);
150  return -1;
151  }
152 
153  switch (rep->type)
154  {
155  case REDIS_REPLY_ERROR:
156  max = current;
157  break;
158 
159  case REDIS_REPLY_STATUS:
160  min = current + 1;
161  break;
162 
163  default:
164  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
165  "%s: unexpected reply of type %d", __func__, rep->type);
166  freeReplyObject (rep);
167  return -1;
168  }
169  freeReplyObject (rep);
170  }
171 
172  kbr->max_db = min;
173 
174  /* Go back to DB #0 */
175  rep = redisCommand (ctx, "SELECT 0");
176  if (rep == NULL)
177  {
178  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
179  "%s: DB selection failed with '%s'", __func__, ctx->errstr);
180  rc = -1;
181  }
182 
183  if (rep)
184  freeReplyObject (rep);
185 
186  return rc;
187 }
188 
195 static int
197 {
198  int rc = 0;
199  redisContext *ctx = kbr->rctx;
200  redisReply *rep = NULL;
201 
202  rep = redisCommand (ctx, "CONFIG GET databases");
203  if (rep == NULL)
204  {
205  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
206  "%s: redis command failed with '%s'", __func__, ctx->errstr);
207  rc = -1;
208  goto err_cleanup;
209  }
210 
211  if (rep->type != REDIS_REPLY_ARRAY)
212  {
213  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
214  "%s: cannot retrieve max DB number: %s", __func__, rep->str);
215  rc = -1;
216  goto err_cleanup;
217  }
218 
219  if (rep->elements == 0)
220  {
221  /* Redis 2.4 compatibility mode. Suboptimal... */
222  rc = fetch_max_db_index_compat (kbr);
223  }
224  else if (rep->elements == 2)
225  {
226  kbr->max_db = (unsigned) atoi (rep->element[1]->str);
227  }
228  else
229  {
230  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
231  "%s: unexpected reply length (%zd)", __func__, rep->elements);
232  rc = -1;
233  goto err_cleanup;
234  }
235 
236  g_debug ("%s: maximum DB number: %u", __func__, kbr->max_db);
237 
238 err_cleanup:
239  if (rep != NULL)
240  freeReplyObject (rep);
241 
242  return rc;
243 }
244 
253 static int
255 {
256  int rc;
257  redisContext *ctx = kbr->rctx;
258  redisReply *rep = NULL;
259 
260  if (kbr->db == 0)
261  {
262  unsigned i;
263 
264  if (kbr->max_db == 0)
265  fetch_max_db_index (kbr);
266 
267  for (i = 1; i < kbr->max_db; i++)
268  {
269  rc = try_database_index (kbr, i);
270  if (rc == 0)
271  break;
272  }
273  }
274 
275  /* No DB available, give up. */
276  if (kbr->db == 0)
277  {
278  rc = -1;
279  goto err_cleanup;
280  }
281 
282  rep = redisCommand (ctx, "SELECT %u", kbr->db);
283  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
284  {
285  rc = -1;
286  goto err_cleanup;
287  }
288 
289  rc = 0;
290 
291 err_cleanup:
292  if (rep != NULL)
293  freeReplyObject (rep);
294 
295  return rc;
296 }
297 
304 static int
306 {
307  int rc;
308  redisContext *ctx = kbr->rctx;
309  redisReply *rep;
310 
311  if (ctx == NULL)
312  return -EINVAL;
313 
314  rep = redisCommand (ctx, "SELECT 0"); /* Management database*/
315  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
316  {
317  rc = -1;
318  goto err_cleanup;
319  }
320  freeReplyObject (rep);
321 
322  rep = redisCommand (ctx, "HDEL %s %d", GLOBAL_DBINDEX_NAME, kbr->db);
323  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER)
324  {
325  rc = -1;
326  goto err_cleanup;
327  }
328 
329  rc = 0;
330 
331 err_cleanup:
332  if (rep != NULL)
333  freeReplyObject (rep);
334 
335  return rc;
336 }
337 
345 static redisContext *
346 get_redis_ctx (struct kb_redis *kbr)
347 {
348  int rc;
349 
350  if (kbr->rctx != NULL)
351  return kbr->rctx;
352 
353  do
354  {
355  kbr->rctx = redisConnectUnix (kbr->path);
356  if (kbr->rctx == NULL || kbr->rctx->err)
357  {
358  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
359  "%s: redis connection error: %s", __func__,
360  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
361  redisFree (kbr->rctx);
362  kbr->rctx = NULL;
363  return NULL;
364  }
365 
366  rc = select_database (kbr);
367  if (rc)
368  {
369  g_debug ("%s: No redis DB available, retrying in %ds...", __func__,
371  sleep (KB_RETRY_DELAY);
372  redisFree (kbr->rctx);
373  kbr->rctx = NULL;
374  }
375  }
376  while (rc != 0);
377 
378  g_debug ("%s: connected to redis://%s/%d", __func__, kbr->path, kbr->db);
379  return kbr->rctx;
380 }
381 
387 static int
389 {
390  int rc = 0;
391  redisReply *rep;
392 
393  rep = redis_cmd (kbr, "PING");
394  if (rep == NULL)
395  {
396  /* not 100% relevant but hiredis doesn't provide us with proper error
397  * codes. */
398  rc = -ECONNREFUSED;
399  goto out;
400  }
401 
402  if (rep->type != REDIS_REPLY_STATUS)
403  {
404  rc = -EINVAL;
405  goto out;
406  }
407 
408  if (g_ascii_strcasecmp (rep->str, "PONG"))
409  {
410  rc = -EPROTO;
411  goto out;
412  }
413 
414 out:
415  if (rep != NULL)
416  freeReplyObject (rep);
417 
418  return rc;
419 }
420 
426 static int
428 {
429  struct kb_redis *kbr;
430 
431  kbr = redis_kb (kb);
432 
433  redis_delete_all (kbr);
434  redis_release_db (kbr);
435 
436  if (kbr->rctx != NULL)
437  {
438  redisFree (kbr->rctx);
439  kbr->rctx = NULL;
440  }
441 
442  g_free (kb);
443  return 0;
444 }
445 
451 static int
453 {
454  int i;
455  i = ((struct kb_redis *) kb)->db;
456  if (i > 0)
457  return i;
458  return -1;
459 }
460 
467 static int
468 redis_new (kb_t *kb, const char *kb_path)
469 {
470  struct kb_redis *kbr;
471  int rc = 0;
472 
473  kbr = g_malloc0 (sizeof (struct kb_redis) + strlen (kb_path) + 1);
474  kbr->kb.kb_ops = &KBRedisOperations;
475  strncpy (kbr->path, kb_path, strlen (kb_path));
476 
477  rc = redis_test_connection (kbr);
478  if (rc)
479  {
480  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
481  "%s: cannot access redis at '%s'", __func__, kb_path);
482  redis_delete ((kb_t) kbr);
483  kbr = NULL;
484  }
485 
486  *kb = (kb_t) kbr;
487 
488  return rc;
489 }
490 
497 static kb_t
498 redis_direct_conn (const char *kb_path, const int kb_index)
499 {
500  struct kb_redis *kbr;
501  redisReply *rep;
502 
503  kbr = g_malloc0 (sizeof (struct kb_redis) + strlen (kb_path) + 1);
504  kbr->kb.kb_ops = &KBRedisOperations;
505  strncpy (kbr->path, kb_path, strlen (kb_path));
506 
507  kbr->rctx = redisConnectUnix (kbr->path);
508  if (kbr->rctx == NULL || kbr->rctx->err)
509  {
510  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
511  "%s: redis connection error: %s", __func__,
512  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
513  redisFree (kbr->rctx);
514  g_free (kbr);
515  return NULL;
516  }
517  kbr->db = kb_index;
518  rep = redisCommand (kbr->rctx, "SELECT %d", kb_index);
519  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
520  {
521  if (rep != NULL)
522  freeReplyObject (rep);
523  redisFree (kbr->rctx);
524  kbr->rctx = NULL;
525  return NULL;
526  }
527  freeReplyObject (rep);
528  return (kb_t) kbr;
529 }
530 
537 static kb_t
538 redis_find (const char *kb_path, const char *key)
539 {
540  struct kb_redis *kbr;
541  unsigned int i = 1;
542 
543  kbr = g_malloc0 (sizeof (struct kb_redis) + strlen (kb_path) + 1);
544  kbr->kb.kb_ops = &KBRedisOperations;
545  strncpy (kbr->path, kb_path, strlen (kb_path));
546 
547  do
548  {
549  redisReply *rep;
550 
551  kbr->rctx = redisConnectUnix (kbr->path);
552  if (kbr->rctx == NULL || kbr->rctx->err)
553  {
554  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
555  "%s: redis connection error: %s", __func__,
556  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
557  redisFree (kbr->rctx);
558  g_free (kbr);
559  return NULL;
560  }
561 
562  if (kbr->max_db == 0)
563  fetch_max_db_index (kbr);
564 
565  kbr->db = i;
566  rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
567  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
568  {
569  if (rep != NULL)
570  freeReplyObject (rep);
571  i++;
572  continue;
573  }
574  freeReplyObject (rep);
575  rep = redisCommand (kbr->rctx, "SELECT %u", i);
576  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
577  {
578  sleep (KB_RETRY_DELAY);
579  kbr->rctx = NULL;
580  }
581  else
582  {
583  freeReplyObject (rep);
584  if (key)
585  {
586  char *tmp = kb_item_get_str (&kbr->kb, key);
587  if (tmp)
588  {
589  g_free (tmp);
590  return (kb_t) kbr;
591  }
592  }
593  }
594  redisFree (kbr->rctx);
595  i++;
596  }
597  while (i < kbr->max_db);
598 
599  g_free (kbr);
600  return NULL;
601 }
602 
607 void
608 kb_item_free (struct kb_item *item)
609 {
610  while (item != NULL)
611  {
612  struct kb_item *next;
613 
614  next = item->next;
615  if (item->type == KB_TYPE_STR && item->v_str != NULL)
616  g_free (item->v_str);
617  g_free (item);
618  item = next;
619  }
620 }
621 
629 static struct kb_item *
630 redis2kbitem_single (const char *name, const redisReply *elt, int force_int)
631 {
632  struct kb_item *item;
633  size_t namelen;
634 
635  if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
636  return NULL;
637 
638  namelen = strlen (name) + 1;
639 
640  item = g_malloc0 (sizeof (struct kb_item) + namelen);
641  if (elt->type == REDIS_REPLY_INTEGER)
642  {
643  item->type = KB_TYPE_INT;
644  item->v_int = elt->integer;
645  }
646  else if (force_int)
647  {
648  item->type = KB_TYPE_INT;
649  item->v_int = atoi (elt->str);
650  }
651  else
652  {
653  item->type = KB_TYPE_STR;
654  item->v_str = g_memdup (elt->str, elt->len + 1);
655  item->len = elt->len;
656  }
657 
658  item->next = NULL;
659  item->namelen = namelen;
660  strncpy (item->name, name, namelen);
661 
662  return item;
663 }
664 
671 static struct kb_item *
672 redis2kbitem (const char *name, const redisReply *rep)
673 {
674  struct kb_item *kbi;
675 
676  kbi = NULL;
677 
678  switch (rep->type)
679  {
680  unsigned int i;
681 
682  case REDIS_REPLY_STRING:
683  case REDIS_REPLY_INTEGER:
684  kbi = redis2kbitem_single (name, rep, 0);
685  break;
686 
687  case REDIS_REPLY_ARRAY:
688  for (i = 0; i < rep->elements; i++)
689  {
690  struct kb_item *tmpitem;
691 
692  tmpitem = redis2kbitem_single (name, rep->element[i], 0);
693  if (tmpitem == NULL)
694  break;
695 
696  if (kbi != NULL)
697  {
698  tmpitem->next = kbi;
699  kbi = tmpitem;
700  }
701  else
702  kbi = tmpitem;
703  }
704  break;
705 
706  case REDIS_REPLY_NIL:
707  case REDIS_REPLY_STATUS:
708  case REDIS_REPLY_ERROR:
709  default:
710  break;
711  }
712 
713  return kbi;
714 }
715 
722 static redisReply *
723 redis_cmd (struct kb_redis *kbr, const char *fmt, ...)
724 {
725  redisReply *rep;
726  va_list ap, aq;
727  int retry = 0;
728 
729  va_start (ap, fmt);
730  do
731  {
732  redisContext *ctx;
733 
734  rep = NULL;
735 
736  ctx = get_redis_ctx (kbr);
737  if (ctx == NULL)
738  {
739  va_end (ap);
740  return NULL;
741  }
742 
743  va_copy (aq, ap);
744  rep = redisvCommand (ctx, fmt, aq);
745  va_end (aq);
746 
747  if (ctx->err)
748  {
749  if (rep != NULL)
750  freeReplyObject (rep);
751 
752  redis_lnk_reset ((kb_t) kbr);
753  retry = !retry;
754  }
755  else
756  retry = 0;
757  }
758  while (retry);
759 
760  va_end (ap);
761 
762  return rep;
763 }
764 
773 static struct kb_item *
775 {
776  struct kb_item *kbi;
777  struct kb_redis *kbr;
778  redisReply *rep;
779 
780  kbr = redis_kb (kb);
781  kbi = NULL;
782 
783  rep = redis_cmd (kbr, "LINDEX %s -1", name);
784  if (rep == NULL || rep->type != REDIS_REPLY_STRING)
785  {
786  kbi = NULL;
787  goto out;
788  }
789 
790  kbi = redis2kbitem_single (name, rep, type == KB_TYPE_INT);
791 
792 out:
793  if (rep != NULL)
794  freeReplyObject (rep);
795 
796  return kbi;
797 }
798 
806 static char *
807 redis_get_str (kb_t kb, const char *name)
808 {
809  struct kb_item *kbi;
810 
812  if (kbi != NULL)
813  {
814  char *res;
815 
816  res = kbi->v_str;
817  kbi->v_str = NULL;
818  kb_item_free (kbi);
819  return res;
820  }
821  return NULL;
822 }
823 
831 static int
832 redis_push_str (kb_t kb, const char *name, const char *value)
833 {
834  struct kb_redis *kbr;
835  redisReply *rep = NULL;
836  int rc = 0;
837 
838  kbr = redis_kb (kb);
839  rep = redis_cmd (kbr, "LPUSH %s %s", name, value);
840  if (!rep || rep->type == REDIS_REPLY_ERROR)
841  rc = -1;
842 
843  if (rep)
844  freeReplyObject (rep);
845 
846  return rc;
847 }
848 
855 static char *
856 redis_pop_str (kb_t kb, const char *name)
857 {
858  struct kb_redis *kbr;
859  redisReply *rep;
860  char *value = NULL;
861 
862  kbr = redis_kb (kb);
863  rep = redis_cmd (kbr, "RPOP %s", name);
864  if (!rep)
865  return NULL;
866 
867  if (rep->type == REDIS_REPLY_STRING)
868  value = g_strdup (rep->str);
869  freeReplyObject (rep);
870 
871  return value;
872 }
873 
881 static int
882 redis_get_int (kb_t kb, const char *name)
883 {
884  struct kb_item *kbi;
885 
887  if (kbi != NULL)
888  {
889  int res;
890 
891  res = kbi->v_int;
892  kb_item_free (kbi);
893  return res;
894  }
895  return -1;
896 }
897 
905 static char *
906 redis_get_nvt (kb_t kb, const char *oid, enum kb_nvt_pos position)
907 {
908  struct kb_redis *kbr;
909  redisReply *rep;
910  char *res = NULL;
911 
912  kbr = redis_kb (kb);
913  if (position >= NVT_TIMESTAMP_POS)
914  rep = redis_cmd (kbr, "LINDEX filename:%s %d", oid,
915  position - NVT_TIMESTAMP_POS);
916  else
917  rep = redis_cmd (kbr, "LINDEX nvt:%s %d", oid, position);
918  if (!rep)
919  return NULL;
920  if (rep->type == REDIS_REPLY_INTEGER)
921  res = g_strdup_printf ("%lld", rep->integer);
922  else if (rep->type == REDIS_REPLY_STRING)
923  res = g_strdup (rep->str);
924  freeReplyObject (rep);
925 
926  return res;
927 }
928 
935 static nvti_t *
936 redis_get_nvt_all (kb_t kb, const char *oid)
937 {
938  struct kb_redis *kbr;
939  redisReply *rep;
940 
941  kbr = redis_kb (kb);
942  rep =
943  redis_cmd (kbr, "LRANGE nvt:%s %d %d", oid, NVT_FILENAME_POS, NVT_NAME_POS);
944  if (!rep)
945  return NULL;
946  if (rep->type != REDIS_REPLY_ARRAY || rep->elements != NVT_NAME_POS + 1)
947  {
948  freeReplyObject (rep);
949  return NULL;
950  }
951  else
952  {
953  nvti_t *nvti = nvti_new ();
954 
955  nvti_set_oid (nvti, oid);
956  nvti_set_required_keys (nvti, rep->element[NVT_REQUIRED_KEYS_POS]->str);
958  nvti_set_excluded_keys (nvti, rep->element[NVT_EXCLUDED_KEYS_POS]->str);
960  nvti, rep->element[NVT_REQUIRED_UDP_PORTS_POS]->str);
962  nvti_set_dependencies (nvti, rep->element[NVT_DEPENDENCIES_POS]->str);
963  nvti_set_tag (nvti, rep->element[NVT_TAGS_POS]->str);
964  nvti_set_cve (nvti, rep->element[NVT_CVES_POS]->str);
965  nvti_set_bid (nvti, rep->element[NVT_BIDS_POS]->str);
966  nvti_set_xref (nvti, rep->element[NVT_XREFS_POS]->str);
967  nvti_set_category (nvti, atoi (rep->element[NVT_CATEGORY_POS]->str));
968  nvti_set_timeout (nvti, atoi (rep->element[NVT_TIMEOUT_POS]->str));
969  nvti_set_family (nvti, rep->element[NVT_FAMILY_POS]->str);
970  nvti_set_name (nvti, rep->element[NVT_NAME_POS]->str);
971 
972  freeReplyObject (rep);
973  return nvti;
974  }
975 }
976 
984 static struct kb_item *
985 redis_get_all (kb_t kb, const char *name)
986 {
987  struct kb_redis *kbr;
988  struct kb_item *kbi;
989  redisReply *rep;
990 
991  kbr = redis_kb (kb);
992 
993  rep = redis_cmd (kbr, "LRANGE %s 0 -1", name);
994  if (rep == NULL)
995  return NULL;
996 
997  kbi = redis2kbitem (name, rep);
998 
999  freeReplyObject (rep);
1000 
1001  return kbi;
1002 }
1003 
1011 static struct kb_item *
1012 redis_get_pattern (kb_t kb, const char *pattern)
1013 {
1014  struct kb_redis *kbr;
1015  struct kb_item *kbi = NULL;
1016  redisReply *rep;
1017  unsigned int i;
1018  redisContext *ctx;
1019 
1020  kbr = redis_kb (kb);
1021  rep = redis_cmd (kbr, "KEYS %s", pattern);
1022  if (!rep)
1023  return NULL;
1024  if (rep->type != REDIS_REPLY_ARRAY)
1025  {
1026  freeReplyObject (rep);
1027  return NULL;
1028  }
1029 
1030  ctx = get_redis_ctx (kbr);
1031  for (i = 0; i < rep->elements; i++)
1032  redisAppendCommand (ctx, "LRANGE %s 0 -1", rep->element[i]->str);
1033 
1034  for (i = 0; i < rep->elements; i++)
1035  {
1036  struct kb_item *tmp;
1037  redisReply *rep_range;
1038 
1039  redisGetReply (ctx, (void **) &rep_range);
1040  if (!rep)
1041  continue;
1042  tmp = redis2kbitem (rep->element[i]->str, rep_range);
1043  if (!tmp)
1044  {
1045  freeReplyObject (rep_range);
1046  continue;
1047  }
1048 
1049  if (kbi)
1050  {
1051  struct kb_item *tmp2;
1052 
1053  tmp2 = tmp;
1054  while (tmp->next)
1055  tmp = tmp->next;
1056  tmp->next = kbi;
1057  kbi = tmp2;
1058  }
1059  else
1060  kbi = tmp;
1061  freeReplyObject (rep_range);
1062  }
1063 
1064  freeReplyObject (rep);
1065  return kbi;
1066 }
1067 
1073 static GSList *
1075 {
1076  struct kb_redis *kbr;
1077  redisReply *rep;
1078  GSList *list = NULL;
1079  size_t i;
1080 
1081  kbr = redis_kb (kb);
1082  rep = redis_cmd (kbr, "KEYS nvt:*");
1083  if (!rep)
1084  return NULL;
1085 
1086  if (rep->type != REDIS_REPLY_ARRAY)
1087  {
1088  freeReplyObject (rep);
1089  return NULL;
1090  }
1091 
1092  /* Fetch OID values from key names nvt:OID. */
1093  for (i = 0; i < rep->elements; i++)
1094  list = g_slist_prepend (list, g_strdup (rep->element[i]->str + 4));
1095  freeReplyObject (rep);
1096 
1097  return list;
1098 }
1099 
1108 static size_t
1109 redis_count (kb_t kb, const char *pattern)
1110 {
1111  struct kb_redis *kbr;
1112  redisReply *rep;
1113  size_t count;
1114 
1115  kbr = redis_kb (kb);
1116 
1117  rep = redis_cmd (kbr, "KEYS %s", pattern);
1118  if (rep == NULL)
1119  return 0;
1120 
1121  if (rep->type != REDIS_REPLY_ARRAY)
1122  {
1123  freeReplyObject (rep);
1124  return 0;
1125  }
1126 
1127  count = rep->elements;
1128  freeReplyObject (rep);
1129  return count;
1130 }
1131 
1138 static int
1139 redis_del_items (kb_t kb, const char *name)
1140 {
1141  struct kb_redis *kbr;
1142  redisReply *rep;
1143  int rc = 0;
1144 
1145  kbr = redis_kb (kb);
1146 
1147  rep = redis_cmd (kbr, "DEL %s", name);
1148  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1149  rc = -1;
1150 
1151  if (rep != NULL)
1152  freeReplyObject (rep);
1153 
1154  return rc;
1155 }
1156 
1165 static int
1166 redis_add_str_unique (kb_t kb, const char *name, const char *str, size_t len)
1167 {
1168  struct kb_redis *kbr;
1169  redisReply *rep = NULL;
1170  int rc = 0;
1171  redisContext *ctx;
1172 
1173  kbr = redis_kb (kb);
1174  ctx = get_redis_ctx (kbr);
1175 
1176  /* Some VTs still rely on values being unique (ie. a value inserted multiple
1177  * times, will only be present once.)
1178  * Once these are fixed, the LREM becomes redundant and should be removed.
1179  */
1180  if (len == 0)
1181  {
1182  redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
1183  redisAppendCommand (ctx, "RPUSH %s %s", name, str);
1184  redisGetReply (ctx, (void **) &rep);
1185  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1186  g_debug ("Key '%s' already contained value '%s'", name, str);
1187  freeReplyObject (rep);
1188  redisGetReply (ctx, (void **) &rep);
1189  }
1190  else
1191  {
1192  redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
1193  redisAppendCommand (ctx, "RPUSH %s %b", name, str, len);
1194  redisGetReply (ctx, (void **) &rep);
1195  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1196  g_debug ("Key '%s' already contained string '%s'", name, str);
1197  freeReplyObject (rep);
1198  redisGetReply (ctx, (void **) &rep);
1199  }
1200  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1201  rc = -1;
1202 
1203  if (rep != NULL)
1204  freeReplyObject (rep);
1205 
1206  return rc;
1207 }
1208 
1217 static int
1218 redis_add_str (kb_t kb, const char *name, const char *str, size_t len)
1219 {
1220  struct kb_redis *kbr;
1221  redisReply *rep;
1222  int rc = 0;
1223 
1224  kbr = redis_kb (kb);
1225  if (len == 0)
1226  rep = redis_cmd (kbr, "RPUSH %s %s", name, str);
1227  else
1228  rep = redis_cmd (kbr, "RPUSH %s %b", name, str, len);
1229  if (!rep || rep->type == REDIS_REPLY_ERROR)
1230  rc = -1;
1231 
1232  if (rep)
1233  freeReplyObject (rep);
1234  return rc;
1235 }
1236 
1245 static int
1246 redis_set_str (kb_t kb, const char *name, const char *val, size_t len)
1247 {
1248  struct kb_redis *kbr;
1249  redisReply *rep = NULL;
1250  redisContext *ctx;
1251  int rc = 0, i = 4;
1252 
1253  kbr = redis_kb (kb);
1254  ctx = get_redis_ctx (kbr);
1255  redisAppendCommand (ctx, "MULTI");
1256  redisAppendCommand (ctx, "DEL %s", name);
1257  if (len == 0)
1258  redisAppendCommand (ctx, "RPUSH %s %s", name, val);
1259  else
1260  redisAppendCommand (ctx, "RPUSH %s %b", name, val, len);
1261  redisAppendCommand (ctx, "EXEC");
1262  while (i--)
1263  {
1264  redisGetReply (ctx, (void **) &rep);
1265  if (!rep || rep->type == REDIS_REPLY_ERROR)
1266  rc = -1;
1267  if (rep)
1268  freeReplyObject (rep);
1269  }
1270 
1271  return rc;
1272 }
1273 
1281 static int
1282 redis_add_int_unique (kb_t kb, const char *name, int val)
1283 {
1284  struct kb_redis *kbr;
1285  redisReply *rep;
1286  int rc = 0;
1287  redisContext *ctx;
1288 
1289  kbr = redis_kb (kb);
1290  ctx = get_redis_ctx (kbr);
1291  redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
1292  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1293  redisGetReply (ctx, (void **) &rep);
1294  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1295  g_debug ("Key '%s' already contained integer '%d'", name, val);
1296  freeReplyObject (rep);
1297  redisGetReply (ctx, (void **) &rep);
1298  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1299  {
1300  rc = -1;
1301  goto out;
1302  }
1303 
1304 out:
1305  if (rep != NULL)
1306  freeReplyObject (rep);
1307 
1308  return rc;
1309 }
1310 
1318 static int
1319 redis_add_int (kb_t kb, const char *name, int val)
1320 {
1321  redisReply *rep;
1322  int rc = 0;
1323 
1324  rep = redis_cmd (redis_kb (kb), "RPUSH %s %d", name, val);
1325  if (!rep || rep->type == REDIS_REPLY_ERROR)
1326  rc = -1;
1327  if (rep)
1328  freeReplyObject (rep);
1329 
1330  return rc;
1331 }
1332 
1340 static int
1341 redis_set_int (kb_t kb, const char *name, int val)
1342 {
1343  redisReply *rep = NULL;
1344  redisContext *ctx;
1345  int rc = 0, i = 4;
1346 
1347  ctx = get_redis_ctx (redis_kb (kb));
1348  redisAppendCommand (ctx, "MULTI");
1349  redisAppendCommand (ctx, "DEL %s", name);
1350  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1351  redisAppendCommand (ctx, "EXEC");
1352  while (i--)
1353  {
1354  redisGetReply (ctx, (void **) &rep);
1355  if (!rep || rep->type == REDIS_REPLY_ERROR)
1356  rc = -1;
1357  if (rep)
1358  freeReplyObject (rep);
1359  }
1360 
1361  return rc;
1362 }
1363 
1371 static int
1372 redis_add_nvt (kb_t kb, const nvti_t *nvt, const char *filename)
1373 {
1374  struct kb_redis *kbr;
1375  redisReply *rep = NULL;
1376  int rc = 0;
1377  GSList *element;
1378 
1379  if (!nvt || !filename)
1380  return -1;
1381 
1382  kbr = redis_kb (kb);
1383  rep = redis_cmd (
1384  kbr, "RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %d %s %s",
1385  nvti_oid (nvt), filename, nvti_required_keys (nvt) ?: "",
1386  nvti_mandatory_keys (nvt) ?: "", nvti_excluded_keys (nvt) ?: "",
1387  nvti_required_udp_ports (nvt) ?: "", nvti_required_ports (nvt) ?: "",
1388  nvti_dependencies (nvt) ?: "", nvti_tag (nvt) ?: "", nvti_cve (nvt) ?: "",
1389  nvti_bid (nvt) ?: "", nvti_xref (nvt) ?: "", nvti_category (nvt),
1390  nvti_timeout (nvt), nvti_family (nvt), nvti_name (nvt));
1391  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1392  rc = -1;
1393  if (rep != NULL)
1394  freeReplyObject (rep);
1395 
1396  element = nvt->prefs;
1397  if (g_slist_length (element))
1398  rep = redis_cmd (kbr, "DEL oid:%s:prefs", nvti_oid (nvt));
1399  while (element)
1400  {
1401  nvtpref_t *pref = element->data;
1402 
1403  rep = redis_cmd (kbr, "RPUSH oid:%s:prefs %s|||%s|||%s", nvti_oid (nvt),
1404  pref->name, pref->type, pref->dflt);
1405  if (!rep || rep->type == REDIS_REPLY_ERROR)
1406  rc = -1;
1407  if (rep)
1408  freeReplyObject (rep);
1409  element = element->next;
1410  }
1411  rep = redis_cmd (kbr, "RPUSH filename:%s %lu %s", filename, time (NULL),
1412  nvti_oid (nvt));
1413  if (!rep || rep->type == REDIS_REPLY_ERROR)
1414  rc = -1;
1415  if (rep)
1416  freeReplyObject (rep);
1417  return rc;
1418 }
1419 
1426 static int
1428 {
1429  struct kb_redis *kbr;
1430 
1431  kbr = redis_kb (kb);
1432 
1433  if (kbr->rctx != NULL)
1434  {
1435  redisFree (kbr->rctx);
1436  kbr->rctx = NULL;
1437  }
1438 
1439  return 0;
1440 }
1441 
1448 static int
1449 redis_flush_all (kb_t kb, const char *except)
1450 {
1451  unsigned int i = 1;
1452  struct kb_redis *kbr;
1453 
1454  kbr = redis_kb (kb);
1455  if (kbr->rctx)
1456  redisFree (kbr->rctx);
1457 
1458  g_debug ("%s: deleting all DBs at %s except %s", __func__, kbr->path, except);
1459  do
1460  {
1461  redisReply *rep;
1462 
1463  kbr->rctx = redisConnectUnix (kbr->path);
1464  if (kbr->rctx == NULL || kbr->rctx->err)
1465  {
1466  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1467  "%s: redis connection error: %s", __func__,
1468  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
1469  redisFree (kbr->rctx);
1470  kbr->rctx = NULL;
1471  return -1;
1472  }
1473 
1474  kbr->db = i;
1475  rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
1476  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
1477  {
1478  freeReplyObject (rep);
1479  redisFree (kbr->rctx);
1480  i++;
1481  continue;
1482  }
1483  freeReplyObject (rep);
1484  rep = redisCommand (kbr->rctx, "SELECT %u", i);
1485  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1486  {
1487  freeReplyObject (rep);
1488  sleep (KB_RETRY_DELAY);
1489  redisFree (kbr->rctx);
1490  kbr->rctx = NULL;
1491  }
1492  else
1493  {
1494  freeReplyObject (rep);
1495  /* Don't remove DB if it has "except" key. */
1496  if (except)
1497  {
1498  char *tmp = kb_item_get_str (kb, except);
1499  if (tmp)
1500  {
1501  g_free (tmp);
1502  i++;
1503  redisFree (kbr->rctx);
1504  continue;
1505  }
1506  }
1507  redis_delete_all (kbr);
1508  redis_release_db (kbr);
1509  redisFree (kbr->rctx);
1510  }
1511  i++;
1512  }
1513  while (i < kbr->max_db);
1514 
1515  g_free (kb);
1516  return 0;
1517 }
1518 
1524 int
1526 {
1527  int rc;
1528  redisReply *rep;
1529  struct kb_redis *kbr;
1530 
1531  kbr = redis_kb (kb);
1532  g_debug ("%s: saving all elements from KB #%u", __func__, kbr->db);
1533  rep = redis_cmd (kbr, "SAVE");
1534  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1535  {
1536  rc = -1;
1537  goto err_cleanup;
1538  }
1539 
1540  rc = 0;
1541 
1542 err_cleanup:
1543  if (rep != NULL)
1544  freeReplyObject (rep);
1545 
1546  return rc;
1547 }
1548 
1554 int
1556 {
1557  int rc;
1558  redisReply *rep;
1559  struct sigaction new_action, original_action;
1560 
1561  /* Ignore SIGPIPE, in case of a lost connection. */
1562  new_action.sa_flags = 0;
1563  if (sigemptyset (&new_action.sa_mask))
1564  return -1;
1565  new_action.sa_handler = SIG_IGN;
1566  if (sigaction (SIGPIPE, &new_action, &original_action))
1567  return -1;
1568 
1569  g_debug ("%s: deleting all elements from KB #%u", __func__, kbr->db);
1570  rep = redis_cmd (kbr, "FLUSHDB");
1571  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1572  {
1573  rc = -1;
1574  goto err_cleanup;
1575  }
1576 
1577  rc = 0;
1578 
1579 err_cleanup:
1580  if (sigaction (SIGPIPE, &original_action, NULL))
1581  return -1;
1582  if (rep != NULL)
1583  freeReplyObject (rep);
1584 
1585  return rc;
1586 }
1587 
1593 static const struct kb_operations KBRedisOperations = {
1594  .kb_new = redis_new,
1595  .kb_find = redis_find,
1596  .kb_delete = redis_delete,
1597  .kb_get_single = redis_get_single,
1598  .kb_get_str = redis_get_str,
1599  .kb_get_int = redis_get_int,
1600  .kb_get_nvt = redis_get_nvt,
1601  .kb_get_nvt_all = redis_get_nvt_all,
1602  .kb_get_nvt_oids = redis_get_oids,
1603  .kb_push_str = redis_push_str,
1604  .kb_pop_str = redis_pop_str,
1605  .kb_get_all = redis_get_all,
1606  .kb_get_pattern = redis_get_pattern,
1607  .kb_count = redis_count,
1608  .kb_add_str = redis_add_str,
1609  .kb_add_str_unique = redis_add_str_unique,
1610  .kb_set_str = redis_set_str,
1611  .kb_add_int = redis_add_int,
1612  .kb_add_int_unique = redis_add_int_unique,
1613  .kb_set_int = redis_set_int,
1614  .kb_add_nvt = redis_add_nvt,
1615  .kb_del_items = redis_del_items,
1616  .kb_lnk_reset = redis_lnk_reset,
1617  .kb_save = redis_save,
1618  .kb_flush = redis_flush_all,
1619  .kb_direct_conn = redis_direct_conn,
1620  .kb_get_kb_index = redis_get_kb_index,
1621 };
1622 
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:832
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
Definition: nvti.c:817
#define redis_kb(__kb)
Definition: kb.c:74
#define KB_RETRY_DELAY
Number of seconds to wait for between two attempts to acquire a KB namespace.
Definition: kb.c:57
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:1218
kb_nvt_pos
Possible positions of nvt values in cache list.
Definition: kb.h:54
gchar * nvti_xref(const nvti_t *n)
Get the xref's.
Definition: nvti.c:275
static int fetch_max_db_index_compat(struct kb_redis *kbr)
Set the number of databases have been configured into kbr struct. (For Redis 2.4.* compatibility).
Definition: kb.c:129
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
Definition: kb.c:936
Definition: kb.h:46
gchar * nvti_required_ports(const nvti_t *n)
Get the required ports list.
Definition: nvti.c:373
static int redis_test_connection(struct kb_redis *kbr)
Test redis connection.
Definition: kb.c:388
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:774
void kb_item_free(struct kb_item *item)
Release a KB item (or a list).
Definition: kb.c:608
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
Definition: kb.c:1555
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition: nvti.c:156
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
Definition: nvti.c:777
#define G_LOG_DOMAIN
Definition: kb.c:39
int nvti_set_required_ports(nvti_t *n, const gchar *required_ports)
Set the required ports of a NVT.
Definition: nvti.c:728
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Definition: kb.c:856
unsigned int max_db
Definition: kb.c:69
gchar * nvti_cve(const nvti_t *n)
Get the CVE references.
Definition: nvti.c:247
gchar * name
Name of the preference.
Definition: nvti.h:41
The structure of a information record that corresponds to a NVT.
Definition: nvti.h:62
static redisContext * get_redis_ctx(struct kb_redis *kbr)
Get redis context if it is already connected or do a a connection.
Definition: kb.c:346
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
Definition: kb.h:79
struct kb_item * next
Definition: kb.h:90
enum kb_item_type type
Definition: kb.h:81
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
Definition: kb.c:985
unsigned int db
Definition: kb.c:70
KB interface. Functions provided by an implementation. All functions have to be provided,...
Definition: kb.h:117
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
Definition: nvti.c:456
int nvti_set_timeout(nvti_t *n, const gint timeout)
Set the timeout of a NVT Info.
Definition: nvti.c:798
int nvti_set_tag(nvti_t *n, const gchar *tag)
Set the tags of a NVT.
Definition: nvti.c:579
redisContext * rctx
Definition: kb.c:71
gint nvti_timeout(const nvti_t *n)
Get the timeout for this NVT.
Definition: nvti.c:443
int nvti_set_cve(nvti_t *n, const gchar *cve)
Set the CVE references of a NVT.
Definition: nvti.c:513
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Definition: kb.c:1372
static int redis_release_db(struct kb_redis *kbr)
Release DB.
Definition: kb.c:305
gchar * nvti_tag(const nvti_t *n)
Get the tag.
Definition: nvti.c:289
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
Definition: kb.c:1074
gchar * nvti_family(const nvti_t *n)
Get the family name.
Definition: nvti.c:401
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
Definition: kb.c:1449
static struct kb_item * redis2kbitem_single(const char *name, const redisReply *elt, int force_int)
Give a single KB item.
Definition: kb.c:630
gchar * type
Preference type.
Definition: nvti.h:40
gchar * nvti_dependencies(const nvti_t *n)
Get the dependencies list.
Definition: nvti.c:317
Definition: kb.h:45
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:1341
char path[0]
Definition: kb.c:72
gchar * nvti_excluded_keys(const nvti_t *n)
Get the excluded keys list.
Definition: nvti.c:359
static int select_database(struct kb_redis *kbr)
Select DB.
Definition: kb.c:254
gchar * nvti_mandatory_keys(const nvti_t *n)
Get the mandatory keys list.
Definition: nvti.c:345
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:101
#define GLOBAL_DBINDEX_NAME
Name of the namespace usage bitmap in redis.
Definition: kb.c:51
const struct kb_operations * kb_ops
Definition: kb.h:103
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:1427
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
Definition: nvti.c:471
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:498
int nvti_set_mandatory_keys(nvti_t *n, const gchar *mandatory_keys)
Set the mandatory keys of a NVT.
Definition: nvti.c:678
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
Definition: nvti.c:492
int nvti_set_xref(nvti_t *n, const gchar *xref)
Set the xrefs of a NVT.
Definition: nvti.c:555
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:1166
Knowledge base management API - Redis backend.
size_t len
Definition: kb.h:89
static struct kb_item * redis2kbitem(const char *name, const redisReply *rep)
Fetch a KB item or list from a redis Reply.
Definition: kb.c:672
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
Definition: kb.c:1109
int nvti_set_bid(nvti_t *n, const gchar *bid)
Set the bid references of a NVT.
Definition: nvti.c:534
gchar * nvti_required_udp_ports(const nvti_t *n)
Get the required udp ports list.
Definition: nvti.c:387
struct kb kb
Definition: kb.c:68
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:753
gchar * dflt
Default value of the preference.
Definition: nvti.h:42
static int try_database_index(struct kb_redis *kbr, int index)
Attempt to atomically acquire ownership of a database.
Definition: kb.c:89
int v_int
Definition: kb.h:86
static redisReply * redis_cmd(struct kb_redis *kbr, const char *fmt,...)
Execute a redis command and get a redis reply.
Definition: kb.c:723
kb_item_type
Possible type of a kb_item.
Definition: kb.h:42
static char * kb_item_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.h:323
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:1319
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.c:807
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:1246
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:1282
size_t namelen
Definition: kb.h:92
int redis_save(kb_t kb)
Save all the elements from the KB.
Definition: kb.c:1525
Subclass of struct kb, it contains the redis-specific fields, such as the redis context,...
Definition: kb.c:66
static int redis_delete(kb_t kb)
Delete all entries and release ownership on the namespace.
Definition: kb.c:427
static const struct kb_operations KBRedisOperations
Default KB operations. No selection mechanism is provided yet since there's only one implementation (...
Definition: kb.c:59
int nvti_set_excluded_keys(nvti_t *n, const gchar *excluded_keys)
Set the excluded keys of a NVT.
Definition: nvti.c:703
The structure for a preference of a NVT.
Definition: nvti.h:38
struct kb * kb_t
type abstraction to hide KB internals.
Definition: kb.h:109
int nvti_set_dependencies(nvti_t *n, const gchar *dependencies)
Set the dependencies of a NVT.
Definition: nvti.c:628
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
Definition: kb.c:906
gchar * nvti_required_keys(const nvti_t *n)
Get the required keys list.
Definition: nvti.c:331
#define MAX_DB_INDEX__24
Max number of configured DB.
Definition: kb.c:120
char name[0]
Definition: kb.h:93
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
Definition: kb.c:538
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
Definition: kb.c:468
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
Definition: kb.c:882
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition: nvti.c:219
static int redis_get_kb_index(kb_t kb)
Return the kb index.
Definition: kb.c:452
gchar * nvti_bid(const nvti_t *n)
Get the bid references.
Definition: nvti.c:261
const struct kb_operations * KBDefaultOperations
Default KB operations. No selection mechanism is provided yet since there's only one implementation (...
Definition: kb.c:1623
static int fetch_max_db_index(struct kb_redis *kbr)
Set the number of databases have been configured into kbr struct.
Definition: kb.c:196
char * v_str
Definition: kb.h:85
int nvti_set_required_keys(nvti_t *n, const gchar *required_keys)
Set the required keys of a NVT.
Definition: nvti.c:653
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
Definition: kb.c:1012
int(* kb_new)(kb_t *, const char *)
Definition: kb.h:120
static int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
Definition: kb.c:1139
gchar * nvti_name(const nvti_t *n)
Get the name.
Definition: nvti.c:233
GSList * prefs
Collection of NVT preferences.
Definition: nvti.h:83