OpenVAS Scanner 23.43.1
openvas-krb5.c File Reference
#include "openvas-krb5.h"
#include <ctype.h>
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_krb5.h>
#include <krb5/krb5.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
Include dependency graph for openvas-krb5.c:

Go to the source code of this file.

Data Structures

struct  OKrb5GSSCredentials
struct  OKrb5GSSContext

Macros

#define GUARD_NULL(var, return_var)
#define GUARD_NOT_NULL(var, return_var)
#define ALLOCATE_AND_CHECK(var, type, n, return_var)
#define SKIP_WS(line, line_len, start, i)
#define IS_STR_EQUAL(line, line_len, start, cmp, cmp_len)
#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH   11
#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID   "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"
#define gss_mech_spnego   (&spnego_mech_oid_desc)
#define ARRAY_SIZE(a)
#define MAX_LINE_LENGTH   1024
#define CHECK_FPRINTF(result, writer, fmt, ...)
#define CHECK_FPRINT(result, writer, fmt)
#define CHECK_MAJOR_STAT()
#define HEAP_STRING(var, s)

Functions

OKrb5ErrorCode o_krb5_find_kdc (const OKrb5Credential *creds, char **kdc)
static OKrb5ErrorCode o_krb5_write_trimmed (FILE *file, const char *prefix, const char *start, const char *end)
static OKrb5ErrorCode o_krb5_write_realm (FILE *file, const OKrb5Credential *creds, const char *kdc)
OKrb5ErrorCode o_krb5_add_realm (const OKrb5Credential *creds, const char *kdc)
static OKrb5ErrorCode okrb5_gss_authenticate (const OKrb5Credential *creds, struct OKrb5GSSContext *gss_creds)
struct OKrb5GSSContextokrb5_gss_init_context (void)
void okrb5_gss_free_context (struct OKrb5GSSContext *context)
OKrb5ErrorCode o_krb5_gss_prepare_context (const OKrb5Credential *creds, struct OKrb5GSSContext *gss_context)
OKrb5ErrorCode o_krb5_gss_update_context (struct OKrb5GSSContext *gss_context, const struct OKrb5Slice *in_data, struct OKrb5Slice **out_data, bool *more)
OKrb5ErrorCode o_krb5_gss_session_key_context (struct OKrb5GSSContext *gss_context, struct OKrb5Slice **out)
char * okrb5_error_code_to_string (const OKrb5ErrorCode code)

Variables

gss_OID_desc spnego_mech_oid_desc = {6, (void *) "\x2b\x06\x01\x05\x05\x02"}

Macro Definition Documentation

◆ ALLOCATE_AND_CHECK

#define ALLOCATE_AND_CHECK ( var,
type,
n,
return_var )
Value:
do \
{ \
var = (type *) calloc (n, sizeof (type)); \
if (var == NULL) \
{ \
return_var = O_KRB5_NOMEM; \
goto result; \
} \
} \
while (0)
@ O_KRB5_NOMEM

Definition at line 39 of file openvas-krb5.c.

39#define ALLOCATE_AND_CHECK(var, type, n, return_var) \
40 do \
41 { \
42 var = (type *) calloc (n, sizeof (type)); \
43 if (var == NULL) \
44 { \
45 return_var = O_KRB5_NOMEM; \
46 goto result; \
47 } \
48 } \
49 while (0)

Referenced by o_krb5_find_kdc(), o_krb5_gss_prepare_context(), and okrb5_gss_authenticate().

◆ ARRAY_SIZE

#define ARRAY_SIZE ( a)
Value:
(sizeof (a) / sizeof (a[0]))

Definition at line 80 of file openvas-krb5.c.

Referenced by okrb5_gss_authenticate().

◆ CHECK_FPRINT

#define CHECK_FPRINT ( result,
writer,
fmt )
Value:
do \
{ \
if (fprintf (writer, fmt) < 0) \
{ \
goto result; \
} \
} \
while (0)
@ O_KRB5_UNABLE_TO_WRITE

Definition at line 187 of file openvas-krb5.c.

187#define CHECK_FPRINT(result, writer, fmt) \
188 do \
189 { \
190 if (fprintf (writer, fmt) < 0) \
191 { \
192 result = O_KRB5_UNABLE_TO_WRITE; \
193 goto result; \
194 } \
195 } \
196 while (0)

Referenced by o_krb5_add_realm(), and o_krb5_write_realm().

◆ CHECK_FPRINTF

