Greenbone Vulnerability Management Libraries 22.8.0
kb.c File Reference

Knowledge base management API - Redis backend. More...

#include "kb.h"
#include <errno.h>
#include <glib.h>
#include <hiredis/hiredis.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for kb.c:

Go to the source code of this file.

Data Structures

struct  kb_redis
 Subclass of struct kb, it contains the redis-specific fields, such as the redis context, current DB (namespace) id and the server socket path. More...
 

Macros

#define _GNU_SOURCE
 
#define G_LOG_DOMAIN   "libgvm util"
 GLib logging domain.
 
#define memdup   g_memdup
 
#define GLOBAL_DBINDEX_NAME   "GVM.__GlobalDBIndex"
 Name of the namespace usage bitmap in redis.
 
#define redis_kb(__kb)   ((struct kb_redis *) (__kb))
 

Functions

static int redis_delete_all (struct kb_redis *kbr)
 Delete all the KB's content.
 
static int redis_lnk_reset (kb_t kb)
 Reset connection to the KB. This is called after each fork() to make sure connections aren't shared between concurrent processes.
 
static int redis_flush_all (kb_t kb, const char *except)
 Flush all the KB's content. Delete all namespaces.
 
static redisReply * redis_cmd (struct kb_redis *kbr, const char *fmt,...)
 Execute a redis command and get a redis reply.
 
static int try_database_index (struct kb_redis *kbr, int index)
 Attempt to atomically acquire ownership of a database.
 
static int fetch_max_db_index (struct kb_redis *kbr)
 Set the number of databases have been configured into kbr struct.
 
static int select_database (struct kb_redis *kbr)
 Select DB.
 
static int redis_release_db (struct kb_redis *kbr)
 Release DB.
 
static char * parse_port_of_addr (const char *addr, int tcp_indicator_len)
 
static redisContext * connect_redis (const char *addr, int len)
 
static int get_redis_ctx (struct kb_redis *kbr)
 Get redis context if it is already connected or do a a connection.
 
static int redis_test_connection (struct kb_redis *kbr)
 Test redis connection.
 
static int redis_delete (kb_t kb)
 Delete all entries and release ownership on the namespace.
 
static int redis_get_kb_index (kb_t kb)
 Return the kb index.
 
static int redis_memory_purge (kb_t kb)
 Attempt to purge dirty pages.
 
static int redis_new (kb_t *kb, const char *kb_path)
 Initialize a new Knowledge Base object.
 
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.
 
static kb_t redis_find (const char *kb_path, const char *key)
 Find an existing Knowledge Base object with key.
 
void kb_item_free (struct kb_item *item)
 Release a KB item (or a list).
 
static struct kb_itemredis2kbitem_single (const char *name, const redisReply *elt, int force_int)
 Give a single KB item.
 
static struct kb_itemredis2kbitem (const char *name, const redisReply *rep)
 Fetch a KB item or list from a redis Reply.
 
static struct kb_itemredis_get_single (kb_t kb, const char *name, enum kb_item_type type)
 Get a single KB element.
 
static char * redis_get_str (kb_t kb, const char *name)
 Get a single KB string item.
 
static int redis_push_str (kb_t kb, const char *name, const char *value)
 Push a new entry under a given key.
 
static char * redis_pop_str (kb_t kb, const char *name)
 Pops a single KB string item.
 
static int redis_get_int (kb_t kb, const char *name)
 Get a single KB integer item.
 
static char * redis_get_nvt (kb_t kb, const char *oid, enum kb_nvt_pos position)
 Get field of a NVT.
 
static nvti_tredis_get_nvt_all (kb_t kb, const char *oid)
 Get a full NVT.
 
static struct kb_itemredis_get_all (kb_t kb, const char *name)
 Get all items stored under a given name.
 
static struct kb_itemredis_get_pattern (kb_t kb, const char *pattern)
 Get all items stored under a given pattern.
 
static GSList * redis_get_oids (kb_t kb)
 Get all NVT OIDs.
 
static size_t redis_count (kb_t kb, const char *pattern)
 Count all items stored under a given pattern.
 
static int redis_del_items (kb_t kb, const char *name)
 Delete all entries under a given name.
 
static int redis_add_str_unique_volatile (kb_t kb, const char *name, const char *str, int expire, size_t len, int pos)
 Insert (append) a new unique and volatile entry under a given name.
 
static int redis_add_str_unique (kb_t kb, const char *name, const char *str, size_t len, int pos)
 Insert (append) a new unique entry under a given name.
 
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.
 
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.
 
static int redis_add_int_unique_volatile (kb_t kb, const char *name, int val, int expire)
 Insert (append) a new unique entry under a given name.
 
static int redis_add_int_unique (kb_t kb, const char *name, int val)
 Insert (append) a new unique entry under a given name.
 
static int redis_add_int (kb_t kb, const char *name, int val)
 Insert (append) a new entry under a given name.
 
static int redis_set_int (kb_t kb, const char *name, int val)
 Set (replace) a new entry under a given name.
 
static int redis_add_nvt (kb_t kb, const nvti_t *nvt, const char *filename)
 Insert a new nvt.
 
static int redis_save (kb_t kb)
 Save all the elements from the KB.
 

Variables

static const struct kb_operations KBRedisOperations
 Default KB operations.
 
const struct kb_operationsKBDefaultOperations = &KBRedisOperations
 Default KB operations. No selection mechanism is provided yet since there's only one implementation (redis-based).
 

Detailed Description

Knowledge base management API - Redis backend.

Contains specialized structures and functions to use redis as a KB server.

Definition in file kb.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 11 of file kb.c.

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "libgvm util"

GLib logging domain.

Definition at line 27 of file kb.c.

◆ GLOBAL_DBINDEX_NAME

#define GLOBAL_DBINDEX_NAME   "GVM.__GlobalDBIndex"

Name of the namespace usage bitmap in redis.

Definition at line 45 of file kb.c.

◆ memdup

#define memdup   g_memdup

Definition at line 32 of file kb.c.

◆ redis_kb

#define redis_kb (   __kb)    ((struct kb_redis *) (__kb))

Definition at line 62 of file kb.c.

Function Documentation

◆ connect_redis()

static redisContext * connect_redis ( const char *  addr,
int  len 
)
static

Definition at line 263 of file kb.c.

264{
265 const char *tcp_indicator = "tcp://";
266 const int tcp_indicator_len = strlen (tcp_indicator);
267 const int redis_default_port = 6379;
268
269 int port, host_len;
270 char *tmp, *host;
271 redisContext *result;
272 static int warn_flag = 0;
273
274 if (len < tcp_indicator_len + 1)
275 goto unix_connect;
276 if (memcmp (addr, tcp_indicator, tcp_indicator_len) != 0)
277 goto unix_connect;
278 host_len = len - tcp_indicator_len;
279 if ((tmp = parse_port_of_addr (addr, tcp_indicator_len)) == NULL)
280 port = redis_default_port;
281 else
282 {
283 port = atoi (tmp);
284 host_len -= strlen (tmp) + 1;
285 }
286 host = calloc (1, host_len);
287 memmove (host, addr + tcp_indicator_len, host_len);
288 result = redisConnect (host, port);
289 if (warn_flag == 0)
290 {
291 g_warning ("A Redis TCP connection is being used. This feature is "
292 "experimental and insecure, since it is not an encrypted "
293 "channel. We discourage its usage in production environments");
294 warn_flag = 1;
295 }
296 free (host);
297 return result;
298unix_connect:
299 return redisConnectUnix (addr);
300}
static char * parse_port_of_addr(const char *addr, int tcp_indicator_len)
Definition: kb.c:250

References parse_port_of_addr().

Referenced by get_redis_ctx(), redis_direct_conn(), redis_find(), and redis_flush_all().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fetch_max_db_index()

static int fetch_max_db_index ( struct kb_redis kbr)
static

Set the number of databases have been configured into kbr struct.

Parameters
[in]kbrSubclass of struct kb where to save the max db index founded.
Returns
0 on success, -1 on error.

Definition at line 109 of file kb.c.

110{
111 int rc = 0;
112 redisContext *ctx = kbr->rctx;
113 redisReply *rep = NULL;
114
115 rep = redisCommand (ctx, "CONFIG GET databases");
116 if (rep == NULL)
117 {
118 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
119 "%s: redis command failed with '%s'", __func__, ctx->errstr);
120 rc = -1;
121 goto err_cleanup;
122 }
123
124 if (rep->type != REDIS_REPLY_ARRAY)
125 {
126 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
127 "%s: cannot retrieve max DB number: %s", __func__, rep->str);
128 rc = -1;
129 goto err_cleanup;
130 }
131
132 if (rep->elements == 2)
133 {
134 kbr->max_db = (unsigned) atoi (rep->element[1]->str);
135 }
136 else
137 {
138 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
139 "%s: unexpected reply length (%zd)", __func__, rep->elements);
140 rc = -1;
141 goto err_cleanup;
142 }
143
144 g_debug ("%s: maximum DB number: %u", __func__, kbr->max_db);
145
146err_cleanup:
147 if (rep != NULL)
148 freeReplyObject (rep);
149
150 return rc;
151}
#define G_LOG_DOMAIN
GLib logging domain.
Definition: kb.c:27
unsigned int max_db
Definition: kb.c:57
redisContext * rctx
Definition: kb.c:59

