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