#define CHECK_FPRINTF ( result,
writer,
fmt,
... )
Value:
do \
{ \
if (fprintf (writer, fmt, __VA_ARGS__) < 0) \
{ \
goto result; \
} \
} \
while (0)

Definition at line 176 of file openvas-krb5.c.

176#define CHECK_FPRINTF(result, writer, fmt, ...) \
177 do \
178 { \
179 if (fprintf (writer, fmt, __VA_ARGS__) < 0) \
180 { \
181 result = O_KRB5_UNABLE_TO_WRITE; \
182 goto result; \
183 } \
184 } \
185 while (0)

Referenced by o_krb5_write_realm(), and o_krb5_write_trimmed().

◆ CHECK_MAJOR_STAT

#define CHECK_MAJOR_STAT ( )
Value:
if (maj_stat != GSS_S_COMPLETE) \
{ \
result = O_KRB5_ERROR + maj_stat; \
goto result; \
}
@ O_KRB5_ERROR

Referenced by okrb5_gss_authenticate().

◆ GSS_KRB5_INQ_SSPI_SESSION_KEY_OID

#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID   "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"

Definition at line 72 of file openvas-krb5.c.

72#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID \
73 "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"

Referenced by o_krb5_gss_session_key_context().

◆ GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH

#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH   11

Definition at line 70 of file openvas-krb5.c.

Referenced by o_krb5_gss_session_key_context().

◆ gss_mech_spnego

#define gss_mech_spnego   (&spnego_mech_oid_desc)

◆ GUARD_NOT_NULL

#define GUARD_NOT_NULL ( var,
return_var )
Value:
do \
{ \
if (var == NULL) \
{ \
return_var = O_KRB5_EXPECTED_NOT_NULL; \
goto result; \
} \
} \
while (0)
@ O_KRB5_EXPECTED_NOT_NULL

Definition at line 28 of file openvas-krb5.c.

28#define GUARD_NOT_NULL(var, return_var) \
29 do \
30 { \
31 if (var == NULL) \
32 { \
33 return_var = O_KRB5_EXPECTED_NOT_NULL; \
34 goto result; \
35 } \
36 } \
37 while (0)

◆ GUARD_NULL

#define GUARD_NULL ( var,
return_var )
Value:
do \
{ \
if (var != NULL) \
{ \
return_var = O_KRB5_EXPECTED_NULL; \
goto result; \
} \
} \
while (0)
@ O_KRB5_EXPECTED_NULL

Definition at line 17 of file openvas-krb5.c.

17#define GUARD_NULL(var, return_var) \
18 do \
19 { \
20 if (var != NULL) \
21 { \
22 return_var = O_KRB5_EXPECTED_NULL; \
23 goto result; \
24 } \
25 } \
26 while (0)

Referenced by o_krb5_find_kdc().

◆ HEAP_STRING

#define HEAP_STRING ( var,
s )
Value:
do \
{ \
var = calloc (1, strlen (s) + 1); \
snprintf (var, strlen (s) + 1, s); \
goto result; \
} \
while (0)

Referenced by okrb5_error_code_to_string().

◆ IS_STR_EQUAL

#define IS_STR_EQUAL ( line,
line_len,
start,
cmp,
cmp_len )
Value:
((line_len - start < cmp_len) ? 0 \
: (line_len == 0 && cmp_len == 0) \
? 1 \
: (memcmp (line + start, cmp, cmp_len) == 0))

Definition at line 64 of file openvas-krb5.c.

64#define IS_STR_EQUAL(line, line_len, start, cmp, cmp_len) \
65 ((line_len - start < cmp_len) ? 0 \
66 : (line_len == 0 && cmp_len == 0) \
67 ? 1 \
68 : (memcmp (line + start, cmp, cmp_len) == 0))

Referenced by o_krb5_add_realm(), and o_krb5_find_kdc().

◆ MAX_LINE_LENGTH

#define MAX_LINE_LENGTH   1024

Definition at line 82 of file openvas-krb5.c.

Referenced by o_krb5_add_realm(), and o_krb5_find_kdc().

◆ SKIP_WS

#define SKIP_WS ( line,
line_len,
start,
i )
Value:
do \
{ \
for (i = start; i < line_len; i++) \
{ \
if (line[i] != ' ' && line[i] != '\t') \
{ \
break; \
} \
} \
} \
while (0)

Definition at line 51 of file openvas-krb5.c.

51#define SKIP_WS(line, line_len, start, i) \
52 do \
53 { \
54 for (i = start; i < line_len; i++) \
55 { \
56 if (line[i] != ' ' && line[i] != '\t') \
57 { \
58 break; \
59 } \
60 } \
61 } \
62 while (0)

