Greenbone Vulnerability Management Libraries
11.0.0
|
Go to the documentation of this file.
31 #include <hiredis/hiredis.h>
38 #define G_LOG_DOMAIN "lib kb"
50 #define GLOBAL_DBINDEX_NAME "GVM.__GlobalDBIndex"
67 #define redis_kb(__kb) ((struct kb_redis *) (__kb))
84 redisContext *ctx = kbr->
rctx;
92 if (rep->type != REDIS_REPLY_INTEGER)
94 else if (rep->integer == 0)
99 freeReplyObject (rep);
114 redisContext *ctx = kbr->
rctx;
115 redisReply *rep = NULL;
117 rep = redisCommand (ctx,
"CONFIG GET databases");
121 "%s: redis command failed with '%s'", __func__, ctx->errstr);
126 if (rep->type != REDIS_REPLY_ARRAY)
129 "%s: cannot retrieve max DB number: %s", __func__, rep->str);
134 if (rep->elements == 2)
136 kbr->
max_db = (unsigned) atoi (rep->element[1]->str);
141 "%s: unexpected reply length (%zd)", __func__, rep->elements);
146 g_debug (
"%s: maximum DB number: %u", __func__, kbr->
max_db);
150 freeReplyObject (rep);
167 redisContext *ctx = kbr->
rctx;
168 redisReply *rep = NULL;
177 for (i = 1; i < kbr->
max_db; i++)
192 rep = redisCommand (ctx,
"SELECT %u", kbr->
db);
193 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
203 freeReplyObject (rep);
218 redisContext *ctx = kbr->
rctx;
224 rep = redisCommand (ctx,
"SELECT 0");
225 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
230 freeReplyObject (rep);
233 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER)
243 freeReplyObject (rep);
260 if (kbr->
rctx != NULL)
263 kbr->
rctx = redisConnectUnix (kbr->
path);
264 if (kbr->
rctx == NULL || kbr->
rctx->err)
267 "%s: redis connection error to %s: %s", __func__, kbr->
path,
268 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
269 redisFree (kbr->
rctx);
277 g_log (
G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"No redis DB available");
278 redisFree (kbr->
rctx);
283 g_debug (
"%s: connected to redis://%s/%d", __func__, kbr->
path, kbr->
db);
307 if (rep->type != REDIS_REPLY_STATUS)
313 if (g_ascii_strcasecmp (rep->str,
"PONG"))
321 freeReplyObject (rep);
341 if (kbr->
rctx != NULL)
343 redisFree (kbr->
rctx);
378 kbr = g_malloc0 (
sizeof (
struct kb_redis) + strlen (kb_path) + 1);
380 strcpy (kbr->
path, kb_path);
387 "%s: cannot access redis at '%s'", __func__, kb_path);
409 kbr = g_malloc0 (
sizeof (
struct kb_redis) + strlen (kb_path) + 1);
411 strcpy (kbr->
path, kb_path);
413 kbr->
rctx = redisConnectUnix (kbr->
path);
414 if (kbr->
rctx == NULL || kbr->
rctx->err)
417 "%s: redis connection error to %s: %s", __func__, kbr->
path,
418 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
419 redisFree (kbr->
rctx);
424 rep = redisCommand (kbr->
rctx,
"SELECT %d", kb_index);
425 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
428 freeReplyObject (rep);
429 redisFree (kbr->
rctx);
433 freeReplyObject (rep);
449 kbr = g_malloc0 (
sizeof (
struct kb_redis) + strlen (kb_path) + 1);
451 strcpy (kbr->
path, kb_path);
457 kbr->
rctx = redisConnectUnix (kbr->
path);
458 if (kbr->
rctx == NULL || kbr->
rctx->err)
461 "%s: redis connection error to %s: %s", __func__, kbr->
path,
462 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
463 redisFree (kbr->
rctx);
473 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
476 freeReplyObject (rep);
478 redisFree (kbr->
rctx);
482 freeReplyObject (rep);
483 rep = redisCommand (kbr->
rctx,
"SELECT %u", i);
484 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
486 redisFree (kbr->
rctx);
491 freeReplyObject (rep);
501 redisFree (kbr->
rctx);
524 g_free (item->
v_str);
543 if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
549 if (elt->type == REDIS_REPLY_INTEGER)
552 item->
v_int = elt->integer;
557 item->
v_int = atoi (elt->str);
562 item->
v_str = g_memdup (elt->str, elt->len + 1);
563 item->
len = elt->len;
590 case REDIS_REPLY_STRING:
591 case REDIS_REPLY_INTEGER:
595 case REDIS_REPLY_ARRAY:
596 for (i = 0; i < rep->elements; i++)
614 case REDIS_REPLY_NIL:
615 case REDIS_REPLY_STATUS:
616 case REDIS_REPLY_ERROR:
647 rep = redisvCommand (kbr->
rctx, fmt, aq);
653 freeReplyObject (rep);
686 rep =
redis_cmd (kbr,
"LINDEX %s -1", name);
687 if (rep == NULL || rep->type != REDIS_REPLY_STRING)
697 freeReplyObject (rep);
738 redisReply *rep = NULL;
742 rep =
redis_cmd (kbr,
"LPUSH %s %s", name, value);
743 if (!rep || rep->type == REDIS_REPLY_ERROR)
747 freeReplyObject (rep);
770 if (rep->type == REDIS_REPLY_STRING)
771 value = g_strdup (rep->str);
772 freeReplyObject (rep);
817 rep =
redis_cmd (kbr,
"LINDEX filename:%s %d", oid,
820 rep =
redis_cmd (kbr,
"LINDEX nvt:%s %d", oid, position);
823 if (rep->type == REDIS_REPLY_INTEGER)
824 res = g_strdup_printf (
"%lld", rep->integer);
825 else if (rep->type == REDIS_REPLY_STRING)
826 res = g_strdup (rep->str);
827 freeReplyObject (rep);
849 if (rep->type != REDIS_REPLY_ARRAY || rep->elements !=
NVT_NAME_POS + 1)
851 freeReplyObject (rep);
875 freeReplyObject (rep);
902 freeReplyObject (rep);
923 rep =
redis_cmd (kbr,
"KEYS %s", pattern);
926 if (rep->type != REDIS_REPLY_ARRAY)
928 freeReplyObject (rep);
934 for (i = 0; i < rep->elements; i++)
935 redisAppendCommand (kbr->
rctx,
"LRANGE %s 0 -1", rep->element[i]->str);
937 for (i = 0; i < rep->elements; i++)
940 redisReply *rep_range;
942 redisGetReply (kbr->
rctx, (
void **) &rep_range);
948 freeReplyObject (rep_range);
964 freeReplyObject (rep_range);
967 freeReplyObject (rep);
989 if (rep->type != REDIS_REPLY_ARRAY)
991 freeReplyObject (rep);
996 for (i = 0; i < rep->elements; i++)
997 list = g_slist_prepend (list, g_strdup (rep->element[i]->str + 4));
998 freeReplyObject (rep);
1020 rep =
redis_cmd (kbr,
"KEYS %s", pattern);
1024 if (rep->type != REDIS_REPLY_ARRAY)
1026 freeReplyObject (rep);
1030 count = rep->elements;
1031 freeReplyObject (rep);
1051 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1055 freeReplyObject (rep);
1072 redisReply *rep = NULL;
1087 redisAppendCommand (ctx,
"LREM %s 1 %s", name, str);
1088 redisAppendCommand (ctx,
"RPUSH %s %s", name, str);
1089 redisGetReply (ctx, (
void **) &rep);
1090 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1091 g_debug (
"Key '%s' already contained value '%s'", name, str);
1092 freeReplyObject (rep);
1093 redisGetReply (ctx, (
void **) &rep);
1097 redisAppendCommand (ctx,
"LREM %s 1 %b", name, str, len);
1098 redisAppendCommand (ctx,
"RPUSH %s %b", name, str, len);
1099 redisGetReply (ctx, (
void **) &rep);
1100 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1101 g_debug (
"Key '%s' already contained string '%s'", name, str);
1102 freeReplyObject (rep);
1103 redisGetReply (ctx, (
void **) &rep);
1105 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1109 freeReplyObject (rep);
1131 rep =
redis_cmd (kbr,
"RPUSH %s %s", name, str);
1133 rep =
redis_cmd (kbr,
"RPUSH %s %b", name, str, len);
1134 if (!rep || rep->type == REDIS_REPLY_ERROR)
1138 freeReplyObject (rep);
1154 redisReply *rep = NULL;
1162 redisAppendCommand (ctx,
"MULTI");
1163 redisAppendCommand (ctx,
"DEL %s", name);
1165 redisAppendCommand (ctx,
"RPUSH %s %s", name, val);
1167 redisAppendCommand (ctx,
"RPUSH %s %b", name, val, len);
1168 redisAppendCommand (ctx,
"EXEC");
1171 redisGetReply (ctx, (
void **) &rep);
1172 if (!rep || rep->type == REDIS_REPLY_ERROR)
1175 freeReplyObject (rep);
1200 redisAppendCommand (ctx,
"LREM %s 1 %d", name, val);
1201 redisAppendCommand (ctx,
"RPUSH %s %d", name, val);
1202 redisGetReply (ctx, (
void **) &rep);
1203 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1204 g_debug (
"Key '%s' already contained integer '%d'", name, val);
1205 freeReplyObject (rep);
1206 redisGetReply (ctx, (
void **) &rep);
1207 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1215 freeReplyObject (rep);
1234 if (!rep || rep->type == REDIS_REPLY_ERROR)
1237 freeReplyObject (rep);
1253 redisReply *rep = NULL;
1261 redisAppendCommand (ctx,
"MULTI");
1262 redisAppendCommand (ctx,
"DEL %s", name);
1263 redisAppendCommand (ctx,
"RPUSH %s %d", name, val);
1264 redisAppendCommand (ctx,
"EXEC");
1267 redisGetReply (ctx, (
void **) &rep);
1268 if (!rep || rep->type == REDIS_REPLY_ERROR)
1271 freeReplyObject (rep);
1288 redisReply *rep = NULL;
1291 gchar *cves, *bids, *xrefs;
1293 if (!nvt || !filename)
1298 xrefs =
nvti_refs (nvt, NULL,
"cve,bid", 1);
1302 kbr,
"RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %d %s %s",
1312 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1315 freeReplyObject (rep);
1323 rep =
redis_cmd (kbr,
"RPUSH oid:%s:prefs %d|||%s|||%s|||%s",
1326 if (!rep || rep->type == REDIS_REPLY_ERROR)
1329 freeReplyObject (rep);
1331 rep =
redis_cmd (kbr,
"RPUSH filename:%s %lu %s", filename, time (NULL),
1333 if (!rep || rep->type == REDIS_REPLY_ERROR)
1336 freeReplyObject (rep);
1353 if (kbr->
rctx != NULL)
1355 redisFree (kbr->
rctx);
1376 redisFree (kbr->
rctx);
1378 g_debug (
"%s: deleting all DBs at %s except %s", __func__, kbr->
path, except);
1383 kbr->
rctx = redisConnectUnix (kbr->
path);
1384 if (kbr->
rctx == NULL || kbr->
rctx->err)
1387 "%s: redis connection error to %s: %s", __func__, kbr->
path,
1388 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
1389 redisFree (kbr->
rctx);
1396 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
1398 freeReplyObject (rep);
1399 redisFree (kbr->
rctx);
1403 freeReplyObject (rep);
1404 rep = redisCommand (kbr->
rctx,
"SELECT %u", i);
1405 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1407 freeReplyObject (rep);
1408 redisFree (kbr->
rctx);
1413 freeReplyObject (rep);
1422 redisFree (kbr->
rctx);
1428 redisFree (kbr->
rctx);
1451 g_debug (
"%s: saving all elements from KB #%u", __func__, kbr->
db);
1453 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1463 freeReplyObject (rep);
1478 struct sigaction new_action, original_action;
1481 new_action.sa_flags = 0;
1482 if (sigemptyset (&new_action.sa_mask))
1484 new_action.sa_handler = SIG_IGN;
1485 if (sigaction (SIGPIPE, &new_action, &original_action))
1488 g_debug (
"%s: deleting all elements from KB #%u", __func__, kbr->
db);
1490 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1499 if (sigaction (SIGPIPE, &original_action, NULL))
1502 freeReplyObject (rep);
const nvtpref_t * nvti_pref(const nvti_t *n, guint p)
Get the n'th preferences of the NVT.
int nvti_set_required_udp_ports(nvti_t *n, const gchar *required_udp_ports)
Set the required udp ports of a NVT.
Knowledge base management API - Redis backend.
static char * kb_item_get_str(kb_t kb, const char *name)
Get a single KB string item.
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
static redisReply * redis_cmd(struct kb_redis *kbr, const char *fmt,...)
Execute a redis command and get a redis reply.
int nvti_set_required_keys(nvti_t *n, const gchar *required_keys)
Set the required keys of a NVT.
gchar * nvti_family(const nvti_t *n)
Get the family name.
int redis_save(kb_t kb)
Save all the elements from the KB.
KB interface. Functions provided by an implementation. All functions have to be provided,...
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
static int redis_push_str(kb_t kb, const char *name, const char *value)
Push a new entry under a given key.
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 int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
static struct kb_item * redis2kbitem_single(const char *name, const redisReply *elt, int force_int)
Give a single KB item.
const struct kb_operations * KBDefaultOperations
Default KB operations. No selection mechanism is provided yet since there's only one implementation (...
static int try_database_index(struct kb_redis *kbr, int index)
Attempt to atomically acquire ownership of a database.
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.
int nvtpref_id(const nvtpref_t *np)
Get the ID of a NVT Preference.
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
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...
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
gchar * nvti_refs(const nvti_t *n, const gchar *type, const gchar *exclude_types, guint use_types)
Get references as string.
gchar * nvti_required_udp_ports(const nvti_t *n)
Get the required udp ports list.
The structure of a information record that corresponds to a NVT.
gchar * nvti_required_ports(const nvti_t *n)
Get the required ports list.
@ NVT_REQUIRED_UDP_PORTS_POS
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
int nvti_set_excluded_keys(nvti_t *n, const gchar *excluded_keys)
Set the excluded keys of a NVT.
static int redis_get_kb_index(kb_t kb)
Return the kb index.
void kb_item_free(struct kb_item *item)
Release a KB item (or a list).
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
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.
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.
The structure for a preference of a NVT.
static int get_redis_ctx(struct kb_redis *kbr)
Get redis context if it is already connected or do a a connection.
int nvti_set_timeout(nvti_t *n, const gint timeout)
Set the timeout of a NVT Info.
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.
guint nvti_pref_len(const nvti_t *n)
Get the number of preferences of the NVT.
static int redis_release_db(struct kb_redis *kbr)
Release DB.
const struct kb_operations * kb_ops
int nvti_set_dependencies(nvti_t *n, const gchar *dependencies)
Set the dependencies of a NVT.
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Subclass of struct kb, it contains the redis-specific fields, such as the redis context,...
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
static int redis_delete(kb_t kb)
Delete all entries and release ownership on the namespace.
gchar * nvti_tag(const nvti_t *n)
Get the tags.
int nvti_set_tag(nvti_t *n, const gchar *tag)
Set the tags of a NVT.
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Top-level KB. This is to be inherited by KB implementations.
gchar * nvtpref_name(const nvtpref_t *np)
Get the Name of a NVT Preference.
gchar * nvti_mandatory_keys(const nvti_t *n)
Get the mandatory keys list.
gint nvti_timeout(const nvti_t *n)
Get the timeout for this NVT.
gchar * nvti_dependencies(const nvti_t *n)
Get the dependencies list.
static struct kb_item * redis2kbitem(const char *name, const redisReply *rep)
Fetch a KB item or list from a redis Reply.
gchar * nvti_name(const nvti_t *n)
Get the name.
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
static int select_database(struct kb_redis *kbr)
Select DB.
static const struct kb_operations KBRedisOperations
Default KB operations. No selection mechanism is provided yet since there's only one implementation (...
kb_item_type
Possible type of a kb_item.
int(* kb_new)(kb_t *, const char *)
static struct kb_item * redis_get_single(kb_t kb, const char *name, enum kb_item_type type)
Get a single KB element.
gchar * nvti_excluded_keys(const nvti_t *n)
Get the excluded keys list.
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
static int redis_add_int_unique(kb_t kb, const char *name, int val)
Insert (append) a new unique entry under a given name.
int nvti_set_required_ports(nvti_t *n, const gchar *required_ports)
Set the required ports of a NVT.
gchar * nvtpref_default(const nvtpref_t *np)
Get the Default of a NVT Preference.
#define GLOBAL_DBINDEX_NAME
Name of the namespace usage bitmap in redis.
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
gchar * nvtpref_type(const nvtpref_t *np)
Get the Type of a NVT Preference.
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
struct kb * kb_t
type abstraction to hide KB internals.
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
static int redis_test_connection(struct kb_redis *kbr)
Test redis connection.
static int fetch_max_db_index(struct kb_redis *kbr)
Set the number of databases have been configured into kbr struct.
int nvti_set_mandatory_keys(nvti_t *n, const gchar *mandatory_keys)
Set the mandatory keys of a NVT.
static int redis_add_int(kb_t kb, const char *name, int val)
Insert (append) a new entry under a given name.
kb_nvt_pos
Possible positions of nvt values in cache list.
static int redis_set_int(kb_t kb, const char *name, int val)
Set (replace) a new entry under a given name.
gchar * nvti_required_keys(const nvti_t *n)
Get the required keys list.