References G_LOG_DOMAIN, kb_redis::max_db, and kb_redis::rctx.

Referenced by redis_find(), and select_database().

Here is the caller graph for this function:

◆ get_redis_ctx()

static int get_redis_ctx ( struct kb_redis kbr)
static

Get redis context if it is already connected or do a a connection.

Parameters
[in]kbrSubclass of struct kb where to fetch the context. or where it is saved in case of a new connection.
Returns
0 on success, -1 on connection error, -2 on unavailable DB slot.

Definition at line 312 of file kb.c.

313{
314 int rc;
315
316 if (kbr->rctx != NULL)
317 return 0;
318
319 kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
320 if (kbr->rctx == NULL || kbr->rctx->err)
321 {
322 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
323 "%s: redis connection error to %s: %s", __func__, kbr->path,
324 kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
325 redisFree (kbr->rctx);
326 kbr->rctx = NULL;
327 return -1;
328 }
329
330 rc = select_database (kbr);
331 if (rc)
332 {
333 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "No redis DB available");
334 redisFree (kbr->rctx);
335 kbr->rctx = NULL;
336 return -2;
337 }
338
339 g_debug ("%s: connected to redis://%s/%d", __func__, kbr->path, kbr->db);
340 return 0;
341}
static int select_database(struct kb_redis *kbr)
Select DB.
Definition: kb.c:164
static redisContext * connect_redis(const char *addr, int len)
Definition: kb.c:263
char * path
Definition: kb.c:60
unsigned int db
Definition: kb.c:58

References connect_redis(), kb_redis::db, G_LOG_DOMAIN, kb_redis::path, kb_redis::rctx, and select_database().

Referenced by redis_add_int_unique(), redis_add_int_unique_volatile(), redis_add_str_unique(), redis_add_str_unique_volatile(), redis_cmd(), redis_get_pattern(), redis_new(), redis_set_int(), and redis_set_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ kb_item_free()

void kb_item_free ( struct kb_item item)

Release a KB item (or a list).

Parameters
[in]itemItem or list to be release

Definition at line 639 of file kb.c.

640{
641 while (item != NULL)
642 {
643 struct kb_item *next;
644
645 next = item->next;
646 if (item->type == KB_TYPE_STR && item->v_str != NULL)
647 g_free (item->v_str);
648 g_free (item);
649 item = next;
650 }
651}
@ KB_TYPE_STR
Definition: kb.h:36
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
Definition: kb.h:69
enum kb_item_type type
Definition: kb.h:70
char * v_str
Definition: kb.h:74
struct kb_item * next
Definition: kb.h:79

References KB_TYPE_STR, kb_item::next, kb_item::type, and kb_item::v_str.

Referenced by nvticache_get_prefs(), redis_get_int(), and redis_get_str().

Here is the caller graph for this function:

◆ parse_port_of_addr()

static char * parse_port_of_addr ( const char *  addr,
int  tcp_indicator_len 
)
inlinestatic

Definition at line 250 of file kb.c.

251{
252 char *tmp;
253 int is_ip_v6;
254 if ((tmp = rindex (addr + tcp_indicator_len, ':')) == NULL)
255 return NULL;
256 is_ip_v6 = addr[tcp_indicator_len] == '[';
257 if (is_ip_v6 && (tmp - 1)[0] != ']')
258 return NULL;
259 return tmp + 1;
260}

Referenced by connect_redis().

Here is the caller graph for this function:

◆ redis2kbitem()

static struct kb_item * redis2kbitem ( const char *  name,
const redisReply *  rep 
)
static

Fetch a KB item or list from a redis Reply.

Parameters
[in]nameName of the item.
[in]repA redisReply element where to fetch the item.
Returns
kb_item or list on success, NULL otherwise.

Definition at line 708 of file kb.c.

709{
710 struct kb_item *kbi;
711
712 kbi = NULL;
713
714 switch (rep->type)
715 {
716 unsigned int i;
717
718 case REDIS_REPLY_STRING:
719 case REDIS_REPLY_INTEGER:
720 kbi = redis2kbitem_single (name, rep, 0);
721 break;
722
723 case REDIS_REPLY_ARRAY:
724 for (i = 0; i < rep->elements; i++)
725 {
726 struct kb_item *tmpitem;
727
728 tmpitem = redis2kbitem_single (name, rep->element[i], 0);
729 if (tmpitem == NULL)
730 break;
731
732 if (kbi != NULL)
733 {
734 tmpitem->next = kbi;
735 kbi = tmpitem;
736 }
737 else
738 kbi = tmpitem;
739 }
740 break;
741
742 case REDIS_REPLY_NIL:
743 case REDIS_REPLY_STATUS:
744 case REDIS_REPLY_ERROR:
745 default:
746 break;
747 }
748
749 return kbi;
750}
static struct kb_item * redis2kbitem_single(const char *name, const redisReply *elt, int force_int)
Give a single KB item.
Definition: kb.c:663
char name[]
Definition: kb.h:82

References kb_item::name, kb_item::next, and redis2kbitem_single().

Referenced by redis_get_all(), and redis_get_pattern().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis2kbitem_single()

static struct kb_item * redis2kbitem_single ( const char *  name,
const redisReply *  elt,
int  force_int 
)
static

Give a single KB item.

Parameters
[in]nameName of the item.
[in]eltA redisReply element where to fetch the item.
[in]force_intTo force string to integer conversion.
Returns
Single retrieve kb_item on success, NULL otherwise.

Definition at line 663 of file kb.c.

664{
665 struct kb_item *item;
666 size_t namelen;
667
668 if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
669 return NULL;
670
671 namelen = strlen (name) + 1;
672
673 item = g_malloc0 (sizeof (struct kb_item) + namelen);
674 if (elt->type == REDIS_REPLY_INTEGER)
675 {
676 item->type = KB_TYPE_INT;
677 item->v_int = elt->integer;
678 }
679 else if (force_int)
680 {
681 item->type = KB_TYPE_INT;
682 item->v_int = atoi (elt->str);
683 }
684 else
685 {
686 item->type = KB_TYPE_STR;
687 item->v_str = memdup (elt->str, elt->len + 1);
688 item->len = elt->len;
689 }
690
691 item->next = NULL;
692 item->namelen = namelen;
693 memset (item->name, 0, namelen);
694 memcpy (item->name, name, namelen);
695
696 return item;
697}
#define memdup
Definition: kb.c:32
@ KB_TYPE_INT
Definition: kb.h:35
int v_int
Definition: kb.h:75
size_t len
Definition: kb.h:78
size_t namelen
Definition: kb.h:81

References KB_TYPE_INT, KB_TYPE_STR, kb_item::len, memdup, kb_item::name, kb_item::namelen, kb_item::next, kb_item::type, kb_item::v_int, and kb_item::v_str.

Referenced by redis2kbitem(), and redis_get_single().

Here is the caller graph for this function:

◆ redis_add_int()

static int redis_add_int ( kb_t  kb,
const char *  name,
int  val 
)
static

Insert (append) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
Returns
0 on success, non-null on error.

Definition at line 1543 of file kb.c.

1544{
1545 redisReply *rep;
1546 int rc = 0;
1547
1548 rep = redis_cmd (redis_kb (kb), "RPUSH %s %d", name, val);
1549 if (!rep || rep->type == REDIS_REPLY_ERROR)
1550 rc = -1;
1551 if (rep)
1552 freeReplyObject (rep);
1553
1554 return rc;
1555}
#define redis_kb(__kb)
Definition: kb.c:62
static redisReply * redis_cmd(struct kb_redis *kbr, const char *fmt,...)
Execute a redis command and get a redis reply.
Definition: kb.c:761
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:91

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_int_unique()

static int redis_add_int_unique ( kb_t  kb,
const char *  name,
int  val 
)
static

Insert (append) a new unique entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
Returns
0 on success, non-null on error.

Definition at line 1502 of file kb.c.

1503{
1504 struct kb_redis *kbr;
1505 redisReply *rep;
1506 int rc = 0;
1507 redisContext *ctx;
1508
1509 kbr = redis_kb (kb);
1510 if (get_redis_ctx (kbr) < 0)
1511 return -1;
1512 ctx = kbr->rctx;
1513 redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
1514 redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1515 redisGetReply (ctx, (void **) &rep);
1516 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1517 g_debug ("Key '%s' already contained integer '%d'", name, val);
1518 freeReplyObject (rep);
1519 redisGetReply (ctx, (void **) &rep);
1520 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1521 {
1522 rc = -1;
1523 goto out;
1524 }
1525
1526out:
1527 if (rep != NULL)
1528 freeReplyObject (rep);
1529
1530 return rc;
1531}
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:312
Subclass of struct kb, it contains the redis-specific fields, such as the redis context,...
Definition: kb.c:55

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_add_int_unique_volatile()