Referenced by o_krb5_add_realm(), and o_krb5_find_kdc().

Function Documentation

◆ o_krb5_add_realm()

OKrb5ErrorCode o_krb5_add_realm ( const OKrb5Credential * creds,
const char * kdc )

Definition at line 247 of file openvas-krb5.c.

248{
250 FILE *file = NULL, *tmp = NULL;
251 char line[MAX_LINE_LENGTH] = {0};
252 char tmpfn[MAX_LINE_LENGTH] = {0};
253 int state, i;
254 char *cp = (char *) creds->config_path.data;
255
256 if ((file = fopen (cp, "r")) == NULL)
257 {
258 if ((file = fopen (cp, "w")) == NULL)
259 {
261 goto result;
262 }
263 CHECK_FPRINT (result, file, "[realms]\n");
264 o_krb5_write_realm (file, creds, kdc);
265 goto result;
266 }
267 snprintf (tmpfn, MAX_LINE_LENGTH, "%s.tmp", cp);
268 if ((tmp = fopen (tmpfn, "w")) == NULL)
269 {
271 goto result;
272 }
273 state = 0;
274 while (fgets (line, MAX_LINE_LENGTH, file))
275 {
276 fputs (line, tmp);
277 if (state == 0)
278 {
279 SKIP_WS (line, MAX_LINE_LENGTH, 0, i);
280 if (IS_STR_EQUAL (line, MAX_LINE_LENGTH, i, "[realms]", 8) == 1)
281 {
282 o_krb5_write_realm (file, creds, kdc);
283
284 state = 1;
285 }
286 }
287 }
288
289 if (rename (tmpfn, cp) != 0)
290 {
292 }
293
294result:
295 if (tmp != NULL)
296 fclose (tmp);
297 if (file != NULL)
298 fclose (file);
299 return result;
300}
#define IS_STR_EQUAL(line, line_len, start, cmp, cmp_len)
#define CHECK_FPRINT(result, writer, fmt)
#define SKIP_WS(line, line_len, start, i)
#define MAX_LINE_LENGTH
static OKrb5ErrorCode o_krb5_write_realm(FILE *file, const OKrb5Credential *creds, const char *kdc)
OKrb5ErrorCode
@ O_KRB5_SUCCESS
@ O_KRB5_CONF_NOT_CREATED
@ O_KRB5_TMP_CONF_NOT_MOVED
@ O_KRB5_TMP_CONF_NOT_CREATED
struct OKrb5Slice config_path
void * data

References CHECK_FPRINT, OKrb5Credential::config_path, OKrb5Slice::data, IS_STR_EQUAL, MAX_LINE_LENGTH, O_KRB5_CONF_NOT_CREATED, O_KRB5_SUCCESS, O_KRB5_TMP_CONF_NOT_CREATED, O_KRB5_TMP_CONF_NOT_MOVED, o_krb5_write_realm(), and SKIP_WS.

Referenced by build_krb5_credential(), and nasl_okrb5_add_realm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ o_krb5_find_kdc()

OKrb5ErrorCode o_krb5_find_kdc ( const OKrb5Credential * creds,
char ** kdc )

Definition at line 85 of file openvas-krb5.c.

