1 /* Copyright (C) 2014-2021 Greenbone Networks GmbH
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 /**
21 * @file
22 * @brief Knowledge base management API - Redis backend.
23 */
24
25 #ifndef _GVM_KB_H
26 #define _GVM_KB_H
27
28 #include "../base/nvti.h" /* for nvti_t */
29
30 #include <assert.h>
31 #include <stddef.h> /* for NULL */
32 #include <sys/types.h> /* for size_t */
33
34 /**
35 * @brief Default KB location.
36 */
37 #ifdef REDIS_SOCKET_PATH
38 #define KB_PATH_DEFAULT REDIS_SOCKET_PATH
39 #else
40 #define KB_PATH_DEFAULT "/run/redis/redis.sock"
41 #endif
42
43 /**
44 * @brief Possible type of a kb_item.
45 */
46 enum kb_item_type
47 {
48 KB_TYPE_UNSPEC, /**< Ignore the value (name/presence test). */
49 KB_TYPE_INT, /**< The kb_items v should then be interpreted as int. */
50 KB_TYPE_STR, /**< The kb_items v should then be interpreted as char*. */
51 /* -- */
52 KB_TYPE_CNT,
53 };
54
55 /**
56 * @brief Possible positions of nvt values in cache list.
57 */
58 enum kb_nvt_pos
59 {
60 NVT_FILENAME_POS,
61 NVT_REQUIRED_KEYS_POS,
62 NVT_MANDATORY_KEYS_POS,
63 NVT_EXCLUDED_KEYS_POS,
64 NVT_REQUIRED_UDP_PORTS_POS,
65 NVT_REQUIRED_PORTS_POS,
66 NVT_DEPENDENCIES_POS,
67 NVT_TAGS_POS,
68 NVT_CVES_POS,
69 NVT_BIDS_POS,
70 NVT_XREFS_POS,
71 NVT_CATEGORY_POS,
72 NVT_TIMEOUT_POS,
73 NVT_FAMILY_POS,
74 NVT_NAME_POS,
75 NVT_TIMESTAMP_POS,
76 NVT_OID_POS,
77 };
78
79 /**
80 * @brief Knowledge base item (defined by name, type (int/char*) and value).
81 * Implemented as a singly linked list
82 */
83 struct kb_item
84 {
85 enum kb_item_type type; /**< One of KB_TYPE_INT or KB_TYPE_STR. */
86
87 union /**< Store a char or an int. */
88 {
89 char *v_str; /**< Hold an str value for this kb item. */
90 int v_int; /**< Hold an int value for this kb item. */
91 }; /**< Value of this knowledge base item. */
92
93 size_t len; /**< Length of string. */
94 struct kb_item *next; /**< Next item in list. */
95
96 size_t namelen; /**< Name length (including final NULL byte). */
97 char name[0]; /**< Name of this knowledge base item. */
98 };
99
100 struct kb_operations;
101
102 /**
103 * @brief Top-level KB. This is to be inherited by KB implementations.
104 */
105 struct kb
106 {
107 const struct kb_operations *kb_ops; /**< KB vtable. */
108 };
109
110 /**
111 * @brief type abstraction to hide KB internals.
112 */
113 typedef struct kb *kb_t;
114
115 /**
116 * @brief KB interface. Functions provided by an implementation. All functions
117 * have to be provided, there is no default/fallback. These functions
118 * should be called via the corresponding static inline wrappers below.
119 * See the wrappers for the documentation.
120 */
121 struct kb_operations
122 {
123 /* ctor/dtor */
124 int (*kb_new) (kb_t *, const char *); /**< New KB. */
125 int (*kb_delete) (kb_t); /**< Delete KB. */
126 kb_t (*kb_find) (const char *, const char *); /**< Find KB. */
127 kb_t (*kb_direct_conn) (const char *, const int); /**< Connect to a KB. */
128
129 /* Actual kb operations */
130 /**
131 * Function provided by an implementation to get a single kb element.
132 */
133 struct kb_item *(*kb_get_single) (kb_t, const char *, enum kb_item_type);
134 /**
135 * Function provided by an implementation to get single kb str item.
136 */
137 char *(*kb_get_str) (kb_t, const char *);
138 /**
139 * Function provided by an implementation to get single kb int item.
140 */
141 int (*kb_get_int) (kb_t, const char *);
142 /**
143 * Function provided by an implementation to get field of NVT.
144 */
145 char *(*kb_get_nvt) (kb_t, const char *, enum kb_nvt_pos);
146 /**
147 * Function provided by an implementation to get a full NVT.
148 */
149 nvti_t *(*kb_get_nvt_all) (kb_t, const char *);
150 /**
151 * Function provided by an implementation to get list of OIDs.
152 */
153 GSList *(*kb_get_nvt_oids) (kb_t);
154 /**
155 * Function provided by an implementation to push a new value under a key.
156 */
157 int (*kb_push_str) (kb_t, const char *, const char *);
158 /**
159 * Function provided by an implementation to pop a str under a key.
160 */
161 char *(*kb_pop_str) (kb_t, const char *);
162 /**
163 * Function provided by an implementation to get all items stored
164 * under a given name.
165 */
166 struct kb_item *(*kb_get_all) (kb_t, const char *);
167 /**
168 * Function provided by an implementation to get all items stored
169 * under a given pattern.
170 */
171 struct kb_item *(*kb_get_pattern) (kb_t, const char *);
172 /**
173 * Function provided by an implementation to count all items stored
174 * under a given pattern.
175 */
176 size_t (*kb_count) (kb_t, const char *);
177 /**
178 * Function provided by an implementation to insert (append) a new entry
179 * under a given name.
180 */
181 int (*kb_add_str) (kb_t, const char *, const char *, size_t);
182 /**
183 * Function provided by an implementation to insert (append) a new
184 * unique entry under a given name.
185 */
186 int (*kb_add_str_unique) (kb_t, const char *, const char *, size_t, int);
187 /**
188 * Function provided by an implementation to get (replace) a new entry
189 * under a given name.
190 */
191 int (*kb_set_str) (kb_t, const char *, const char *, size_t);
192 /**
193 * Function provided by an implementation to insert (append) a new entry
194 * under a given name.
195 */
196 int (*kb_add_int) (kb_t, const char *, int);
197 /**
198 * Function provided by an implementation to insert (append) a new
199 * unique entry under a given name.
200 */
201 int (*kb_add_int_unique) (kb_t, const char *, int);
202 /**
203 * Function provided by an implementation to get (replace) a new entry
204 * under a given name.
205 */
206 int (*kb_set_int) (kb_t, const char *, int);
207 /**
208 * Function provided by an implementation to
209 * insert a new nvt.
210 */
211 int (*kb_add_nvt) (kb_t, const nvti_t *, const char *);
212 /**
213 * Function provided by an implementation to delete all entries
214 * under a given name.
215 */
216 int (*kb_del_items) (kb_t, const char *);
217
218 /* Utils */
219 int (*kb_save) (kb_t); /**< Save all kb content. */
220 int (*kb_lnk_reset) (kb_t); /**< Reset connection to KB. */
221 int (*kb_flush) (kb_t, const char *); /**< Flush redis DB. */
222 int (*kb_get_kb_index) (kb_t); /**< Get kb index. */
223 };
224
225 /**
226 * @brief Default KB operations.
227 * No selection mechanism is provided yet since there's only one
228 * implementation (redis-based).
229 */
230 extern const struct kb_operations *KBDefaultOperations;
231
232 /**
233 * @brief Release a KB item (or a list).
234 */
235 void
236 kb_item_free (struct kb_item *);
237
238 /**
239 * @brief Initialize a new Knowledge Base object.
240 * @param[in] kb Reference to a kb_t to initialize.
241 * @param[in] kb_path Path to KB.
242 * @return 0 on success, -1 on connection error, -2 on unavailable DB spot.
243 */
244 static inline int
kb_new(kb_t * kb,const char * kb_path)245 kb_new (kb_t *kb, const char *kb_path)
246 {
247 assert (kb);
248 assert (KBDefaultOperations);
249 assert (KBDefaultOperations->kb_new);
250
251 *kb = NULL;
252
253 return KBDefaultOperations->kb_new (kb, kb_path);
254 }
255
256 /**
257 * @brief Connect to a Knowledge Base object which has the given kb_index.
258 * @param[in] kb_path Path to KB.
259 * @param[in] kb_index DB index
260 * @return Knowledge Base object, NULL otherwise.
261 */
262 static inline kb_t
kb_direct_conn(const char * kb_path,const int kb_index)263 kb_direct_conn (const char *kb_path, const int kb_index)
264 {
265 assert (KBDefaultOperations);
266 assert (KBDefaultOperations->kb_direct_conn);
267
268 return KBDefaultOperations->kb_direct_conn (kb_path, kb_index);
269 }
270
271 /**
272 * @brief Find an existing Knowledge Base object with key.
273 * @param[in] kb_path Path to KB.
274 * @param[in] key Marker key to search for in KB objects.
275 * @return Knowledge Base object, NULL otherwise.
276 */
277 static inline kb_t
kb_find(const char * kb_path,const char * key)278 kb_find (const char *kb_path, const char *key)
279 {
280 assert (KBDefaultOperations);
281 assert (KBDefaultOperations->kb_find);
282
283 return KBDefaultOperations->kb_find (kb_path, key);
284 }
285
286 /**
287 * @brief Delete all entries and release ownership on the namespace.
288 * @param[in] kb KB handle to release.
289 * @return 0 on success, non-null on error.
290 */
291 static inline int
kb_delete(kb_t kb)292 kb_delete (kb_t kb)
293 {
294 assert (kb);
295 assert (kb->kb_ops);
296 assert (kb->kb_ops->kb_delete);
297
298 return kb->kb_ops->kb_delete (kb);
299 }
300
301 /**
302 * @brief Get a single KB element.
303 * @param[in] kb KB handle where to fetch the item.
304 * @param[in] name Name of the element to retrieve.
305 * @param[in] type Desired element type.
306 * @return A struct kb_item to be freed with kb_item_free() or NULL if no
307 * element was found or on error.
308 */
309 static inline struct kb_item *
kb_item_get_single(kb_t kb,const char * name,enum kb_item_type type)310 kb_item_get_single (kb_t kb, const char *name, enum kb_item_type type)
311 {
312 assert (kb);
313 assert (kb->kb_ops);
314 assert (kb->kb_ops->kb_get_single);
315
316 return kb->kb_ops->kb_get_single (kb, name, type);
317 }
318
319 /**
320 * @brief Get a single KB string item.
321 * @param[in] kb KB handle where to fetch the item.
322 * @param[in] name Name of the element to retrieve.
323 * @return A string to be freed or NULL if list is empty or on error.
324 */
325 static inline char *
kb_item_get_str(kb_t kb,const char * name)326 kb_item_get_str (kb_t kb, const char *name)
327 {
328 assert (kb);
329 assert (kb->kb_ops);
330 assert (kb->kb_ops->kb_get_str);
331
332 return kb->kb_ops->kb_get_str (kb, name);
333 }
334
335 /**
336 * @brief Get a single KB integer item.
337 * @param[in] kb KB handle where to fetch the item.
338 * @param[in] name Name of the element to retrieve.
339 * @return An integer.
340 */
341 static inline int
kb_item_get_int(kb_t kb,const char * name)342 kb_item_get_int (kb_t kb, const char *name)
343 {
344 assert (kb);
345 assert (kb->kb_ops);
346 assert (kb->kb_ops->kb_get_int);
347
348 return kb->kb_ops->kb_get_int (kb, name);
349 }
350
351 /**
352 * @brief Get all items stored under a given name.
353 * @param[in] kb KB handle where to fetch the items.
354 * @param[in] name Name of the elements to retrieve.
355 * @return Linked struct kb_item instances to be freed with kb_item_free() or
356 * NULL if no element was found or on error.
357 */
358 static inline struct kb_item *
kb_item_get_all(kb_t kb,const char * name)359 kb_item_get_all (kb_t kb, const char *name)
360 {
361 assert (kb);
362 assert (kb->kb_ops);
363 assert (kb->kb_ops->kb_get_all);
364
365 return kb->kb_ops->kb_get_all (kb, name);
366 }
367
368 /**
369 * @brief Get all items stored under a given pattern.
370 * @param[in] kb KB handle where to fetch the items.
371 * @param[in] pattern '*' pattern of the elements to retrieve.
372 * @return Linked struct kb_item instances to be freed with kb_item_free() or
373 * NULL if no element was found or on error.
374 */
375 static inline struct kb_item *
kb_item_get_pattern(kb_t kb,const char * pattern)376 kb_item_get_pattern (kb_t kb, const char *pattern)
377 {
378 assert (kb);
379 assert (kb->kb_ops);
380 assert (kb->kb_ops->kb_get_pattern);
381
382 return kb->kb_ops->kb_get_pattern (kb, pattern);
383 }
384
385 /**
386 * @brief Push a new value under a given key.
387 * @param[in] kb KB handle where to store the item.
388 * @param[in] name Key to push to.
389 * @param[in] value Value to push.
390 * @return 0 on success, non-null on error.
391 */
392 static inline int
kb_item_push_str(kb_t kb,const char * name,const char * value)393 kb_item_push_str (kb_t kb, const char *name, const char *value)
394 {
395 assert (kb);
396 assert (kb->kb_ops);
397 assert (kb->kb_ops->kb_push_str);
398
399 return kb->kb_ops->kb_push_str (kb, name, value);
400 }
401
402 /**
403 * @brief Pop a single KB string item.
404 * @param[in] kb KB handle where to fetch the item.
405 * @param[in] name Name of the element to retrieve.
406 * @return A struct kb_item to be freed with kb_item_free() or NULL if no
407 * element was found or on error.
408 */
409 static inline char *
kb_item_pop_str(kb_t kb,const char * name)410 kb_item_pop_str (kb_t kb, const char *name)
411 {
412 assert (kb);
413 assert (kb->kb_ops);
414 assert (kb->kb_ops->kb_pop_str);
415
416 return kb->kb_ops->kb_pop_str (kb, name);
417 }
418
419 /**
420 * @brief Count all items stored under a given pattern.
421 *
422 * @param[in] kb KB handle where to count the items.
423 * @param[in] pattern '*' pattern of the elements to count.
424 *
425 * @return Count of items.
426 */
427 static inline size_t
kb_item_count(kb_t kb,const char * pattern)428 kb_item_count (kb_t kb, const char *pattern)
429 {
430 assert (kb);
431 assert (kb->kb_ops);
432 assert (kb->kb_ops->kb_count);
433
434 return kb->kb_ops->kb_count (kb, pattern);
435 }
436
437 /**
438 * @brief Insert (append) a new entry under a given name.
439 * @param[in] kb KB handle where to store the item.
440 * @param[in] name Item name.
441 * @param[in] str Item value.
442 * @param[in] len Value length. Used for blobs.
443 * @return 0 on success, non-null on error.
444 */
445 static inline int
kb_item_add_str(kb_t kb,const char * name,const char * str,size_t len)446 kb_item_add_str (kb_t kb, const char *name, const char *str, size_t len)
447 {
448 assert (kb);
449 assert (kb->kb_ops);
450 assert (kb->kb_ops->kb_add_str);
451
452 return kb->kb_ops->kb_add_str (kb, name, str, len);
453 }
454
455 /**
456 * @brief Insert (append) a new unique entry under a given name.
457 * @param[in] kb KB handle where to store the item.
458 * @param[in] name Item name.
459 * @param[in] str Item value.
460 * @param[in] len Value length. Used for blobs.
461 * @param[in] pos Which position the value is appended to. 0 for right,
462 * 1 for left position in the list.
463 * @return 0 on success, non-null on error.
464 */
465 static inline int
kb_item_add_str_unique(kb_t kb,const char * name,const char * str,size_t len,int pos)466 kb_item_add_str_unique (kb_t kb, const char *name, const char *str, size_t len,
467 int pos)
468 {
469 assert (kb);
470 assert (kb->kb_ops);
471 assert (kb->kb_ops->kb_add_str_unique);
472
473 return kb->kb_ops->kb_add_str_unique (kb, name, str, len, pos);
474 }
475
476 /**
477 * @brief Set (replace) a new entry under a given name.
478 * @param[in] kb KB handle where to store the item.
479 * @param[in] name Item name.
480 * @param[in] str Item value.
481 * @param[in] len Value length. Used for blobs.
482 * @return 0 on success, non-null on error.
483 */
484 static inline int
kb_item_set_str(kb_t kb,const char * name,const char * str,size_t len)485 kb_item_set_str (kb_t kb, const char *name, const char *str, size_t len)
486 {
487 assert (kb);
488 assert (kb->kb_ops);
489 assert (kb->kb_ops->kb_set_str);
490
491 return kb->kb_ops->kb_set_str (kb, name, str, len);
492 }
493
494 /**
495 * @brief Insert (append) a new entry under a given name.
496 * @param[in] kb KB handle where to store the item.
497 * @param[in] name Item name.
498 * @param[in] val Item value.
499 * @return 0 on success, non-null on error.
500 */
501 static inline int
kb_item_add_int(kb_t kb,const char * name,int val)502 kb_item_add_int (kb_t kb, const char *name, int val)
503 {
504 assert (kb);
505 assert (kb->kb_ops);
506 assert (kb->kb_ops->kb_add_int);
507
508 return kb->kb_ops->kb_add_int (kb, name, val);
509 }
510
511 /**
512 * @brief Insert (append) a new unique entry under a given name.
513 * @param[in] kb KB handle where to store the item.
514 * @param[in] name Item name.
515 * @param[in] val Item value.
516 * @return 0 on success, non-null on error.
517 */
518 static inline int
kb_item_add_int_unique(kb_t kb,const char * name,int val)519 kb_item_add_int_unique (kb_t kb, const char *name, int val)
520 {
521 assert (kb);
522 assert (kb->kb_ops);
523 assert (kb->kb_ops->kb_add_int_unique);
524
525 return kb->kb_ops->kb_add_int_unique (kb, name, val);
526 }
527
528 /**
529 * @brief Set (replace) a new entry under a given name.
530 * @param[in] kb KB handle where to store the item.
531 * @param[in] name Item name.
532 * @param[in] val Item value.
533 * @return 0 on success, non-null on error.
534 */
535 static inline int
kb_item_set_int(kb_t kb,const char * name,int val)536 kb_item_set_int (kb_t kb, const char *name, int val)
537 {
538 assert (kb);
539 assert (kb->kb_ops);
540 assert (kb->kb_ops->kb_set_int);
541
542 return kb->kb_ops->kb_set_int (kb, name, val);
543 }
544
545 /**
546 * @brief Insert a new nvt.
547 * @param[in] kb KB handle where to store the nvt.
548 * @param[in] nvt nvt to store.
549 * @param[in] filename Path to nvt to store.
550 * @return 0 on success, non-null on error.
551 */
552 static inline int
kb_nvt_add(kb_t kb,const nvti_t * nvt,const char * filename)553 kb_nvt_add (kb_t kb, const nvti_t *nvt, const char *filename)
554 {
555 assert (kb);
556 assert (kb->kb_ops);
557 assert (kb->kb_ops->kb_add_nvt);
558
559 return kb->kb_ops->kb_add_nvt (kb, nvt, filename);
560 }
561
562 /**
563 * @brief Get field of a NVT.
564 * @param[in] kb KB handle where to store the nvt.
565 * @param[in] oid OID of NVT to get from.
566 * @param[in] position Position of field to get.
567 * @return Value of field, NULL otherwise.
568 */
569 static inline char *
kb_nvt_get(kb_t kb,const char * oid,enum kb_nvt_pos position)570 kb_nvt_get (kb_t kb, const char *oid, enum kb_nvt_pos position)
571 {
572 assert (kb);
573 assert (kb->kb_ops);
574 assert (kb->kb_ops->kb_get_nvt);
575
576 return kb->kb_ops->kb_get_nvt (kb, oid, position);
577 }
578
579 /**
580 * @brief Get a full NVT.
581 * @param[in] kb KB handle where to store the nvt.
582 * @param[in] oid OID of NVT to get.
583 * @return nvti_t of NVT, NULL otherwise.
584 */
585 static inline nvti_t *
kb_nvt_get_all(kb_t kb,const char * oid)586 kb_nvt_get_all (kb_t kb, const char *oid)
587 {
588 assert (kb);
589 assert (kb->kb_ops);
590 assert (kb->kb_ops->kb_get_nvt_all);
591
592 return kb->kb_ops->kb_get_nvt_all (kb, oid);
593 }
594
595 /**
596 * @brief Get list of NVT OIDs.
597 * @param[in] kb KB handle where NVTs are stored.
598 * @return Linked-list of OIDs, NULL otherwise.
599 */
600 static inline GSList *
kb_nvt_get_oids(kb_t kb)601 kb_nvt_get_oids (kb_t kb)
602 {
603 assert (kb);
604 assert (kb->kb_ops);
605 assert (kb->kb_ops->kb_get_nvt_oids);
606
607 return kb->kb_ops->kb_get_nvt_oids (kb);
608 }
609
610 /**
611 * @brief Delete all entries under a given name.
612 * @param[in] kb KB handle where to store the item.
613 * @param[in] name Item name.
614 * @return 0 on success, non-null on error.
615 */
616 static inline int
kb_del_items(kb_t kb,const char * name)617 kb_del_items (kb_t kb, const char *name)
618 {
619 assert (kb);
620 assert (kb->kb_ops);
621 assert (kb->kb_ops->kb_del_items);
622
623 return kb->kb_ops->kb_del_items (kb, name);
624 }
625
626 /**
627 * @brief Save all the KB's content.
628 * @param[in] kb KB handle.
629 * @return 0 on success, non-null on error.
630 */
631 static inline int
kb_save(kb_t kb)632 kb_save (kb_t kb)
633 {
634 int rc = 0;
635
636 assert (kb);
637 assert (kb->kb_ops);
638
639 if (kb->kb_ops->kb_save != NULL)
640 rc = kb->kb_ops->kb_save (kb);
641
642 return rc;
643 }
644
645 /**
646 * @brief Reset connection to the KB. This is called after each fork() to make
647 * sure connections aren't shared between concurrent processes.
648 * @param[in] kb KB handle.
649 * @return 0 on success, non-null on error.
650 */
651 static inline int
kb_lnk_reset(kb_t kb)652 kb_lnk_reset (kb_t kb)
653 {
654 int rc = 0;
655
656 assert (kb);
657 assert (kb->kb_ops);
658
659 if (kb->kb_ops->kb_lnk_reset != NULL)
660 rc = kb->kb_ops->kb_lnk_reset (kb);
661
662 return rc;
663 }
664
665 /**
666 * @brief Flush all the KB's content. Delete all namespaces.
667 * @param[in] kb KB handle.
668 * @param[in] except Don't flush DB with except key.
669 * @return 0 on success, non-null on error.
670 */
671 static inline int
kb_flush(kb_t kb,const char * except)672 kb_flush (kb_t kb, const char *except)
673 {
674 int rc = 0;
675
676 assert (kb);
677 assert (kb->kb_ops);
678
679 if (kb->kb_ops->kb_flush != NULL)
680 rc = kb->kb_ops->kb_flush (kb, except);
681
682 return rc;
683 }
684
685 /**
686 * @brief Return the kb index
687 * @param[in] kb KB handle.
688 * @return kb_index on success, null on error.
689 */
690 static inline int
kb_get_kb_index(kb_t kb)691 kb_get_kb_index (kb_t kb)
692 {
693 assert (kb);
694 assert (kb->kb_ops);
695 assert (kb->kb_ops->kb_get_kb_index);
696
697 return kb->kb_ops->kb_get_kb_index (kb);
698 }
699
700 #endif
701