static int redis_add_int_unique_volatile ( kb_t  kb,
const char *  name,
int  val,
int  expire 
)
static

Insert (append) a new unique entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
[in]expireItem expire.
Returns
0 on success, non-null on error.

Definition at line 1449 of file kb.c.

1450{
1451 struct kb_redis *kbr;
1452 redisReply *rep;
1453 int rc = 0;
1454 redisContext *ctx;
1455
1456 kbr = redis_kb (kb);
1457 if (get_redis_ctx (kbr) < 0)
1458 return -1;
1459 ctx = kbr->rctx;
1460 redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
1461 redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1462 redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
1463 /* Check LREM reply. */
1464 redisGetReply (ctx, (void **) &rep);
1465 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1466 g_debug ("Key '%s' already contained integer '%d'", name, val);
1467 freeReplyObject (rep);
1468 /* Check PUSH reply. */
1469 redisGetReply (ctx, (void **) &rep);
1470 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1471 {
1472 rc = -1;
1473 goto out;
1474 }
1475 /* Check EXPIRE reply. */
1476 redisGetReply (ctx, (void **) &rep);
1477 if (rep == NULL || rep->type == REDIS_REPLY_ERROR
1478 || (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
1479 {
1480 g_warning ("%s: Not able to set expire", __func__);
1481 rc = -1;
1482 goto out;
1483 }
1484
1485out:
1486 if (rep != NULL)
1487 freeReplyObject (rep);
1488
1489 return rc;
1490}

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_add_nvt()

static int redis_add_nvt ( kb_t  kb,
const nvti_t nvt,
const char *  filename 
)
static

Insert a new nvt.

Parameters
[in]kbKB handle where to store the nvt.
[in]nvtnvt to store.
[in]filenamePath to nvt to store.
Returns
0 on success, non-null on error.

Definition at line 1604 of file kb.c.

1605{
1606 struct kb_redis *kbr;
1607 redisReply *rep = NULL;
1608 int rc = 0;
1609 unsigned int i;
1610 gchar *cves, *bids, *xrefs;
1611
1612 if (!nvt || !filename)
1613 return -1;
1614
1615 cves = nvti_refs (nvt, "cve", "", 0);
1616 bids = nvti_refs (nvt, "bid", "", 0);
1617 xrefs = nvti_refs (nvt, NULL, "cve,bid", 1);
1618
1619 kbr = redis_kb (kb);
1620 rep = redis_cmd (
1621 kbr, "RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %s %s",
1622 nvti_oid (nvt), filename,
1623 nvti_required_keys (nvt) ? nvti_required_keys (nvt) : "",
1624 nvti_mandatory_keys (nvt) ? nvti_mandatory_keys (nvt) : "",
1625 nvti_excluded_keys (nvt) ? nvti_excluded_keys (nvt) : "",
1627 nvti_required_ports (nvt) ? nvti_required_ports (nvt) : "",
1628 nvti_dependencies (nvt) ? nvti_dependencies (nvt) : "",
1629 nvti_tag (nvt) ? nvti_tag (nvt) : "", cves ? cves : "", bids ? bids : "",
1630 xrefs ? xrefs : "", nvti_category (nvt), nvti_family (nvt),
1631 nvti_name (nvt));
1632 g_free (cves);
1633 g_free (bids);
1634 g_free (xrefs);
1635 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1636 rc = -1;
1637 if (rep != NULL)
1638 freeReplyObject (rep);
1639
1640 if (nvti_pref_len (nvt))
1641 redis_cmd (kbr, "DEL oid:%s:prefs", nvti_oid (nvt));
1642 for (i = 0; i < nvti_pref_len (nvt); i++)
1643 {
1644 const nvtpref_t *pref = nvti_pref (nvt, i);
1645
1646 rep = redis_cmd (kbr, "RPUSH oid:%s:prefs %d|||%s|||%s|||%s",
1647 nvti_oid (nvt), nvtpref_id (pref), nvtpref_name (pref),
1648 nvtpref_type (pref), nvtpref_default (pref));
1649 if (!rep || rep->type == REDIS_REPLY_ERROR)
1650 rc = -1;
1651 if (rep)
1652 freeReplyObject (rep);
1653 }
1654 rep = redis_cmd (kbr, "RPUSH filename:%s %lu %s", filename, time (NULL),
1655 nvti_oid (nvt));
1656 if (!rep || rep->type == REDIS_REPLY_ERROR)
1657 rc = -1;
1658 if (rep)
1659 freeReplyObject (rep);
1660 return rc;
1661}
gchar * nvti_dependencies(const nvti_t *n)
Get the dependencies list.
Definition: nvti.c:1070
guint nvti_pref_len(const nvti_t *n)
Get the number of preferences of the NVT.
Definition: nvti.c:1209
gchar * nvti_required_udp_ports(const nvti_t *n)
Get the required udp ports list.
Definition: nvti.c:1140
gchar * nvti_required_ports(const nvti_t *n)
Get the required ports list.
Definition: nvti.c:1126
gchar * nvti_refs(const nvti_t *n, const gchar *type, const gchar *exclude_types, guint use_types)
Get references as string.
Definition: nvti.c:804
gchar * nvtpref_type(const nvtpref_t *np)
Get the Type of a NVT Preference.
Definition: nvti.c:569
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
Definition: nvti.c:1237
gchar * nvti_family(const nvti_t *n)
Get the family name.
Definition: nvti.c:1196
const nvtpref_t * nvti_pref(const nvti_t *n, guint p)
Get the n'th preferences of the NVT.
Definition: nvti.c:1224
gchar * nvti_excluded_keys(const nvti_t *n)
Get the excluded keys list.
Definition: nvti.c:1112
gchar * nvti_name(const nvti_t *n)
Get the name.
Definition: nvti.c:663
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition: nvti.c:649
int nvtpref_id(const nvtpref_t *np)
Get the ID of a NVT Preference.
Definition: nvti.c:541
gchar * nvti_required_keys(const nvti_t *n)
Get the required keys list.
Definition: nvti.c:1084
gchar * nvti_mandatory_keys(const nvti_t *n)
Get the mandatory keys list.
Definition: nvti.c:1098
gchar * nvtpref_default(const nvtpref_t *np)
Get the Default of a NVT Preference.
Definition: nvti.c:583
gchar * nvtpref_name(const nvtpref_t *np)
Get the Name of a NVT Preference.
Definition: nvti.c:555
gchar * nvti_tag(const nvti_t *n)
Get the tags.
Definition: nvti.c:1004
The structure for a preference of a NVT.
Definition: nvti.c:477

References nvti_category(), nvti_dependencies(), nvti_excluded_keys(), nvti_family(), nvti_mandatory_keys(), nvti_name(), nvti_oid(), nvti_pref(), nvti_pref_len(), nvti_refs(), nvti_required_keys(), nvti_required_ports(), nvti_required_udp_ports(), nvti_tag(), nvtpref_default(), nvtpref_id(), nvtpref_name(), nvtpref_type(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_str()

static int redis_add_str ( kb_t  kb,
const char *  name,
const char *  str,
size_t  len 
)
static

Insert (append) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]strItem value.
[in]lenValue length. Used for blobs.
Returns
0 on success, non-null on error.

Definition at line 1378 of file kb.c.

1379{
1380 struct kb_redis *kbr;
1381 redisReply *rep;
1382 int rc = 0;
1383
1384 kbr = redis_kb (kb);
1385 if (len == 0)
1386 rep = redis_cmd (kbr, "RPUSH %s %s", name, str);
1387 else
1388 rep = redis_cmd (kbr, "RPUSH %s %b", name, str, len);
1389 if (!rep || rep->type == REDIS_REPLY_ERROR)
1390 rc = -1;
1391
1392 if (rep)
1393 freeReplyObject (rep);
1394 return rc;
1395}

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_str_unique()

static int redis_add_str_unique ( kb_t  kb,
const char *  name,
const char *  str,
size_t  len,
int  pos 
)
static

Insert (append) a new unique entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]strItem value.
[in]lenValue length. Used for blobs.
[in]posWhich position the value is appended to. 0 for right, 1 for left position in the list.
Returns
0 on success, non-null on error.

Definition at line 1320 of file kb.c.

1322{
1323 struct kb_redis *kbr;
1324 redisReply *rep = NULL;
1325 int rc = 0;
1326 redisContext *ctx;
1327
1328 kbr = redis_kb (kb);
1329 if (get_redis_ctx (kbr) < 0)
1330 return -1;
1331 ctx = kbr->rctx;
1332
1333 /* Some VTs still rely on values being unique (ie. a value inserted multiple
1334 * times, will only be present once.)
1335 * Once these are fixed, the LREM becomes redundant and should be removed.
1336 */
1337 if (len == 0)
1338 {
1339 redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
1340 redisAppendCommand (ctx, "%s %s %s", pos ? "LPUSH" : "RPUSH", name, str);
1341 redisGetReply (ctx, (void **) &rep);
1342 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1343 g_debug ("Key '%s' already contained value '%s'", name, str);
1344 freeReplyObject (rep);
1345 redisGetReply (ctx, (void **) &rep);
1346 }
1347 else
1348 {
1349 redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
1350 redisAppendCommand (ctx, "%s %s %b", pos ? "LPUSH" : "RPUSH", name, str,
1351 len);
1352 redisGetReply (ctx, (void **) &rep);
1353 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1354 g_debug ("Key '%s' already contained string '%s'", name, str);
1355 freeReplyObject (rep);
1356 redisGetReply (ctx, (void **) &rep);
1357 }
1358 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1359 rc = -1;
1360
1361 if (rep != NULL)
1362 freeReplyObject (rep);
1363
1364 return rc;
1365}

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_add_str_unique_volatile()

static int redis_add_str_unique_volatile ( kb_t  kb,
const char *  name,
const char *  str,
int  expire,
size_t  len,
int  pos 
)
static

Insert (append) a new unique and volatile entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]strItem value.
[in]expireItem expire.
[in]lenValue length. Used for blobs.
[in]posWhich position the value is appended to. 0 for right, 1 for left position in the list.
Returns
0 on success, -1 on error.