86{
88 char line[MAX_LINE_LENGTH];
89 int state = 0;
90 size_t last_element;
91 size_t i, j;
92 FILE *file = NULL;
93
94 // we don't know if we should free it or just override it.
95 // aborting instead.
96 GUARD_NULL (*kdc, result);
97 if ((file = fopen ((char *) creds->config_path.data, "r")) == NULL)
98 {
99 result = O_KRB5_CONF_NOT_FOUND;
100 goto result;
101 }
102
103 while (fgets (line, MAX_LINE_LENGTH, file))
104 {
105 line[strcspn (line, "\n")] = 0;
106 last_element = strlen (line) - 1;
107 SKIP_WS (line, last_element, 0, i);
108 if (line[i] == '[' && line[last_element] == ']')
109 {
110 if (state != 0)
111 {
112 result = O_KRB5_REALM_NOT_FOUND;
113 goto result;
114 }
115 if (IS_STR_EQUAL (line, last_element + 1, i, "[realms]", 8) == 1)
116 {
117 state = 1;
118 }
119 }
120 else
121 {
122 if (line[i] == '}' || line[last_element] == '}')
123 {
124 state = 1;
125 }
126 else if (state == 1)
127 {
128 for (j = i; j <= last_element; j++)
129 {
130 if (line[j] != ((char *) creds->realm.data)[j - i])
131 {
132 state = 2;
133 break;
134 }
135 if (j - i >= creds->realm.len)
136 {
137 break;
138 }
139 }
140 if (j - i == creds->realm.len)
141 {
142 state = 3;
143 }
144 }
145 else if (state == 3)
146 {
147 if (IS_STR_EQUAL (line, last_element + 1, i, "kdc", 3))
148 {
149 SKIP_WS (line, last_element, i + 3, i);
150 if (line[i] == '=')
151 {
152 SKIP_WS (line, last_element, i + 1, i);
153 ALLOCATE_AND_CHECK (*kdc, char, (last_element - i) + 1,
154 result);
155 for (j = i; j <= last_element; j++)
156 {
157 (*kdc)[j - i] = line[j];
158 }
159
160 result = O_KRB5_SUCCESS;
161 goto result;
162 }
163 }
164 }
165 }
166 }
167
168result:
169 if (file != NULL)
170 {
171 fclose (file);
172 }
173 return result;
174}
#define GUARD_NULL(var, return_var)
#define ALLOCATE_AND_CHECK(var, type, n, return_var)
@ O_KRB5_REALM_NOT_FOUND
@ O_KRB5_CONF_NOT_FOUND
struct OKrb5Slice realm

References ALLOCATE_AND_CHECK, OKrb5Credential::config_path, OKrb5Slice::data, GUARD_NULL, IS_STR_EQUAL, OKrb5Slice::len, MAX_LINE_LENGTH, O_KRB5_CONF_NOT_FOUND, O_KRB5_REALM_NOT_FOUND, O_KRB5_SUCCESS, OKrb5Credential::realm, and SKIP_WS.

Referenced by build_krb5_credential(), and nasl_okrb5_find_kdc().

Here is the caller graph for this function:

◆ o_krb5_gss_prepare_context()

OKrb5ErrorCode o_krb5_gss_prepare_context ( const OKrb5Credential * creds,
struct OKrb5GSSContext * gss_context )

Definition at line 446 of file openvas-krb5.c.

448{
449 char *target_principal_str = NULL;
451
452 gss_name_t gss_target = GSS_C_NO_NAME;
453 OM_uint32 maj_stat;
454 OM_uint32 min_stat;
455 gss_buffer_desc targetbuf = GSS_C_EMPTY_BUFFER;
456 const struct OKrb5Target *target = &creds->target;
457
458 if (gss_context->gss_creds == GSS_C_NO_CREDENTIAL)
459 {
460 if ((result = okrb5_gss_authenticate (creds, gss_context)))
461 {
462 goto result;
463 }
464 }
465
466 if (target->domain.len != 0)
467 {
468 ALLOCATE_AND_CHECK (target_principal_str, char,
469 target->host_name.len + target->domain.len
470 + target->service.len + creds->realm.len + 4,
471 result);
472 snprintf (target_principal_str,
473 target->host_name.len + target->domain.len + target->service.len
474 + creds->realm.len + 4,
475 "%.*s/%.*s/%.*s@%.*s", (int) target->service.len,
476 (char *) target->service.data, (int) target->host_name.len,
477 (char *) target->host_name.data, (int) target->domain.len,
478 (char *) target->domain.data, (int) creds->realm.len,
479 (char *) creds->realm.data);
480 }
481 else
482 {
483 ALLOCATE_AND_CHECK (target_principal_str, char,
484 target->host_name.len + target->service.len
485 + creds->realm.len + 3,
486 result);
487 snprintf (target_principal_str,
488 target->host_name.len + target->service.len + creds->realm.len
489 + 3,
490 "%.*s/%.*s@%.*s", (int) target->service.len,
491 (char *) target->service.data, (int) target->host_name.len,
492 (char *) target->host_name.data, (int) creds->realm.len,
493 (char *) creds->realm.data);
494 }
495
496 targetbuf = (gss_buffer_desc) {
497 .value = target_principal_str,
498 .length = strlen (target_principal_str),
499 };
500
501 maj_stat = gss_import_name (&min_stat, &targetbuf,
502 // might also be GSS_C_NT_HOSTBASED_SERVICE,
503 // but samba uses GSS_C_NT_USER_NAME
504 GSS_C_NT_USER_NAME, &gss_target);
505 if (maj_stat != GSS_S_COMPLETE)
506 {
507 result = O_KRB5_ERROR + maj_stat;
508 goto result;
509 }
510
511 gss_context->gss_target = gss_target;
512 gss_context->gss_mech = gss_mech_spnego;
513 gss_context->gss_want_flags = GSS_C_MUTUAL_FLAG | GSS_C_DELEG_POLICY_FLAG
514 | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG
515 | GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
516 gss_context->gss_got_flags = 0;
517 gss_context->gss_channel_bindings = GSS_C_NO_CHANNEL_BINDINGS;
518 gss_context->gss_time_req = 0;
519 gss_context->gss_time_rec = 0;
520 gss_context->gss_actual_mech_type = NULL;
521result:
522 if (target_principal_str != NULL)
523 free (target_principal_str);
524
525 return result;
526}
void free(void *)
#define gss_mech_spnego
static OKrb5ErrorCode okrb5_gss_authenticate(const OKrb5Credential *creds, struct OKrb5GSSContext *gss_creds)
struct OKrb5Target target
OM_uint32 gss_want_flags
gss_cred_id_t gss_creds
gss_name_t gss_target
gss_channel_bindings_t gss_channel_bindings
OM_uint32 gss_time_req
OM_uint32 gss_got_flags
OM_uint32 gss_time_rec
gss_OID gss_actual_mech_type
struct OKrb5Slice service
struct OKrb5Slice domain
struct OKrb5Slice host_name

