OpenVAS Scanner 23.40.3
nasl_krb5.c
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 Greenbone AG
2//
3// SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception
4
5#include "nasl_krb5.h"
6
8#include "nasl_debug.h"
9#include "nasl_func.h"
10#include "nasl_global_ctxt.h"
11#include "nasl_lex_ctxt.h"
12#include "nasl_tree.h"
13#include "nasl_var.h"
14
15#include <stdio.h>
16
17#define NASL_PRINT_KRB_ERROR(lexic, credential, result) \
18 do \
19 { \
20 char *error_str = okrb5_error_code_to_string (result); \
21 nasl_perror ( \
22 lexic, "%s[config_path: '%s' realm: '%s' user: '%s'] => %s (%d)", \
23 __func__, credential.config_path.data, credential.realm.data, \
24 credential.user.user.data, error_str, result); \
25 free (error_str); \
26 } \
27 while (0)
28
29// Is used for krb5_is_success, krb5_is_failure which allows the script author
30// to verify if the last called krb5 function failed or not. This is strictly
31// speaking a safety net for incorrect usage as most krb5 functions return
32// the error code.
34
35// cached_gss_context is used on cases that require an already existing session.
36// NASL does currently not have the concept of a pointer nor struct so we need
37// to store it as a global variable.
38//
39// We use one context per run, this means that per run (target + oid) there is
40// only on credential allowed making it safe to be cached in that fashion.
41static struct OKrb5GSSContext *cached_gss_context = NULL;
42
43// Is used for `krb5_gss_update_context_out` and is essential a
44// cache for the data from `krb5_gss_update_context`.
45static struct OKrb5Slice *to_application = NULL;
46
47// Is used for `krb5_gss_update_context_needs_more` which indicates to the
48// script author that `krb5_gss_update_context` is not satisfied yet.
49static bool gss_update_context_more = false;
50
51#define SET_SLICE_FROM_LEX_OR_ENV(lexic, slice, name, env_name) \
52 do \
53 { \
54 okrb5_set_slice_from_str (slice, get_str_var_by_name (lexic, name)); \
55 if (slice.len == 0) \
56 { \
57 okrb5_set_slice_from_str (slice, getenv (env_name)); \
58 } \
59 } \
60 while (0)
61
62#define PERROR_SET_SLICE_FROM_LEX_OR_ENV(lexic, slice, name, env_name) \
63 do \
64 { \
65 SET_SLICE_FROM_LEX_OR_ENV (lexic, slice, name, env_name); \
66 if (slice.len == 0) \
67 { \
68 nasl_perror (lexic, "Expected %s or env variable %s", name, \
69 env_name); \
70 } \
71 } \
72 while (0)
73
74
75static OKrb5Credential
77{
78 OKrb5Credential credential = {0};
80
81 char *kdc = NULL;
82
83 SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.config_path, "config_path",
84 "KRB5_CONFIG");
85 if (credential.config_path.len == 0)
86 {
87 okrb5_set_slice_from_str (credential.config_path, "/etc/krb5.conf");
88 }
89
90 PERROR_SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.realm, "realm",
91 "KRB5_REALM");
92 PERROR_SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.kdc, "kdc", "KRB5_KDC");
93 PERROR_SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.user.user, "user",
94 "KRB5_USER");
95 PERROR_SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.user.password, "password",
96 "KRB5_PASSWORD");
97 PERROR_SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.target.host_name, "host",
98 "KRB5_TARGET_HOST");
99 // SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.target.service, "service",
100 // "KRB5_TARGET_SERVICE");
101
102 if ((code = o_krb5_find_kdc (&credential, &kdc)))
103 {
105 {
106 NASL_PRINT_KRB_ERROR (lexic, credential, code);
107 }
108 else
109 {
110 if ((code = o_krb5_add_realm (&credential, credential.kdc.data)))
111 {
112 NASL_PRINT_KRB_ERROR (lexic, credential, code);
113 }
114 }
115 }
116 else
117 {
118 free (kdc);
119 }
120 if (credential.target.service.len == 0)
121 {
122 okrb5_set_slice_from_str (credential.target.service, "cifs");
123 }
124 SET_SLICE_FROM_LEX_OR_ENV (lexic, credential.kdc, "kdc", "KRB5_KDC");
125
126 memset (&credential.target.domain, 0, sizeof (struct OKrb5Slice));
127
128 return credential;
129}
130
150tree_cell *
152{
153 tree_cell *retc;
154 char *kdc = NULL;
155 OKrb5Credential credential;
156
157 credential = build_krb5_credential (lexic);
158
159 if ((last_okrb5_result = o_krb5_find_kdc (&credential, &kdc)))
160 {
161 NASL_PRINT_KRB_ERROR (lexic, credential, last_okrb5_result);
162 return FAKE_CELL;
163 }
164
166 retc->x.str_val = kdc;
167 retc->size = strlen (kdc);
168 return retc;
169}
170
171tree_cell *
173{
174 tree_cell *retc;
175 OKrb5Credential credential;
176 char *kdc = get_str_var_by_name (lexic, "kdc");
177 if (kdc == NULL)
178 {
179 kdc = getenv ("KRB5_KDC");
180 if (kdc == NULL)
181 {
183 NASL_PRINT_KRB_ERROR (lexic, credential, last_okrb5_result);
184 goto exit;
185 }
186 }
187
188 credential = build_krb5_credential (lexic);
189
190 if ((last_okrb5_result = o_krb5_add_realm (&credential, kdc)))
191 {
192 NASL_PRINT_KRB_ERROR (lexic, credential, last_okrb5_result);
193 }
194
195exit:
197 retc->x.i_val = last_okrb5_result;
198 return retc;
199}
200
213tree_cell *
215{
218 retc->x.i_val = result == O_KRB5_SUCCESS;
219 return retc;
220}
221
234tree_cell *
236{
239 retc->x.i_val = result != O_KRB5_SUCCESS;
240 return retc;
241}
242
243
244tree_cell *
246{
247 (void) lexic;
249 if (cached_gss_context == NULL)
250 {
252 }
253 else
254 {
256 };
258 retc->x.i_val = last_okrb5_result;
259 return retc;
260}
261tree_cell *
263{
264 (void) lexic;
265
266 OKrb5Credential credential;
267 credential = build_krb5_credential (lexic);
269 if (cached_gss_context == NULL)
270 {
272 }
273 result = o_krb5_gss_prepare_context (&credential, cached_gss_context);
275 retc->x.i_val = result;
276 last_okrb5_result = result;
277 return retc;
278}
279
280
281tree_cell *
283{
285 tree_cell *retc;
286 struct OKrb5Slice from_application;
287
288 if (to_application != NULL)
289 {
290 free (to_application->data);
292 to_application = NULL;
293 }
294
295 from_application.data = (void *) get_str_var_by_num (lexic, 0);
296 from_application.len = get_var_size_by_num (lexic, 0);
297
298 if (cached_gss_context == NULL)
299 {
301 goto result;
302 }
303 result =
306result:
308 retc->x.i_val = result;
309 last_okrb5_result = result;
310 return retc;
311}
312
313void
315{
316 if (to_application != NULL)
317 {
318 free (to_application->data);
320 to_application = NULL;
321 }
322 if (cached_gss_context != NULL)
323 {
325 }
326}
327
328tree_cell *
330{
331 (void) lexic;
334 return retc;
335}
336
337static inline tree_cell *
339{
341 retc->x.str_val = slice->data;
342 retc->size = slice->len;
343 return retc;
344}
345
346tree_cell *
348{
349 (void) lexic;
350 if (to_application == NULL)
351 {
352 return FAKE_CELL;
353 }
355 // we need to prevent accidental free it as it is freed when the tree_cell is
356 // cleaned up
357 to_application = NULL;
358 return out;
359}
360
361tree_cell *
363{
364 (void) lexic;
365 struct OKrb5Slice *session_key = NULL;
366 if (cached_gss_context == NULL)
367 {
369 return FAKE_CELL;
370 }
371 if ((last_okrb5_result =
374 {
375 return FAKE_CELL;
376 }
377 return okrb5_slice_to_tree_cell (session_key);
378}
379
380tree_cell *
382{
383 (void) lexic;
386 retc->size = strlen (retc->x.str_val);
387 return retc;
388}
void free(void *)
tree_cell * nasl_okrb5_is_failure(lex_ctxt *lexic)
Returns 0 if the krb5 function was successful and 1 if it failed.
Definition nasl_krb5.c:235
static struct OKrb5Slice * to_application
Definition nasl_krb5.c:45
tree_cell * nasl_okrb5_find_kdc(lex_ctxt *lexic)
Returns the defined KDC of a given Realm.
Definition nasl_krb5.c:151
tree_cell * nasl_okrb5_gss_session_key_context(lex_ctxt *lexic)
Definition nasl_krb5.c:362
tree_cell * nasl_okrb5_add_realm(lex_ctxt *lexic)
Adds the given KDC to the given Realm.
Definition nasl_krb5.c:172
tree_cell * nasl_okrb5_gss_update_context_out(lex_ctxt *lexic)
Definition nasl_krb5.c:347
tree_cell * nasl_okrb5_gss_update_context_needs_more(lex_ctxt *lexic)
Definition nasl_krb5.c:329
#define PERROR_SET_SLICE_FROM_LEX_OR_ENV(lexic, slice, name, env_name)
Definition nasl_krb5.c:62
static struct OKrb5GSSContext * cached_gss_context
Definition nasl_krb5.c:41
tree_cell * nasl_okrb5_gss_update_context(lex_ctxt *lexic)
Definition nasl_krb5.c:282
tree_cell * nasl_okrb5_gss_prepare_context(lex_ctxt *lexic)
Definition nasl_krb5.c:262
tree_cell * nasl_okrb5_error_code_to_string(lex_ctxt *lexic)
Definition nasl_krb5.c:381
#define SET_SLICE_FROM_LEX_OR_ENV(lexic, slice, name, env_name)
Definition nasl_krb5.c:51
tree_cell * nasl_okrb5_gss_init(lex_ctxt *lexic)
Definition nasl_krb5.c:245
static OKrb5ErrorCode last_okrb5_result
Definition nasl_krb5.c:33
tree_cell * nasl_okrb5_is_success(lex_ctxt *lexic)
Returns 1 if the krb5 function was successful 0 otherwise.
Definition nasl_krb5.c:214
void nasl_okrb5_clean(void)
Definition nasl_krb5.c:314
#define NASL_PRINT_KRB_ERROR(lexic, credential, result)
Definition nasl_krb5.c:17
static OKrb5Credential build_krb5_credential(lex_ctxt *lexic)
Definition nasl_krb5.c:76
static bool gss_update_context_more
Definition nasl_krb5.c:49
static tree_cell * okrb5_slice_to_tree_cell(struct OKrb5Slice *slice)
Definition nasl_krb5.c:338
long int get_var_size_by_num(lex_ctxt *, int)
Definition nasl_var.c:1145
struct struct_lex_ctxt lex_ctxt
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
char * get_str_var_by_num(lex_ctxt *, int)
Definition nasl_var.c:1108
long int get_int_var_by_num(lex_ctxt *, int, int)
Definition nasl_var.c:1094
#define code
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
@ CONST_STR
Definition nasl_tree.h:80
@ CONST_INT
Definition nasl_tree.h:79
struct TC tree_cell
#define FAKE_CELL
Definition nasl_tree.h:110
char * okrb5_error_code_to_string(const OKrb5ErrorCode code)
void okrb5_gss_free_context(struct OKrb5GSSContext *context)
OKrb5ErrorCode o_krb5_add_realm(const OKrb5Credential *creds, const char *kdc)
OKrb5ErrorCode o_krb5_find_kdc(const OKrb5Credential *creds, char **kdc)
OKrb5ErrorCode o_krb5_gss_prepare_context(const OKrb5Credential *creds, struct OKrb5GSSContext *gss_context)
OKrb5ErrorCode o_krb5_gss_session_key_context(struct OKrb5GSSContext *gss_context, struct OKrb5Slice **out)
struct OKrb5GSSContext * okrb5_gss_init_context(void)
OKrb5ErrorCode o_krb5_gss_update_context(struct OKrb5GSSContext *gss_context, const struct OKrb5Slice *in_data, struct OKrb5Slice **out_data, bool *more)
OKrb5ErrorCode
@ O_KRB5_SUCCESS
@ O_KRB5_EXPECTED_NOT_NULL
@ O_KRB5_REALM_NOT_FOUND
@ O_KRB5_CONF_NOT_FOUND
#define okrb5_set_slice_from_str(slice, str)
struct OKrb5Slice kdc
struct OKrb5Slice realm
struct OKrb5Target target
struct OKrb5Slice config_path
struct OKrb5User user
void * data
struct OKrb5Slice service
struct OKrb5Slice domain
struct OKrb5Slice host_name
struct OKrb5Slice password
struct OKrb5Slice user
long int i_val
Definition nasl_tree.h:104
long int size
Definition nasl_tree.h:99
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103