Definition at line 1227 of file kb.c.

1229{
1230 struct kb_redis *kbr;
1231 redisReply *rep = NULL;
1232 int rc = 0;
1233 redisContext *ctx;
1234
1235 kbr = redis_kb (kb);
1236 if (get_redis_ctx (kbr) < 0)
1237 return -1;
1238 ctx = kbr->rctx;
1239
1240 /* Some VTs still rely on values being unique (ie. a value inserted multiple
1241 * times, will only be present once.)
1242 * Once these are fixed, the LREM becomes redundant and should be removed.
1243 */
1244 if (len == 0)
1245 {
1246 redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
1247 redisAppendCommand (ctx, "%s %s %s", pos ? "LPUSH" : "RPUSH", name, str);
1248 redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
1249 /* Check LREM reply. */
1250 redisGetReply (ctx, (void **) &rep);
1251 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1252 g_debug ("Key '%s' already contained value '%s'", name, str);
1253 freeReplyObject (rep);
1254 /* Check PUSH reply. */
1255 redisGetReply (ctx, (void **) &rep);
1256 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1257 {
1258 rc = -1;
1259 goto out;
1260 }
1261 /* Check EXPIRE reply. */
1262 redisGetReply (ctx, (void **) &rep);
1263 if (rep == NULL || rep->type == REDIS_REPLY_ERROR
1264 || (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
1265 {
1266 g_warning ("%s: Not able to set expire", __func__);
1267 rc = -1;
1268 goto out;
1269 }
1270 }
1271 else
1272 {
1273 redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
1274 redisAppendCommand (ctx, "%s %s %b", pos ? "LPUSH" : "RPUSH", name, str,
1275 len);
1276 redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
1277 /* Check LREM reply. */
1278 redisGetReply (ctx, (void **) &rep);
1279 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1280 g_debug ("Key '%s' already contained string '%s'", name, str);
1281 freeReplyObject (rep);
1282 /* Check PUSH reply. */
1283 redisGetReply (ctx, (void **) &rep);
1284 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1285 {
1286 rc = -1;
1287 goto out;
1288 }
1289 /* Check EXPIRE reply. */
1290 redisGetReply (ctx, (void **) &rep);
1291 if (rep == NULL || rep->type == REDIS_REPLY_ERROR
1292 || (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
1293 {
1294 g_warning ("%s: Not able to set expire", __func__);
1295 rc = -1;
1296 goto out;
1297 }
1298 }
1299
1300out:
1301 if (rep != NULL)
1302 freeReplyObject (rep);
1303
1304 return rc;
1305}

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_cmd()

static redisReply * redis_cmd ( struct kb_redis kbr,
const char *  fmt,
  ... 
)
static

Execute a redis command and get a redis reply.

Parameters
[in]kbrSubclass of struct kb to connect to.
[in]fmtFormatted variable argument list with the cmd to be executed.
Returns
Redis reply on success, NULL otherwise.

Definition at line 761 of file kb.c.

762{
763 redisReply *rep;
764 va_list ap, aq;
765 int retry = 0;
766
767 va_start (ap, fmt);
768 do
769 {
770 if (get_redis_ctx (kbr) < 0)
771 {
772 va_end (ap);
773 return NULL;
774 }
775
776 va_copy (aq, ap);
777 rep = redisvCommand (kbr->rctx, fmt, aq);
778 va_end (aq);
779
780 if (kbr->rctx->err)
781 {
782 if (rep != NULL)
783 freeReplyObject (rep);
784
785 redis_lnk_reset ((kb_t) kbr);
786 retry = !retry;
787 }
788 else
789 retry = 0;
790 }
791 while (retry);
792
793 va_end (ap);
794
795 return rep;
796}
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:1672

References get_redis_ctx(), kb_redis::rctx, and redis_lnk_reset().

Referenced by redis_add_int(), redis_add_nvt(), redis_add_str(), redis_count(), redis_del_items(), redis_delete_all(), redis_get_all(), redis_get_nvt(), redis_get_nvt_all(), redis_get_oids(), redis_get_pattern(), redis_get_single(), redis_memory_purge(), redis_pop_str(), redis_push_str(), redis_save(), and redis_test_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_count()

static size_t redis_count ( kb_t  kb,
const char *  pattern 
)
static

Count all items stored under a given pattern.

Parameters
[in]kbKB handle where to count the items.
[in]pattern'*' pattern of the elements to count.
Returns
Count of items.

Definition at line 1163 of file kb.c.

1164{
1165 struct kb_redis *kbr;
1166 redisReply *rep;
1167 size_t count;
1168
1169 kbr = redis_kb (kb);
1170
1171 rep = redis_cmd (kbr, "KEYS %s", pattern);
1172 if (rep == NULL)
1173 return 0;
1174
1175 if (rep->type != REDIS_REPLY_ARRAY)
1176 {
1177 freeReplyObject (rep);
1178 return 0;
1179 }
1180
1181 count = rep->elements;
1182 freeReplyObject (rep);
1183 return count;
1184}

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_del_items()

static int redis_del_items ( kb_t  kb,
const char *  name 
)
static

Delete all entries under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
Returns
0 on success, non-null on error.

Definition at line 1195 of file kb.c.

1196{
1197 struct kb_redis *kbr;
1198 redisReply *rep;
1199 int rc = 0;
1200
1201 kbr = redis_kb (kb);
1202
1203 rep = redis_cmd (kbr, "DEL %s", name);
1204 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1205 rc = -1;
1206
1207 if (rep != NULL)
1208 freeReplyObject (rep);
1209
1210 return rc;
1211}

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_delete()

static int redis_delete ( kb_t  kb)
static

Delete all entries and release ownership on the namespace.

Parameters
[in]kbKB handle to release.
Returns
0 on success, non-null on error.

Definition at line 392 of file kb.c.

393{
394 struct kb_redis *kbr;
395
396 kbr = redis_kb (kb);
397
398 redis_delete_all (kbr);
399 redis_release_db (kbr);
400
401 if (kbr->rctx != NULL)
402 {
403 g_free (kbr->path);
404 redisFree (kbr->rctx);
405 kbr->rctx = NULL;
406 }
407
408 g_free (kb);
409 return 0;
410}
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
Definition: kb.c:1806
static int redis_release_db(struct kb_redis *kbr)
Release DB.
Definition: kb.c:216

References kb_redis::path, kb_redis::rctx, redis_delete_all(), redis_kb, and redis_release_db().

Referenced by redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_delete_all()

int redis_delete_all ( struct kb_redis kbr)
static

Delete all the KB's content.

Parameters
[in]kbrSubclass of struct kb.
Returns
0 on success, non-null on error.

Definition at line 1806 of file kb.c.

1807{
1808 int rc;
1809 redisReply *rep;
1810 struct sigaction new_action, original_action;
1811
1812 /* Ignore SIGPIPE, in case of a lost connection. */
1813 new_action.sa_flags = 0;
1814 if (sigemptyset (&new_action.sa_mask))
1815 return -1;
1816 new_action.sa_handler = SIG_IGN;
1817 if (sigaction (SIGPIPE, &new_action, &original_action))
1818 return -1;
1819
1820 if (kbr)
1821 g_debug ("%s: deleting all elements from KB #%u", __func__, kbr->db);
1822 rep = redis_cmd (kbr, "FLUSHDB");
1823 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1824 {
1825 rc = -1;
1826 goto err_cleanup;
1827 }
1828
1829 rc = 0;
1830
1831err_cleanup:
1832 if (sigaction (SIGPIPE, &original_action, NULL))
1833 return -1;
1834 if (rep != NULL)
1835 freeReplyObject (rep);
1836
1837 return rc;
1838}

References kb_redis::db, and redis_cmd().

Referenced by redis_delete(), redis_flush_all(), and redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_direct_conn()

static kb_t redis_direct_conn ( const char *  kb_path,
const int  kb_index 
)
static

Connect to a Knowledge Base object with the given kb_index.

Parameters
[in]kb_pathPath to KB.
[in]kb_indexDB index
Returns
Knowledge Base object, NULL otherwise.

Definition at line 513 of file kb.c.

514{
515 struct kb_redis *kbr;
516 redisReply *rep;
517
518 if (kb_path == NULL)
519 return NULL;
520
521 kbr = g_malloc0 (sizeof (struct kb_redis));
523 kbr->path = g_strdup (kb_path);
524
525 kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
526 if (kbr->rctx == NULL || kbr->rctx->err)
527 {
528 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
529 "%s: redis connection error to %s: %s", __func__, kbr->path,
530 kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
531 redisFree (kbr->rctx);
532 g_free (kbr->path);
533 g_free (kbr);
534 return NULL;
535 }
536 kbr->db = kb_index;
537 rep = redisCommand (kbr->rctx, "SELECT %d", kb_index);
538 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
539 {
540 if (rep != NULL)
541 freeReplyObject (rep);
542 redisFree (kbr->rctx);
543 kbr->rctx = NULL;
544 g_free (kbr->path);
545 g_free (kbr);
546 return NULL;
547 }
548 freeReplyObject (rep);
549 return (kb_t) kbr;
550}
static const struct kb_operations KBRedisOperations
Default KB operations.
Definition: kb.c:47
struct kb kb
Definition: kb.c:56
const struct kb_operations * kb_ops
Definition: kb.h:92

References connect_redis(), kb_redis::db, G_LOG_DOMAIN, kb_redis::kb, kb::kb_ops, KBRedisOperations, kb_redis::path, and kb_redis::rctx.

Here is the call graph for this function:

◆ redis_find()

static kb_t redis_find ( const char *  kb_path,
const char *  key 
)
static

Find an existing Knowledge Base object with key.

Parameters
[in]kb_pathPath to KB.
[in]keyMarker key to search for in KB objects.
Returns
Knowledge Base object, NULL otherwise.

Definition at line 561 of file kb.c.

562{
563 struct kb_redis *kbr;
564 unsigned int i = 1;
565
566 if (kb_path == NULL)
567 return NULL;
568
569 kbr = g_malloc0 (sizeof (struct kb_redis));
571 kbr->path = g_strdup (kb_path);
572
573 do
574 {
575 redisReply *rep;
576
577 kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
578 if (kbr->rctx == NULL || kbr->rctx->err)
579 {
580 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
581 "%s: redis connection error to %s: %s", __func__, kbr->path,
582 kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
583 redisFree (kbr->rctx);
584 g_free (kbr->path);
585 g_free (kbr);
586 return NULL;
587 }
588
589 if (kbr->max_db == 0)
590 fetch_max_db_index (kbr);
591
592 kbr->db = i;
593 rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
594 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
595 {
596 if (rep != NULL)
597 freeReplyObject (rep);
598 i++;
599 redisFree (kbr->rctx);
600 kbr->rctx = NULL;
601 continue;
602 }
603 freeReplyObject (rep);
604 rep = redisCommand (kbr->rctx, "SELECT %u", i);
605 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
606 {
607 redisFree (kbr->rctx);
608 kbr->rctx = NULL;
609 }
610 else
611 {
612 freeReplyObject (rep);
613 if (key)
614 {
615 char *tmp = kb_item_get_str (&kbr->kb, key);
616 if (tmp)
617 {
618 g_free (tmp);
619 return (kb_t) kbr;
620 }
621 }
622 redisFree (kbr->rctx);
623 }
624 i++;
625 }
626 while (i < kbr->max_db);
627
628 g_free (kbr->path);
629 g_free (kbr);
630 return NULL;
631}
#define GLOBAL_DBINDEX_NAME
Name of the namespace usage bitmap in redis.
Definition: kb.c:45
static int fetch_max_db_index(struct kb_redis *kbr)
Set the number of databases have been configured into kbr struct.
Definition: kb.c:109
static char * kb_item_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.h:334

References connect_redis(), kb_redis::db, fetch_max_db_index(), G_LOG_DOMAIN, GLOBAL_DBINDEX_NAME, kb_redis::kb, kb_item_get_str(), kb::kb_ops, KBRedisOperations, kb_redis::max_db, kb_redis::path, and kb_redis::rctx.

Here is the call graph for this function:

◆ redis_flush_all()

static int redis_flush_all ( kb_t  kb,
const char *  except 
)
static

Flush all the KB's content. Delete all namespaces.

Parameters
[in]kbKB handle.
[in]exceptDon't flush DB with except key.
Returns
0 on success, non-null on error.

Definition at line 1696 of file kb.c.

1697{
1698 unsigned int i = 1;
1699 struct kb_redis *kbr;
1700
1701 kbr = redis_kb (kb);
1702 if (kbr->rctx)
1703 redisFree (kbr->rctx);
1704
1705 g_debug ("%s: deleting all DBs at %s except %s", __func__, kbr->path, except);
1706 do
1707 {
1708 redisReply *rep;
1709
1710 kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
1711 if (kbr->rctx == NULL || kbr->rctx->err)
1712 {
1713 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1714 "%s: redis connection error to %s: %s", __func__, kbr->path,
1715 kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
1716 redisFree (kbr->rctx);
1717 kbr->rctx = NULL;
1718 return -1;
1719 }
1720
1721 kbr->db = i;
1722 rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
1723 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
1724 {
1725 freeReplyObject (rep);
1726 redisFree (kbr->rctx);
1727 i++;
1728 continue;
1729 }
1730 freeReplyObject (rep);
1731 rep = redisCommand (kbr->rctx, "SELECT %u", i);
1732 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1733 {
1734 freeReplyObject (rep);
1735 redisFree (kbr->rctx);
1736 kbr->rctx = NULL;
1737 }
1738 else
1739 {
1740 freeReplyObject (rep);
1741 /* Don't remove DB if it has "except" key. */
1742 if (except)
1743 {
1744 char *tmp = kb_item_get_str (kb, except);
1745 if (tmp)
1746 {
1747 g_free (tmp);
1748 i++;
1749 redisFree (kbr->rctx);
1750 continue;
1751 }
1752 }
1753 redis_delete_all (kbr);
1754 redis_release_db (kbr);
1755 redisFree (kbr->rctx);
1756 }
1757 i++;
1758 }
1759 while (i < kbr->max_db);
1760
1761 g_free (kbr->path);
1762 g_free (kb);
1763 return 0;
1764}

References connect_redis(), kb_redis::db, G_LOG_DOMAIN, GLOBAL_DBINDEX_NAME, kb_item_get_str(), kb_redis::max_db, kb_redis::path, kb_redis::rctx, redis_delete_all(), redis_kb, and redis_release_db().

Here is the call graph for this function:

◆ redis_get_all()

static struct kb_item * redis_get_all ( kb_t  kb,
const char *  name 
)
static

Get all items stored under a given name.

Parameters
[in]kbKB handle where to fetch the items.
[in]nameName of the elements to retrieve.
Returns
Linked struct kb_item instances to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 1035 of file kb.c.

1036{
1037 struct kb_redis *kbr;
1038 struct kb_item *kbi;
1039 redisReply *rep;
1040
1041 kbr = redis_kb (kb);
1042
1043 rep = redis_cmd (kbr, "LRANGE %s 0 -1", name);
1044 if (rep == NULL)
1045 return NULL;
1046
1047 kbi = redis2kbitem (name, rep);
1048
1049 freeReplyObject (rep);
1050
1051 return kbi;
1052}
static struct kb_item * redis2kbitem(const char *name, const redisReply *rep)
Fetch a KB item or list from a redis Reply.
Definition: kb.c:708

References kb_item::name, redis2kbitem(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_int()

static int redis_get_int ( kb_t  kb,
const char *  name 
)
static

Get a single KB integer item.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the element to retrieve.
Returns
An integer.

Definition at line 927 of file kb.c.

928{
929 struct kb_item *kbi;
930
932 if (kbi != NULL)
933 {
934 int res;
935
936 res = kbi->v_int;
937 kb_item_free (kbi);
938 return res;
939 }
940 return -1;
941}
void kb_item_free(struct kb_item *item)
Release a KB item (or a list).
Definition: kb.c:639
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:809

References kb_item_free(), KB_TYPE_INT, kb_item::name, redis_get_single(), and kb_item::v_int.

Here is the call graph for this function:

◆ redis_get_kb_index()

static int redis_get_kb_index ( kb_t  kb)
static

Return the kb index.

Parameters
[in]kbKB handle.
Returns
kb_index on success, null on error.

Definition at line 420 of file kb.c.

421{
422 int i;
423 i = ((struct kb_redis *) kb)->db;
424 if (i > 0)
425 return i;
426 return -1;
427}

◆ redis_get_nvt()

static char * redis_get_nvt ( kb_t  kb,
const char *  oid,
enum kb_nvt_pos  position 
)
static

Get field of a NVT.

Parameters
[in]kbKB handle where to store the nvt.
[in]oidOID of NVT to get from.
[in]positionPosition of field to get.
Returns
Value of field, NULL otherwise.

Definition at line 953 of file kb.c.

954{
955 struct kb_redis *kbr;
956 redisReply *rep;
957 char *res = NULL;
958
959 kbr = redis_kb (kb);
960 if (position >= NVT_TIMESTAMP_POS)
961 rep = redis_cmd (kbr, "LINDEX filename:%s %d", oid,
962 position - NVT_TIMESTAMP_POS);
963 else
964 rep = redis_cmd (kbr, "LINDEX nvt:%s %d", oid, position);
965 if (!rep)
966 return NULL;
967 if (rep->type == REDIS_REPLY_INTEGER)
968 res = g_strdup_printf ("%lld", rep->integer);
969 else if (rep->type == REDIS_REPLY_STRING)
970 res = g_strdup (rep->str);
971 freeReplyObject (rep);
972
973 return res;
974}
@ NVT_TIMESTAMP_POS
Definition: kb.h:60

References NVT_TIMESTAMP_POS, redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_nvt_all()

static nvti_t * redis_get_nvt_all ( kb_t  kb,
const char *  oid 
)
static

Get a full NVT.

Parameters
[in]kbKB handle where to store the nvt.
[in]oidOID of NVT to get.
Returns
nvti_t of NVT, NULL otherwise.

Definition at line 985 of file kb.c.

986{
987 struct kb_redis *kbr;
988 redisReply *rep;
989
990 kbr = redis_kb (kb);
991 rep =
992 redis_cmd (kbr, "LRANGE nvt:%s %d %d", oid, NVT_FILENAME_POS, NVT_NAME_POS);
993 if (!rep)
994 return NULL;
995 if (rep->type != REDIS_REPLY_ARRAY || rep->elements != NVT_NAME_POS + 1)
996 {
997 freeReplyObject (rep);
998 return NULL;
999 }
1000 else
1001 {
1002 nvti_t *nvti = nvti_new ();
1003
1004 nvti_set_oid (nvti, oid);
1009 nvti, rep->element[NVT_REQUIRED_UDP_PORTS_POS]->str);
1011 nvti_set_dependencies (nvti, rep->element[NVT_DEPENDENCIES_POS]->str);
1012 nvti_set_tag (nvti, rep->element[NVT_TAGS_POS]->str);
1013 nvti_add_refs (nvti, "cve", rep->element[NVT_CVES_POS]->str, "");
1014 nvti_add_refs (nvti, "bid", rep->element[NVT_BIDS_POS]->str, "");
1015 nvti_add_refs (nvti, NULL, rep->element[NVT_XREFS_POS]->str, "");
1016 nvti_set_category (nvti, atoi (rep->element[NVT_CATEGORY_POS]->str));
1017 nvti_set_family (nvti, rep->element[NVT_FAMILY_POS]->str);
1018 nvti_set_name (nvti, rep->element[NVT_NAME_POS]->str);
1019
1020 freeReplyObject (rep);
1021 return nvti;
1022 }
1023}
@ NVT_FAMILY_POS
Definition: kb.h:58
@ NVT_CATEGORY_POS
Definition: kb.h:57
@ NVT_NAME_POS
Definition: kb.h:59
@ NVT_TAGS_POS
Definition: kb.h:53
@ NVT_BIDS_POS
Definition: kb.h:55
@ NVT_EXCLUDED_KEYS_POS
Definition: kb.h:49
@ NVT_REQUIRED_PORTS_POS
Definition: kb.h:51
@ NVT_REQUIRED_UDP_PORTS_POS
Definition: kb.h:50
@ NVT_FILENAME_POS
Definition: kb.h:46
@ NVT_DEPENDENCIES_POS
Definition: kb.h:52
@ NVT_CVES_POS
Definition: kb.h:54
@ NVT_REQUIRED_KEYS_POS
Definition: kb.h:47
@ NVT_XREFS_POS
Definition: kb.h:56
@ NVT_MANDATORY_KEYS_POS
Definition: kb.h:48
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition: nvti.c:597
int nvti_set_excluded_keys(nvti_t *n, const gchar *excluded_keys)
Set the excluded keys of a NVT.
Definition: nvti.c:1782
int nvti_set_dependencies(nvti_t *n, const gchar *dependencies)
Set the dependencies of a NVT.
Definition: nvti.c:1710
int nvti_set_required_ports(nvti_t *n, const gchar *required_ports)
Set the required ports of a NVT.
Definition: nvti.c:1806
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
Definition: nvti.c:1252
int nvti_set_tag(nvti_t *n, const gchar *tag)
Set the tags of a NVT.
Definition: nvti.c:1663
int nvti_set_mandatory_keys(nvti_t *n, const gchar *mandatory_keys)
Set the mandatory keys of a NVT.
Definition: nvti.c:1758
int nvti_set_required_keys(nvti_t *n, const gchar *required_keys)
Set the required keys of a NVT.
Definition: nvti.c:1734
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
Definition: nvti.c:1272
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:2006
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:1830
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
Definition: nvti.c:1941
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
Definition: nvti.c:1981
The structure of a information record that corresponds to a NVT.
Definition: nvti.c:394

References NVT_BIDS_POS, NVT_CATEGORY_POS, NVT_CVES_POS, NVT_DEPENDENCIES_POS, NVT_EXCLUDED_KEYS_POS, NVT_FAMILY_POS, NVT_FILENAME_POS, NVT_MANDATORY_KEYS_POS, NVT_NAME_POS, NVT_REQUIRED_KEYS_POS, NVT_REQUIRED_PORTS_POS, NVT_REQUIRED_UDP_PORTS_POS, NVT_TAGS_POS, NVT_XREFS_POS, nvti_add_refs(), nvti_new(), nvti_set_category(), nvti_set_dependencies(), nvti_set_excluded_keys(), nvti_set_family(), nvti_set_mandatory_keys(), nvti_set_name(), nvti_set_oid(), nvti_set_required_keys(), nvti_set_required_ports(), nvti_set_required_udp_ports(), nvti_set_tag(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_oids()

static GSList * redis_get_oids ( kb_t  kb)
static

Get all NVT OIDs.

Parameters
[in]kbKB handle where to fetch the items.
Returns
Linked list of all OIDs or NULL.

Definition at line 1128 of file kb.c.

1129{
1130 struct kb_redis *kbr;
1131 redisReply *rep;
1132 GSList *list = NULL;
1133 size_t i;
1134
1135 kbr = redis_kb (kb);
1136 rep = redis_cmd (kbr, "KEYS nvt:*");
1137 if (!rep)
1138 return NULL;
1139
1140 if (rep->type != REDIS_REPLY_ARRAY)
1141 {
1142 freeReplyObject (rep);
1143 return NULL;
1144 }
1145
1146 /* Fetch OID values from key names nvt:OID. */
1147 for (i = 0; i < rep->elements; i++)
1148 list = g_slist_prepend (list, g_strdup (rep->element[i]->str + 4));
1149 freeReplyObject (rep);
1150
1151 return list;
1152}

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_pattern()

static struct kb_item * redis_get_pattern ( kb_t  kb,
const char *  pattern 
)
static

Get all items stored under a given pattern.

Parameters
[in]kbKB handle where to fetch the items.
[in]pattern'*' pattern of the elements to retrieve.
Returns
Linked struct kb_item instances to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 1064 of file kb.c.

1065{
1066 struct kb_redis *kbr;
1067 struct kb_item *kbi = NULL;
1068 redisReply *rep;
1069 unsigned int i;
1070
1071 kbr = redis_kb (kb);
1072 rep = redis_cmd (kbr, "KEYS %s", pattern);
1073 if (!rep)
1074 return NULL;
1075 if (rep->type != REDIS_REPLY_ARRAY)
1076 {
1077 freeReplyObject (rep);
1078 return NULL;
1079 }
1080
1081 if (get_redis_ctx (kbr) < 0)
1082 return NULL;
1083 for (i = 0; i < rep->elements; i++)
1084 redisAppendCommand (kbr->rctx, "LRANGE %s 0 -1", rep->element[i]->str);
1085
1086 for (i = 0; i < rep->elements; i++)
1087 {
1088 struct kb_item *tmp;
1089 redisReply *rep_range;
1090
1091 redisGetReply (kbr->rctx, (void **) &rep_range);
1092 if (!rep)
1093 continue;
1094 tmp = redis2kbitem (rep->element[i]->str, rep_range);
1095 if (!tmp)
1096 {
1097 freeReplyObject (rep_range);
1098 continue;
1099 }
1100
1101 if (kbi)
1102 {
1103 struct kb_item *tmp2;
1104
1105 tmp2 = tmp;
1106 while (tmp->next)
1107 tmp = tmp->next;
1108 tmp->next = kbi;
1109 kbi = tmp2;
1110 }
1111 else
1112 kbi = tmp;
1113 freeReplyObject (rep_range);
1114 }
1115
1116 freeReplyObject (rep);
1117 return kbi;
1118}

References get_redis_ctx(), kb_item::next, kb_redis::rctx, redis2kbitem(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_single()

static struct kb_item * redis_get_single ( kb_t  kb,
const char *  name,
enum kb_item_type  type 
)
static

Get a single KB element.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the element to retrieve.
[in]typeDesired element type.
Returns
A struct kb_item to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 809 of file kb.c.

810{
811 struct kb_item *kbi;
812 struct kb_redis *kbr;
813 redisReply *rep;
814
815 kbr = redis_kb (kb);
816 kbi = NULL;
817
818 rep = redis_cmd (kbr, "LINDEX %s -1", name);
819 if (rep == NULL || rep->type != REDIS_REPLY_STRING)
820 {
821 kbi = NULL;
822 goto out;
823 }
824
825 kbi = redis2kbitem_single (name, rep, type == KB_TYPE_INT);
826
827out:
828 if (rep != NULL)
829 freeReplyObject (rep);
830
831 return kbi;
832}

References KB_TYPE_INT, redis2kbitem_single(), redis_cmd(), and redis_kb.

Referenced by redis_get_int(), and redis_get_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_get_str()

static char * redis_get_str ( kb_t  kb,
const char *  name 
)
static

Get a single KB string item.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the element to retrieve.
Returns
A struct kb_item to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 844 of file kb.c.

845{
846 struct kb_item *kbi;
847
849 if (kbi != NULL)
850 {
851 char *res;
852
853 res = kbi->v_str;
854 kbi->v_str = NULL;
855 kb_item_free (kbi);
856 return res;
857 }
858 return NULL;
859}

References kb_item_free(), KB_TYPE_STR, kb_item::name, redis_get_single(), and kb_item::v_str.

Here is the call graph for this function:

◆ redis_lnk_reset()

static int redis_lnk_reset ( kb_t  kb)
static

Reset connection to the KB. This is called after each fork() to make sure connections aren't shared between concurrent processes.

Parameters
[in]kbKB handle.
Returns
0 on success, non-null on error.

Definition at line 1672 of file kb.c.

1673{
1674 struct kb_redis *kbr;
1675
1676 kbr = redis_kb (kb);
1677
1678 if (kbr->rctx != NULL)
1679 {
1680 redisFree (kbr->rctx);
1681 kbr->rctx = NULL;
1682 }
1683
1684 return 0;
1685}

References kb_redis::rctx, and redis_kb.

Referenced by redis_cmd().

Here is the caller graph for this function:

◆ redis_memory_purge()

static int redis_memory_purge ( kb_t  kb)
static

Attempt to purge dirty pages.

Attempt to purge dirty pages so these can be reclaimed by the allocator. This command only works when using jemalloc as an allocator, and evaluates to a benign NOOP for all others. Command is applied to complete redis instance and not only single db.

Parameters
[in]kbKB handle where to run the command.
Returns
0 on success, non-null on error.

Definition at line 442 of file kb.c.

443{
444 redisReply *rep;
445 int rc = 0;
446
447 rep = redis_cmd (redis_kb (kb), "MEMORY PURGE");
448 if (!rep || rep->type == REDIS_REPLY_ERROR)
449 rc = -1;
450 if (rep)
451 freeReplyObject (rep);
452
453 return rc;
454}

References redis_cmd(), and redis_kb.

Referenced by redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_new()

static int redis_new ( kb_t kb,
const char *  kb_path 
)
static

Initialize a new Knowledge Base object.

Parameters
[in]kbReference to a kb_t to initialize.
[in]kb_pathPath to KB.
Returns
0 on success, -1 on connection error, -2 when no DB is available, -3 when given kb_path was NULL.

Definition at line 466 of file kb.c.

467{
468 struct kb_redis *kbr;
469 int rc = 0;
470
471 if (kb_path == NULL)
472 return -3;
473
474 kbr = g_malloc0 (sizeof (struct kb_redis));
476 kbr->path = g_strdup (kb_path);
477
478 if ((rc = get_redis_ctx (kbr)) < 0)
479 {
480 redis_delete ((kb_t) kbr);
481 return rc;
482 }
483 if (redis_test_connection (kbr))
484 {
485 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
486 "%s: cannot access redis at '%s'", __func__, kb_path);
487 redis_delete ((kb_t) kbr);
488 kbr = NULL;
489 rc = -1;
490 }
491
492 /* Ensure that the new kb is clean */
493 redis_delete_all (kbr);
494
495 *kb = (kb_t) kbr;
496
497 /* Try to make unused memory available for the OS again. */
498 if (redis_memory_purge (*kb))
499 g_warning ("%s: Memory purge was not successful", __func__);
500
501 return rc;
502}
static int redis_memory_purge(kb_t kb)
Attempt to purge dirty pages.
Definition: kb.c:442
static int redis_test_connection(struct kb_redis *kbr)
Test redis connection.
Definition: kb.c:351
static int redis_delete(kb_t kb)
Delete all entries and release ownership on the namespace.
Definition: kb.c:392
struct kb * kb_t
type abstraction to hide KB internals.
Definition: kb.h:98

References G_LOG_DOMAIN, get_redis_ctx(), kb_redis::kb, kb::kb_ops, KBRedisOperations, kb_redis::path, redis_delete(), redis_delete_all(), redis_memory_purge(), and redis_test_connection().

Here is the call graph for this function:

◆ redis_pop_str()

static char * redis_pop_str ( kb_t  kb,
const char *  name 
)
static

Pops a single KB string item.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the key from where to retrieve.
Returns
A string to be freed or NULL if list is empty or on error.

Definition at line 900 of file kb.c.

901{
902 struct kb_redis *kbr;
903 redisReply *rep;
904 char *value = NULL;
905
906 kbr = redis_kb (kb);
907 rep = redis_cmd (kbr, "RPOP %s", name);
908 if (!rep)
909 return NULL;
910
911 if (rep->type == REDIS_REPLY_STRING)
912 value = g_strdup (rep->str);
913 freeReplyObject (rep);
914
915 return value;
916}

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_push_str()

static int redis_push_str ( kb_t  kb,
const char *  name,
const char *  value 
)
static

Push a new entry under a given key.

Parameters
[in]kbKB handle where to store the item.
[in]nameKey to push to.
[in]valueValue to push.
Returns
0 on success, non-null on error.

Definition at line 871 of file kb.c.

872{
873 struct kb_redis *kbr;
874 redisReply *rep = NULL;
875 int rc = 0;
876
877 if (!value)
878 return -1;
879
880 kbr = redis_kb (kb);
881 rep = redis_cmd (kbr, "LPUSH %s %s", name, value);
882 if (!rep || rep->type == REDIS_REPLY_ERROR)
883 rc = -1;
884
885 if (rep)
886 freeReplyObject (rep);
887
888 return rc;
889}

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_release_db()

static int redis_release_db ( struct kb_redis kbr)
static

Release DB.

Parameters
[in]kbrSubclass of struct kb.
Returns
0 on success, -1 on error.

Definition at line 216 of file kb.c.

217{
218 int rc;
219 redisContext *ctx = kbr->rctx;
220 redisReply *rep;
221
222 if (ctx == NULL)
223 return -EINVAL;
224
225 rep = redisCommand (ctx, "SELECT 0"); /* Management database*/
226 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
227 {
228 rc = -1;
229 goto err_cleanup;
230 }
231 freeReplyObject (rep);
232
233 rep = redisCommand (ctx, "HDEL %s %d", GLOBAL_DBINDEX_NAME, kbr->db);
234 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER)
235 {
236 rc = -1;
237 goto err_cleanup;
238 }
239
240 rc = 0;
241
242err_cleanup:
243 if (rep != NULL)
244 freeReplyObject (rep);
245
246 return rc;
247}

References kb_redis::db, GLOBAL_DBINDEX_NAME, and kb_redis::rctx.

Referenced by redis_delete(), and redis_flush_all().

Here is the caller graph for this function:

◆ redis_save()

static int redis_save ( kb_t  kb)
static

Save all the elements from the KB.

Parameters
[in]kbKB handle.
Returns
0 on success, -1 on error.

Definition at line 1774 of file kb.c.

1775{
1776 int rc;
1777 redisReply *rep;
1778 struct kb_redis *kbr;
1779
1780 kbr = redis_kb (kb);
1781 g_debug ("%s: saving all elements from KB #%u", __func__, kbr->db);
1782 rep = redis_cmd (kbr, "SAVE");
1783 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1784 {
1785 rc = -1;
1786 goto err_cleanup;
1787 }
1788
1789 rc = 0;
1790
1791err_cleanup:
1792 if (rep != NULL)
1793 freeReplyObject (rep);
1794
1795 return rc;
1796}

References kb_redis::db, redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_set_int()

static int redis_set_int ( kb_t  kb,
const char *  name,
int  val 
)
static

Set (replace) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
Returns
0 on success, non-null on error.

Definition at line 1567 of file kb.c.

1568{
1569 struct kb_redis *kbr;
1570 redisReply *rep = NULL;
1571 redisContext *ctx;
1572 int rc = 0, i = 4;
1573
1574 kbr = redis_kb (kb);
1575 if (get_redis_ctx (redis_kb (kb)) < 0)
1576 return -1;
1577 ctx = kbr->rctx;
1578 redisAppendCommand (ctx, "MULTI");
1579 redisAppendCommand (ctx, "DEL %s", name);
1580 redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1581 redisAppendCommand (ctx, "EXEC");
1582 while (i--)
1583 {
1584 redisGetReply (ctx, (void **) &rep);
1585 if (!rep || rep->type == REDIS_REPLY_ERROR)
1586 rc = -1;
1587 if (rep)
1588 freeReplyObject (rep);
1589 }
1590
1591 return rc;
1592}

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_set_str()

static int redis_set_str ( kb_t  kb,
const char *  name,
const char *  val,
size_t  len 
)
static

Set (replace) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
[in]lenValue length. Used for blobs.
Returns
0 on success, non-null on error.

Definition at line 1408 of file kb.c.

1409{
1410 struct kb_redis *kbr;
1411 redisReply *rep = NULL;
1412 redisContext *ctx;
1413 int rc = 0, i = 4;
1414
1415 kbr = redis_kb (kb);
1416 if (get_redis_ctx (kbr) < 0)
1417 return -1;
1418 ctx = kbr->rctx;
1419 redisAppendCommand (ctx, "MULTI");
1420 redisAppendCommand (ctx, "DEL %s", name);
1421 if (len == 0)
1422 redisAppendCommand (ctx, "RPUSH %s %s", name, val);
1423 else
1424 redisAppendCommand (ctx, "RPUSH %s %b", name, val, len);
1425 redisAppendCommand (ctx, "EXEC");
1426 while (i--)
1427 {
1428 redisGetReply (ctx, (void **) &rep);
1429 if (!rep || rep->type == REDIS_REPLY_ERROR)
1430 rc = -1;
1431 if (rep)
1432 freeReplyObject (rep);
1433 }
1434
1435 return rc;
1436}

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_test_connection()

static int redis_test_connection ( struct kb_redis kbr)
static

Test redis connection.

Parameters
[in]kbrSubclass of struct kb to test.
Returns
0 on success, negative integer on error.

Definition at line 351 of file kb.c.

352{
353 int rc = 0;
354 redisReply *rep;
355
356 rep = redis_cmd (kbr, "PING");
357 if (rep == NULL)
358 {
359 /* not 100% relevant but hiredis doesn't provide us with proper error
360 * codes. */
361 rc = -ECONNREFUSED;
362 goto out;
363 }
364
365 if (rep->type != REDIS_REPLY_STATUS)
366 {
367 rc = -EINVAL;
368 goto out;
369 }
370
371 if (g_ascii_strcasecmp (rep->str, "PONG"))
372 {
373 rc = -EPROTO;
374 goto out;
375 }
376
377out:
378 if (rep != NULL)
379 freeReplyObject (rep);
380
381 return rc;
382}

References redis_cmd().

Referenced by redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_database()

static int select_database ( struct kb_redis kbr)
static

Select DB.

WARNING: do not call redis_cmd in here, since our context is not fully acquired yet!

Parameters
[in]kbrSubclass of struct kb where to save the db index.
Returns
0 on success, -1 on error.

Definition at line 164 of file kb.c.

165{
166 int rc;
167 redisContext *ctx = kbr->rctx;
168 redisReply *rep = NULL;
169
170 if (kbr->db == 0)
171 {
172 unsigned i;
173
174 if (kbr->max_db == 0)
175 fetch_max_db_index (kbr);
176
177 for (i = 1; i < kbr->max_db; i++)
178 {
179 rc = try_database_index (kbr, i);
180 if (rc == 0)
181 break;
182 }
183 }
184
185 /* No DB available, give up. */
186 if (kbr->db == 0)
187 {
188 rc = -1;
189 goto err_cleanup;
190 }
191
192 rep = redisCommand (ctx, "SELECT %u", kbr->db);
193 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
194 {
195 rc = -1;
196 goto err_cleanup;
197 }
198
199 rc = 0;
200
201err_cleanup:
202 if (rep != NULL)
203 freeReplyObject (rep);
204
205 return rc;
206}
static int try_database_index(struct kb_redis *kbr, int index)
Attempt to atomically acquire ownership of a database.
Definition: kb.c:78

References kb_redis::db, fetch_max_db_index(), kb_redis::max_db, kb_redis::rctx, and try_database_index().

Referenced by get_redis_ctx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_database_index()

static int try_database_index ( struct kb_redis kbr,
int  index 
)
static

Attempt to atomically acquire ownership of a database.

Returns
0 on success, negative integer otherwise.

Definition at line 78 of file kb.c.

79{
80 redisContext *ctx = kbr->rctx;
81 redisReply *rep;
82 int rc = 0;
83
84 rep = redisCommand (ctx, "HSETNX %s %d 1", GLOBAL_DBINDEX_NAME, index);
85 if (rep == NULL)
86 return -ENOMEM;
87
88 if (rep->type != REDIS_REPLY_INTEGER)
89 rc = -EPROTO;
90 else if (rep->integer == 0)
91 rc = -EALREADY;
92 else
93 kbr->db = index;
94
95 freeReplyObject (rep);
96
97 return rc;
98}

References kb_redis::db, GLOBAL_DBINDEX_NAME, and kb_redis::rctx.

Referenced by select_database().

Here is the caller graph for this function:

Variable Documentation

◆ KBDefaultOperations

const struct kb_operations* KBDefaultOperations = &KBRedisOperations

Default KB operations. No selection mechanism is provided yet since there's only one implementation (redis-based).

Definition at line 1877 of file kb.c.

Referenced by kb_add_int_unique_volatile(), kb_add_str_unique_volatile(), kb_direct_conn(), kb_find(), and kb_new().

◆ KBRedisOperations

static const struct kb_operations KBRedisOperations
static
Initial value:
= {
.kb_new = redis_new,
.kb_find = redis_find,
.kb_delete = redis_delete,
.kb_get_single = redis_get_single,
.kb_get_str = redis_get_str,
.kb_get_int = redis_get_int,
.kb_get_nvt = redis_get_nvt,
.kb_get_nvt_all = redis_get_nvt_all,
.kb_get_nvt_oids = redis_get_oids,
.kb_push_str = redis_push_str,
.kb_pop_str = redis_pop_str,
.kb_get_all = redis_get_all,
.kb_get_pattern = redis_get_pattern,
.kb_count = redis_count,
.kb_add_str = redis_add_str,
.kb_add_str_unique = redis_add_str_unique,
.kb_add_str_unique_volatile = redis_add_str_unique_volatile,
.kb_set_str = redis_set_str,
.kb_add_int = redis_add_int,
.kb_add_int_unique = redis_add_int_unique,
.kb_add_int_unique_volatile = redis_add_int_unique_volatile,
.kb_set_int = redis_set_int,
.kb_add_nvt = redis_add_nvt,
.kb_del_items = redis_del_items,
.kb_lnk_reset = redis_lnk_reset,
.kb_save = redis_save,
.kb_flush = redis_flush_all,
.kb_direct_conn = redis_direct_conn,
.kb_get_kb_index = redis_get_kb_index}
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:871
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:1408
static int redis_add_str_unique_volatile(kb_t kb, const char *name, const char *str, int expire, size_t len, int pos)
Insert (append) a new unique and volatile entry under a given name.
Definition: kb.c:1227
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
Definition: kb.c:953
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
Definition: kb.c:561
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:1378
static int redis_add_int_unique_volatile(kb_t kb, const char *name, int val, int expire)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1449
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
Definition: kb.c:1035
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:1543
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:513
static int redis_add_str_unique(kb_t kb, const char *name, const char *str, size_t len, int pos)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1320
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.c:844
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
Definition: kb.c:1064
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
Definition: kb.c:1128
static int redis_save(kb_t kb)
Save all the elements from the KB.
Definition: kb.c:1774
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
Definition: kb.c:927
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Definition: kb.c:900
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
Definition: kb.c:466
static int redis_get_kb_index(kb_t kb)
Return the kb index.
Definition: kb.c:420
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:1502
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
Definition: kb.c:1696
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
Definition: kb.c:1163
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:1567
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Definition: kb.c:1604
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
Definition: kb.c:985
static int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
Definition: kb.c:1195

Default KB operations.

No selection mechanism is provided yet since there's only one implementation (redis-based).

Definition at line 47 of file kb.c.

Referenced by redis_direct_conn(), redis_find(), and redis_new().