References ALLOCATE_AND_CHECK, OKrb5Slice::data, OKrb5Target::domain, free(), OKrb5GSSContext::gss_actual_mech_type, OKrb5GSSContext::gss_channel_bindings, OKrb5GSSContext::gss_creds, OKrb5GSSContext::gss_got_flags, OKrb5GSSContext::gss_mech, gss_mech_spnego, OKrb5GSSContext::gss_target, OKrb5GSSContext::gss_time_rec, OKrb5GSSContext::gss_time_req, OKrb5GSSContext::gss_want_flags, OKrb5Target::host_name, OKrb5Slice::len, O_KRB5_ERROR, O_KRB5_SUCCESS, okrb5_gss_authenticate(), OKrb5Credential::realm, OKrb5Target::service, and OKrb5Credential::target.

Referenced by nasl_okrb5_gss_prepare_context().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ o_krb5_gss_session_key_context()

OKrb5ErrorCode o_krb5_gss_session_key_context ( struct OKrb5GSSContext * gss_context,
struct OKrb5Slice ** out )

Definition at line 571 of file openvas-krb5.c.

573{
574 OM_uint32 maj_stat;
575 OM_uint32 min_stat;
577 gss_OID_desc gse_sesskey_inq_oid = {
580 };
581 gss_buffer_set_t set = GSS_C_NO_BUFFER_SET;
582
583 maj_stat = gss_inquire_sec_context_by_oid (&min_stat, gss_context->gss_ctx,
584 &gse_sesskey_inq_oid, &set);
585 if (maj_stat != GSS_S_COMPLETE)
586 {
587 result = O_KRB5_ERROR + maj_stat;
588 goto result;
589 }
590
591 if ((set == GSS_C_NO_BUFFER_SET) || (set->count == 0)
592 || (set->elements[0].length == 0))
593 {
594 result = O_KRB5_ERROR + GSS_S_BAD_SIG;
595 goto result;
596 }
597
598 *out = calloc (1, sizeof (struct OKrb5Slice));
599 (*out)->data = malloc (set->elements[0].length);
600 memcpy ((*out)->data, set->elements[0].value, set->elements[0].length);
601 (*out)->len = set->elements[0].length;
602 gss_release_buffer_set (&min_stat, &set);
603result:
604 return result;
605}
void * malloc(YYSIZE_T)
#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH
#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID
gss_ctx_id_t gss_ctx

References OKrb5GSSContext::gss_ctx, GSS_KRB5_INQ_SSPI_SESSION_KEY_OID, GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH, malloc(), O_KRB5_ERROR, and O_KRB5_SUCCESS.

Referenced by nasl_okrb5_gss_session_key_context().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ o_krb5_gss_update_context()

OKrb5ErrorCode o_krb5_gss_update_context ( struct OKrb5GSSContext * gss_context,
const struct OKrb5Slice * in_data,
struct OKrb5Slice ** out_data,
bool * more )

Definition at line 529 of file openvas-krb5.c.

