1 /* Portions Copyright (C) 2009-2021 Greenbone Networks GmbH
2 * Portions Copyright (C) 2006 Software in the Public Interest, Inc.
3 * Based on work Copyright (C) 1998 - 2006 Tenable Network Security, Inc.
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 /**
22 * @file utils.c
23 * @brief A bunch of miscellaneous functions, mostly file conversions.
24 */
25
26 #include "../misc/scanneraux.h" /* for struct scan_globals */
27
28 #include <errno.h> /* for errno() */
29 #include <gvm/base/prefs.h> /* for prefs_get() */
30 #include <stdlib.h> /* for atoi() */
31 #include <string.h> /* for strcmp() */
32 #include <sys/ioctl.h> /* for ioctl() */
33 #include <sys/wait.h> /* for waitpid() */
34
35 extern int global_max_hosts;
36 extern int global_max_checks;
37
38 #undef G_LOG_DOMAIN
39 /**
40 * @brief GLib log domain.
41 */
42 #define G_LOG_DOMAIN "sd main"
43
44 /**
45 * @brief Adds a 'translation' entry for a file sent by the client.
46 *
47 * Files sent by the client are stored in memory on the server side.
48 * In order to access these files, their original name ('local' to the client)
49 * can be 'translated' into the file contents of the in-memory copy of the
50 * file on the server side.
51 *
52 * @param globals Global struct.
53 * @param file_hash hash to reference the file.
54 * @param contents Contents of the file.
55 */
56 static void
files_add_translation(struct scan_globals * globals,const char * file_hash,char * contents)57 files_add_translation (struct scan_globals *globals, const char *file_hash,
58 char *contents)
59 {
60 GHashTable *trans = globals->files_translation;
61 // Register the mapping table if none there yet
62 if (trans == NULL)
63 {
64 trans = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
65 globals->files_translation = trans;
66 }
67
68 g_hash_table_insert (trans, g_strdup (file_hash), contents);
69 }
70
71 /**
72 * @brief Adds a 'content size' entry for a file sent by the client.
73 *
74 * Files sent by the client are stored in memory on the server side.
75 * Because they may be binary we need to store the size of the uploaded file as
76 * well. This function sets up a mapping from the original name sent by the
77 * client to the file size.
78 *
79 * @param globals Global struct.
80 * @param file_hash hash to reference the file.
81 * @param filesize Size of the file in bytes.
82 */
83 static void
files_add_size_translation(struct scan_globals * globals,const char * file_hash,const long filesize)84 files_add_size_translation (struct scan_globals *globals, const char *file_hash,
85 const long filesize)
86 {
87 GHashTable *trans = globals->files_size_translation;
88 gchar *filesize_str = g_strdup_printf ("%ld", filesize);
89
90 // Register the mapping table if none there yet
91 if (trans == NULL)
92 {
93 trans = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
94 globals->files_size_translation = trans;
95 }
96
97 g_hash_table_insert (trans, g_strdup (file_hash), g_strdup (filesize_str));
98 }
99
100 /**
101 * @brief Stores a file type preference in a hash table.
102 *
103 * @param globals Global struct.
104 * @param file File content.
105 * @param file_hash hash to reference the file.
106 *
107 * @return 0 if successful, -1 in case of errors.
108 */
109 int
store_file(struct scan_globals * globals,const char * file,const char * file_hash)110 store_file (struct scan_globals *globals, const char *file,
111 const char *file_hash)
112 {
113 char *origname;
114 gchar *contents = NULL;
115
116 size_t bytes = 0;
117
118 if (!file_hash || *file_hash == '\0')
119 return -1;
120
121 origname = g_strdup (file_hash);
122
123 contents = (gchar *) g_base64_decode (file, &bytes);
124
125 if (contents == NULL)
126 {
127 g_debug ("store_file: Failed to allocate memory for uploaded file.");
128 g_free (origname);
129 return -1;
130 }
131
132 files_add_translation (globals, origname, contents);
133 files_add_size_translation (globals, origname, bytes);
134
135 g_free (origname);
136 return 0;
137 }
138
139 /**
140 * Get the max number of hosts to test at the same time.
141 */
142 int
get_max_hosts_number(void)143 get_max_hosts_number (void)
144 {
145 int max_hosts;
146 if (prefs_get ("max_hosts"))
147 {
148 max_hosts = atoi (prefs_get ("max_hosts"));
149 if (max_hosts <= 0)
150 {
151 g_debug ("Error ! max_hosts = %d -- check %s", max_hosts,
152 (char *) prefs_get ("config_file"));
153 max_hosts = global_max_hosts;
154 }
155 else if (max_hosts > global_max_hosts)
156 {
157 g_debug ("Client tried to raise the maximum hosts number - %d."
158 " Using %d. Change 'max_hosts' in openvas.conf if you"
159 " believe this is incorrect",
160 max_hosts, global_max_hosts);
161 max_hosts = global_max_hosts;
162 }
163 }
164 else
165 max_hosts = global_max_hosts;
166 return (max_hosts);
167 }
168
169 /**
170 * Get the max number of plugins to launch against the remote
171 * host at the same time
172 */
173 int
get_max_checks_number(void)174 get_max_checks_number (void)
175 {
176 int max_checks;
177 if (prefs_get ("max_checks"))
178 {
179 max_checks = atoi (prefs_get ("max_checks"));
180 if (max_checks <= 0)
181 {
182 g_debug ("Error ! max_hosts = %d -- check %s", max_checks,
183 (char *) prefs_get ("config_file"));
184 max_checks = global_max_checks;
185 }
186 else if (max_checks > global_max_checks)
187 {
188 g_debug ("Client tried to raise the maximum checks number - %d."
189 " Using %d. Change 'max_checks' in openvas.conf if you"
190 " believe this is incorrect",
191 max_checks, global_max_checks);
192 max_checks = global_max_checks;
193 }
194 }
195 else
196 max_checks = global_max_checks;
197 return (max_checks);
198 }
199
200 /**
201 * Determines if a process is alive - as reliably as we can
202 */
203 int
process_alive(pid_t pid)204 process_alive (pid_t pid)
205 {
206 int i, ret;
207 if (pid == 0)
208 return 0;
209
210 for (i = 0, ret = 1; (i < 10) && (ret > 0); i++)
211 ret = waitpid (pid, NULL, WNOHANG);
212
213 return kill (pid, 0) == 0;
214 }
215
216 int
data_left(int soc)217 data_left (int soc)
218 {
219 int data = 0;
220 ioctl (soc, FIONREAD, &data);
221 return data;
222 }
223
224 void
wait_for_children1(void)225 wait_for_children1 (void)
226 {
227 int e, n = 0;
228 do
229 {
230 errno = 0;
231 e = waitpid (-1, NULL, WNOHANG);
232 n++;
233 }
234 while ((e > 0 || errno == EINTR) && n < 20);
235 }
236
237 /*
238 * @brief Checks if a provided preference is scanner-only and can't be
239 * read/written by the client.
240 *
241 * @return 1 if pref is scanner-only, 0 otherwise.
242 */
243 int
is_scanner_only_pref(const char * pref)244 is_scanner_only_pref (const char *pref)
245 {
246 if (pref == NULL)
247 return 0;
248 if (!strcmp (pref, "config_file") || !strcmp (pref, "plugins_folder")
249 || !strcmp (
250 pref,
251 "kb_location") // old name of db_address, ignore from old conf's
252 || !strcmp (pref, "db_address") || !strcmp (pref, "negot_timeout")
253 || !strcmp (pref, "force_pubkey_auth")
254 || !strcmp (pref, "log_whole_attack")
255 || !strcmp (pref, "log_plugins_name_at_load")
256 || !strcmp (pref, "nasl_no_signature_check")
257 || !strcmp (pref, "vendor_version") || !strcmp (pref, "drop_privileges")
258 || !strcmp (pref, "nasl_drop_privileges_user")
259 || !strcmp (pref, "debug_tls") || !strcmp (pref, "min_free_mem")
260 || !strcmp (pref, "max_sysload")
261 /* Preferences starting with sys_ are scanner-side only. */
262 || !strncmp (pref, "sys_", 4))
263 return 1;
264 return 0;
265 }
266