Greenbone Vulnerability Management Libraries
11.0.1
|
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))
85 redisContext *ctx = kbr->
rctx;
93 if (rep->type != REDIS_REPLY_INTEGER)
95 else if (rep->integer == 0)
100 freeReplyObject (rep);
117 redisContext *ctx = kbr->
rctx;
118 redisReply *rep = NULL;
120 rep = redisCommand (ctx,
"CONFIG GET databases");
124 "%s: redis command failed with '%s'", __func__, ctx->errstr);
129 if (rep->type != REDIS_REPLY_ARRAY)
132 "%s: cannot retrieve max DB number: %s", __func__, rep->str);
137 if (rep->elements == 2)
139 kbr->
max_db = (unsigned) atoi (rep->element[1]->str);
144 "%s: unexpected reply length (%zd)", __func__, rep->elements);
149 g_debug (
"%s: maximum DB number: %u", __func__, kbr->
max_db);
153 freeReplyObject (rep);
172 redisContext *ctx = kbr->
rctx;
173 redisReply *rep = NULL;
182 for (i = 1; i < kbr->
max_db; i++)
197 rep = redisCommand (ctx,
"SELECT %u", kbr->
db);
198 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
208 freeReplyObject (rep);
224 redisContext *ctx = kbr->
rctx;
230 rep = redisCommand (ctx,
"SELECT 0");
231 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
236 freeReplyObject (rep);
239 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER)
249 freeReplyObject (rep);
268 if (kbr->
rctx != NULL)
271 kbr->
rctx = redisConnectUnix (kbr->
path);
272 if (kbr->
rctx == NULL || kbr->
rctx->err)
275 "%s: redis connection error to %s: %s", __func__, kbr->
path,
276 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
277 redisFree (kbr->
rctx);
285 g_log (
G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"No redis DB available");
286 redisFree (kbr->
rctx);
291 g_debug (
"%s: connected to redis://%s/%d", __func__, kbr->
path, kbr->
db);
317 if (rep->type != REDIS_REPLY_STATUS)
323 if (g_ascii_strcasecmp (rep->str,
"PONG"))
331 freeReplyObject (rep);
353 if (kbr->
rctx != NULL)
355 redisFree (kbr->
rctx);
394 kbr = g_malloc0 (
sizeof (
struct kb_redis) + strlen (kb_path) + 1);
396 strcpy (kbr->
path, kb_path);
403 "%s: cannot access redis at '%s'", __func__, kb_path);
427 kbr = g_malloc0 (
sizeof (
struct kb_redis) + strlen (kb_path) + 1);
429 strcpy (kbr->
path, kb_path);
431 kbr->
rctx = redisConnectUnix (kbr->
path);
432 if (kbr->
rctx == NULL || kbr->
rctx->err)
435 "%s: redis connection error to %s: %s", __func__, kbr->
path,
436 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
437 redisFree (kbr->
rctx);
442 rep = redisCommand (kbr->
rctx,
"SELECT %d", kb_index);
443 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
446 freeReplyObject (rep);
447 redisFree (kbr->
rctx);
451 freeReplyObject (rep);
469 kbr = g_malloc0 (
sizeof (
struct kb_redis) + strlen (kb_path) + 1);
471 strcpy (kbr->
path, kb_path);
477 kbr->
rctx = redisConnectUnix (kbr->
path);
478 if (kbr->
rctx == NULL || kbr->
rctx->err)
481 "%s: redis connection error to %s: %s", __func__, kbr->
path,
482 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
483 redisFree (kbr->
rctx);
493 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
496 freeReplyObject (rep);
498 redisFree (kbr->
rctx);
502 freeReplyObject (rep);
503 rep = redisCommand (kbr->
rctx,
"SELECT %u", i);
504 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
506 redisFree (kbr->
rctx);
511 freeReplyObject (rep);
521 redisFree (kbr->
rctx);
545 g_free (item->
v_str);
566 if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
572 if (elt->type == REDIS_REPLY_INTEGER)
575 item->
v_int = elt->integer;
580 item->
v_int = atoi (elt->str);
585 item->
v_str = g_memdup (elt->str, elt->len + 1);
586 item->
len = elt->len;
615 case REDIS_REPLY_STRING:
616 case REDIS_REPLY_INTEGER:
620 case REDIS_REPLY_ARRAY:
621 for (i = 0; i < rep->elements; i++)
639 case REDIS_REPLY_NIL:
640 case REDIS_REPLY_STATUS:
641 case REDIS_REPLY_ERROR:
674 rep = redisvCommand (kbr->
rctx, fmt, aq);
680 freeReplyObject (rep);
715 rep =
redis_cmd (kbr,
"LINDEX %s -1", name);
716 if (rep == NULL || rep->type != REDIS_REPLY_STRING)
726 freeReplyObject (rep);
771 redisReply *rep = NULL;
775 rep =
redis_cmd (kbr,
"LPUSH %s %s", name, value);
776 if (!rep || rep->type == REDIS_REPLY_ERROR)
780 freeReplyObject (rep);
805 if (rep->type == REDIS_REPLY_STRING)
806 value = g_strdup (rep->str);
807 freeReplyObject (rep);
856 rep =
redis_cmd (kbr,
"LINDEX filename:%s %d", oid,
859 rep =
redis_cmd (kbr,
"LINDEX nvt:%s %d", oid, position);
862 if (rep->type == REDIS_REPLY_INTEGER)
863 res = g_strdup_printf (
"%lld", rep->integer);
864 else if (rep->type == REDIS_REPLY_STRING)
865 res = g_strdup (rep->str);
866 freeReplyObject (rep);
890 if (rep->type != REDIS_REPLY_ARRAY || rep->elements !=
NVT_NAME_POS + 1)
892 freeReplyObject (rep);
916 freeReplyObject (rep);
945 freeReplyObject (rep);
968 rep =
redis_cmd (kbr,
"KEYS %s", pattern);
971 if (rep->type != REDIS_REPLY_ARRAY)
973 freeReplyObject (rep);
979 for (i = 0; i < rep->elements; i++)
980 redisAppendCommand (kbr->
rctx,
"LRANGE %s 0 -1", rep->element[i]->str);
982 for (i = 0; i < rep->elements; i++)
985 redisReply *rep_range;
987 redisGetReply (kbr->
rctx, (
void **) &rep_range);
993 freeReplyObject (rep_range);
1009 freeReplyObject (rep_range);
1012 freeReplyObject (rep);
1028 GSList *list = NULL;
1036 if (rep->type != REDIS_REPLY_ARRAY)
1038 freeReplyObject (rep);
1043 for (i = 0; i < rep->elements; i++)
1044 list = g_slist_prepend (list, g_strdup (rep->element[i]->str + 4));
1045 freeReplyObject (rep);
1067 rep =
redis_cmd (kbr,
"KEYS %s", pattern);
1071 if (rep->type != REDIS_REPLY_ARRAY)
1073 freeReplyObject (rep);
1077 count = rep->elements;
1078 freeReplyObject (rep);
1100 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1104 freeReplyObject (rep);
1123 redisReply *rep = NULL;
1138 redisAppendCommand (ctx,
"LREM %s 1 %s", name, str);
1139 redisAppendCommand (ctx,
"RPUSH %s %s", name, str);
1140 redisGetReply (ctx, (
void **) &rep);
1141 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1142 g_debug (
"Key '%s' already contained value '%s'", name, str);
1143 freeReplyObject (rep);
1144 redisGetReply (ctx, (
void **) &rep);
1148 redisAppendCommand (ctx,
"LREM %s 1 %b", name, str, len);
1149 redisAppendCommand (ctx,
"RPUSH %s %b", name, str, len);
1150 redisGetReply (ctx, (
void **) &rep);
1151 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1152 g_debug (
"Key '%s' already contained string '%s'", name, str);
1153 freeReplyObject (rep);
1154 redisGetReply (ctx, (
void **) &rep);
1156 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1160 freeReplyObject (rep);
1184 rep =
redis_cmd (kbr,
"RPUSH %s %s", name, str);
1186 rep =
redis_cmd (kbr,
"RPUSH %s %b", name, str, len);
1187 if (!rep || rep->type == REDIS_REPLY_ERROR)
1191 freeReplyObject (rep);
1209 redisReply *rep = NULL;
1217 redisAppendCommand (ctx,
"MULTI");
1218 redisAppendCommand (ctx,
"DEL %s", name);
1220 redisAppendCommand (ctx,
"RPUSH %s %s", name, val);
1222 redisAppendCommand (ctx,
"RPUSH %s %b", name, val, len);
1223 redisAppendCommand (ctx,
"EXEC");
1226 redisGetReply (ctx, (
void **) &rep);
1227 if (!rep || rep->type == REDIS_REPLY_ERROR)
1230 freeReplyObject (rep);
1257 redisAppendCommand (ctx,
"LREM %s 1 %d", name, val);
1258 redisAppendCommand (ctx,
"RPUSH %s %d", name, val);
1259 redisGetReply (ctx, (
void **) &rep);
1260 if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1261 g_debug (
"Key '%s' already contained integer '%d'", name, val);
1262 freeReplyObject (rep);
1263 redisGetReply (ctx, (
void **) &rep);
1264 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1272 freeReplyObject (rep);
1293 if (!rep || rep->type == REDIS_REPLY_ERROR)
1296 freeReplyObject (rep);
1314 redisReply *rep = NULL;
1322 redisAppendCommand (ctx,
"MULTI");
1323 redisAppendCommand (ctx,
"DEL %s", name);
1324 redisAppendCommand (ctx,
"RPUSH %s %d", name, val);
1325 redisAppendCommand (ctx,
"EXEC");
1328 redisGetReply (ctx, (
void **) &rep);
1329 if (!rep || rep->type == REDIS_REPLY_ERROR)
1332 freeReplyObject (rep);
1351 redisReply *rep = NULL;
1354 gchar *cves, *bids, *xrefs;
1356 if (!nvt || !filename)
1361 xrefs =
nvti_refs (nvt, NULL,
"cve,bid", 1);
1365 kbr,
"RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %d %s %s",
1375 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1378 freeReplyObject (rep);
1386 rep =
redis_cmd (kbr,
"RPUSH oid:%s:prefs %d|||%s|||%s|||%s",
1389 if (!rep || rep->type == REDIS_REPLY_ERROR)
1392 freeReplyObject (rep);
1394 rep =
redis_cmd (kbr,
"RPUSH filename:%s %lu %s", filename, time (NULL),
1396 if (!rep || rep->type == REDIS_REPLY_ERROR)
1399 freeReplyObject (rep);
1418 if (kbr->
rctx != NULL)
1420 redisFree (kbr->
rctx);
1443 redisFree (kbr->
rctx);
1445 g_debug (
"%s: deleting all DBs at %s except %s", __func__, kbr->
path, except);
1450 kbr->
rctx = redisConnectUnix (kbr->
path);
1451 if (kbr->
rctx == NULL || kbr->
rctx->err)
1454 "%s: redis connection error to %s: %s", __func__, kbr->
path,
1455 kbr->
rctx ? kbr->
rctx->errstr : strerror (ENOMEM));
1456 redisFree (kbr->
rctx);
1463 if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
1465 freeReplyObject (rep);
1466 redisFree (kbr->
rctx);
1470 freeReplyObject (rep);
1471 rep = redisCommand (kbr->
rctx,
"SELECT %u", i);
1472 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1474 freeReplyObject (rep);
1475 redisFree (kbr->
rctx);
1480 freeReplyObject (rep);
1489 redisFree (kbr->
rctx);
1495 redisFree (kbr->
rctx);
1520 g_debug (
"%s: saving all elements from KB #%u", __func__, kbr->
db);
1522 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1532 freeReplyObject (rep);
1549 struct sigaction new_action, original_action;
1552 new_action.sa_flags = 0;
1553 if (sigemptyset (&new_action.sa_mask))
1555 new_action.sa_handler = SIG_IGN;
1556 if (sigaction (SIGPIPE, &new_action, &original_action))
1559 g_debug (
"%s: deleting all elements from KB #%u", __func__, kbr->
db);
1561 if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1570 if (sigaction (SIGPIPE, &original_action, NULL))
1573 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.
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.