532{
533 OM_uint32 maj_stat;
534 OM_uint32 min_stat;
536 gss_buffer_desc in_buf = {
537 .length = in_data->len,
538 .value = in_data->data,
539 };
540 gss_buffer_desc out_buf = GSS_C_EMPTY_BUFFER;
541
542 maj_stat = gss_init_sec_context (
543 &min_stat, gss_context->gss_creds, &gss_context->gss_ctx,
544 gss_context->gss_target, gss_context->gss_mech, gss_context->gss_want_flags,
545 gss_context->gss_time_req, gss_context->gss_channel_bindings, &in_buf,
546 &gss_context->gss_actual_mech_type, &out_buf, &gss_context->gss_got_flags,
547 &gss_context->gss_time_rec);
548 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
549 {
550 result = O_KRB5_ERROR + maj_stat;
551 goto result;
552 }
553 if ((*out_data = malloc (sizeof (struct OKrb5Slice))) == NULL)
554 {
555 result = O_KRB5_NOMEM;
556 gss_release_buffer (&min_stat, &out_buf);
557 goto result;
558 }
559 // transfers ownership of out_buf.value into out_data->data.
560 // This simplifies the code as we don't have to alloc and check if the system
561 // had sufficient memory and don't have to memcpy.
562 (*out_data)->data = out_buf.value;
563 (*out_data)->len = out_buf.length;
564
565 *more = maj_stat == GSS_S_CONTINUE_NEEDED;
566result:
567 return result;
568}

References OKrb5Slice::data, OKrb5GSSContext::gss_actual_mech_type, OKrb5GSSContext::gss_channel_bindings, OKrb5GSSContext::gss_creds, OKrb5GSSContext::gss_ctx, OKrb5GSSContext::gss_got_flags, OKrb5GSSContext::gss_mech, OKrb5GSSContext::gss_target, OKrb5GSSContext::gss_time_rec, OKrb5GSSContext::gss_time_req, OKrb5GSSContext::gss_want_flags, OKrb5Slice::len, malloc(), O_KRB5_ERROR, O_KRB5_NOMEM, and O_KRB5_SUCCESS.

Referenced by nasl_okrb5_gss_update_context().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ o_krb5_write_realm()

OKrb5ErrorCode o_krb5_write_realm ( FILE * file,
const OKrb5Credential * creds,
const char * kdc )
static

Definition at line 215 of file openvas-krb5.c.

216{
218 CHECK_FPRINTF (result, file, "%s = {\n", (char *) creds->realm.data);
219 const char *kdc_delimiter = strchr (kdc, ',');
220 const char *kdc_start = kdc;
221 const char *kdc_first_start = kdc_start;
222 const char *kdc_first_end =
223 kdc_delimiter != NULL ? kdc_delimiter : kdc + strlen (kdc);
224
225 o_krb5_write_trimmed (file, " kdc", kdc_first_start, kdc_first_end);
226 if (kdc_delimiter != NULL)
227 {
228 kdc_start = kdc_delimiter + 1;
229 while ((kdc_delimiter = strchr (kdc_start, ',')) != NULL)
230 {
231 o_krb5_write_trimmed (file, " kdc", kdc_start, kdc_delimiter);
232 kdc_start = kdc_delimiter + 1;
233 }
234
235 o_krb5_write_trimmed (file, " kdc", kdc_start, kdc + strlen (kdc));
236 }
237 o_krb5_write_trimmed (file, " admin_server", kdc_first_start, kdc_first_end);
238 o_krb5_write_trimmed (file, " master_kdc", kdc_first_start, kdc_first_end);
239 CHECK_FPRINT (result, file, "\n}\n");
240
241result:
242 return result;
243}
#define CHECK_FPRINTF(result, writer, fmt,...)
static OKrb5ErrorCode o_krb5_write_trimmed(FILE *file, const char *prefix, const char *start, const char *end)

References CHECK_FPRINT, CHECK_FPRINTF, OKrb5Slice::data, O_KRB5_SUCCESS, o_krb5_write_trimmed(), and OKrb5Credential::realm.

Referenced by o_krb5_add_realm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ o_krb5_write_trimmed()

OKrb5ErrorCode o_krb5_write_trimmed ( FILE * file,
const char * prefix,
const char * start,
const char * end )
static

Definition at line 199 of file openvas-krb5.c.

201{
203 while (start < end && isspace ((unsigned char) *start))
204 start++;
205 while (end > start && isspace ((unsigned char) *(end - 1)))
206 end--;
207 CHECK_FPRINTF (result, file, "%s = %.*s\n", prefix, (int) (end - start),
208 start);
209
210result:
211 return result;
212}
static void prefix(int n, int i)
Definition nasl_tree.c:219

References CHECK_FPRINTF, O_KRB5_SUCCESS, and prefix().

Referenced by o_krb5_write_realm().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ okrb5_error_code_to_string()

char * okrb5_error_code_to_string ( const OKrb5ErrorCode code)

Definition at line 608 of file openvas-krb5.c.

609{
610#define HEAP_STRING(var, s) \
611 do \
612 { \
613 var = calloc (1, strlen (s) + 1); \
614 snprintf (var, strlen (s) + 1, s); \
615 goto result; \
616 } \
617 while (0)
618
619 char *result = NULL;
620 switch (code)
621 {
622 case O_KRB5_SUCCESS:
623 HEAP_STRING (result, "success");
625 HEAP_STRING (result, "krb5.conf not found");
627 HEAP_STRING (result, "krb5.conf not created");
629 HEAP_STRING (result, "tmp krb5.conf not created");
631 HEAP_STRING (result, "tmp krb5.conf not moved");
633 HEAP_STRING (result, "realm not found");
635 HEAP_STRING (result, "expected null");
637 HEAP_STRING (result, "expected not null");
639 HEAP_STRING (result, "unable to write");
640 case O_KRB5_NOMEM:
641 HEAP_STRING (result, "no memory");
642 default:
643 if (code >= O_KRB5_ERROR)
644 {
645 int maj_stat = code - O_KRB5_ERROR;
646 OM_uint32 min_stat;
647 gss_buffer_desc msg;
648 OM_uint32 msg_ctx = 0;
649
650 (void) gss_display_status (&min_stat, maj_stat, GSS_C_GSS_CODE,
651 GSS_C_NULL_OID, &msg_ctx, &msg);
652 // Instead of calling gss_release_buffer, we transfer ownership of
653 // msg.value (a heap-allocated string) directly to result.
654 // The caller is responsible for freeing result later, this conforms
655 // to other values as well.
656 //
657 // msg itself is stack-allocated, but msg.value is dynamically
658 // allocated, so we must not call gss_release_buffer on msg after
659 // ownership transfer.
660 result = msg.value;
661 }
662 else
663 {
664 goto result;
665 }
666 }
667result:
668 return result;
669}
#define code
#define HEAP_STRING(var, s)

References code, HEAP_STRING, O_KRB5_CONF_NOT_CREATED, O_KRB5_CONF_NOT_FOUND, O_KRB5_ERROR, O_KRB5_EXPECTED_NOT_NULL, O_KRB5_EXPECTED_NULL, O_KRB5_NOMEM, O_KRB5_REALM_NOT_FOUND, O_KRB5_SUCCESS, O_KRB5_TMP_CONF_NOT_CREATED, O_KRB5_TMP_CONF_NOT_MOVED, and O_KRB5_UNABLE_TO_WRITE.

Referenced by nasl_okrb5_error_code_to_string().

Here is the caller graph for this function:

◆ okrb5_gss_authenticate()

OKrb5ErrorCode okrb5_gss_authenticate ( const OKrb5Credential * creds,
struct OKrb5GSSContext * gss_creds )
static

Definition at line 322 of file openvas-krb5.c.

324{
325#define CHECK_MAJOR_STAT() \
326 if (maj_stat != GSS_S_COMPLETE) \
327 { \
328 result = O_KRB5_ERROR + maj_stat; \
329 goto result; \
330 }
331 char *user_principal;
332 const struct OKrb5User *user = &creds->user;
333 size_t user_principal_len = user->user.len + creds->realm.len + 1;
334 size_t user_principal_cap = user_principal_len + 1;
335
337 ALLOCATE_AND_CHECK (user_principal, char, user_principal_cap, result);
338 snprintf (user_principal, user_principal_cap, "%s@%s",
339 (char *) user->user.data, (char *) creds->realm.data);
340
341 gss_name_t gss_username = GSS_C_NO_NAME;
342 OM_uint32 maj_stat;
343 OM_uint32 min_stat;
344 // OM_uint32 dummy_min_stat;
345 gss_buffer_desc userbuf = {
346 .value = user_principal,
347 .length = user_principal_len,
348 };
349 gss_buffer_desc pwbuf = {
350 .value = user->password.data,
351 .length = user->password.len,
352 };
353 gss_OID_desc elements[] = {
354 *gss_mech_krb5,
355#ifdef __USE_IAKERB
356 *gss_mech_iakerb,
357#endif /* __USE_IAKERB */
359 };
360 gss_OID_set_desc creds_mechs = {
361 .elements = elements,
362 .count = ARRAY_SIZE (elements),
363 };
364 gss_OID_set_desc spnego_mechs = {
365 .elements = elements,
366 .count = ARRAY_SIZE (elements) - 1, /* without gss_mech_spnego */
367 };
368 gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
369
370 maj_stat =
371 gss_import_name (&min_stat, &userbuf, GSS_C_NT_USER_NAME, &gss_username);
373
374 maj_stat = gss_acquire_cred_with_password (&min_stat, gss_username, &pwbuf, 0,
375 &creds_mechs, GSS_C_INITIATE,
376 &cred, NULL, NULL);
377
378 (void) gss_release_name (&min_stat, &gss_username);
380
381 // let spnego only use the desired mechs
382 maj_stat = gss_set_neg_mechs (&min_stat, cred, &spnego_mechs);
384 gss_creds->gss_creds = cred;
385result:
386 if (user_principal != NULL)
387 free (user_principal);
388 return result;
389}
#define CHECK_MAJOR_STAT()
#define ARRAY_SIZE(a)
struct OKrb5User user
struct OKrb5Slice user

References ALLOCATE_AND_CHECK, ARRAY_SIZE, CHECK_MAJOR_STAT, OKrb5Slice::data, free(), OKrb5GSSContext::gss_creds, gss_mech_spnego, OKrb5Slice::len, O_KRB5_SUCCESS, OKrb5Credential::realm, OKrb5Credential::user, and OKrb5User::user.

Referenced by o_krb5_gss_prepare_context().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ okrb5_gss_free_context()

void okrb5_gss_free_context ( struct OKrb5GSSContext * context)

Definition at line 405 of file openvas-krb5.c.

406{
407 OM_uint32 min_stat;
408 if (context != NULL)
409 {
410 if (context->gss_creds != GSS_C_NO_CREDENTIAL)
411 {
412 gss_release_cred (&min_stat, &context->gss_creds);
413 }
414 if (context->gss_ctx != GSS_C_NO_CONTEXT)
415 {
416 gss_delete_sec_context (&min_stat, &context->gss_ctx,
417 GSS_C_NO_BUFFER);
418 }
419 if (context->gss_target != GSS_C_NO_NAME)
420 {
421 gss_release_name (&min_stat, &context->gss_target);
422 }
423 if (context->gss_mech != NULL && context->gss_mech != gss_mech_spnego)
424 {
425 gss_release_oid (&min_stat, &context->gss_mech);
426 }
427 if (context->gss_channel_bindings != GSS_C_NO_CHANNEL_BINDINGS)
428 {
429 gss_release_buffer (
430 NULL, &context->gss_channel_bindings->initiator_address);
431 gss_release_buffer (&min_stat,
432 &context->gss_channel_bindings->acceptor_address);
433 gss_release_buffer (&min_stat,
434 &context->gss_channel_bindings->application_data);
435 free (context->gss_channel_bindings);
436 }
437 if (context->gss_actual_mech_type != NULL)
438 {
439 gss_release_oid (&min_stat, &context->gss_actual_mech_type);
440 }
441 free (context);
442 }
443}

References free(), OKrb5GSSContext::gss_actual_mech_type, OKrb5GSSContext::gss_channel_bindings, OKrb5GSSContext::gss_creds, OKrb5GSSContext::gss_ctx, OKrb5GSSContext::gss_mech, gss_mech_spnego, and OKrb5GSSContext::gss_target.

Referenced by nasl_okrb5_clean().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ okrb5_gss_init_context()

struct OKrb5GSSContext * okrb5_gss_init_context ( void )

Definition at line 392 of file openvas-krb5.c.

393{
394 struct OKrb5GSSContext *context = calloc (1, sizeof (struct OKrb5GSSContext));
395 if (context == NULL)
396 {
397 return NULL;
398 }
399 context->gss_creds = GSS_C_NO_CREDENTIAL;
400 context->gss_ctx = GSS_C_NO_CONTEXT;
401 return context;
402}

References OKrb5GSSContext::gss_creds, and OKrb5GSSContext::gss_ctx.

Referenced by nasl_okrb5_gss_init(), and nasl_okrb5_gss_prepare_context().

Here is the caller graph for this function:

Variable Documentation

◆ spnego_mech_oid_desc

gss_OID_desc spnego_mech_oid_desc = {6, (void *) "\x2b\x06\x01\x05\x05\x02"}

Definition at line 76 of file openvas-krb5.c.

76{6, (void *) "\x2b\x06\x01\x05\x05\x02"};