OpenVAS Scanner 23.45.1
openvas-krb5.c File Reference
#include "openvas-krb5.h"
#include <ctype.h>
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_krb5.h>
#include <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 43 of file openvas-krb5.c.

43#define ALLOCATE_AND_CHECK(var, type, n, return_var) \
44 do \
45 { \
46 var = (type *) calloc (n, sizeof (type)); \
47 if (var == NULL) \
48 { \
49 return_var = O_KRB5_NOMEM; \
50 goto result; \
51 } \
52 } \
53 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 84 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 191 of file openvas-krb5.c.

191#define CHECK_FPRINT(result, writer, fmt) \
192 do \
193 { \
194 if (fprintf (writer, fmt) < 0) \
195 { \
196 result = O_KRB5_UNABLE_TO_WRITE; \
197 goto result; \
198 } \
199 } \
200 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 180 of file openvas-krb5.c.

180#define CHECK_FPRINTF(result, writer, fmt, ...) \
181 do \
182 { \
183 if (fprintf (writer, fmt, __VA_ARGS__) < 0) \
184 { \
185 result = O_KRB5_UNABLE_TO_WRITE; \
186 goto result; \
187 } \
188 } \
189 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 76 of file openvas-krb5.c.

76#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID \
77 "\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 74 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 32 of file openvas-krb5.c.

32#define GUARD_NOT_NULL(var, return_var) \
33 do \
34 { \
35 if (var == NULL) \
36 { \
37 return_var = O_KRB5_EXPECTED_NOT_NULL; \
38 goto result; \
39 } \
40 } \
41 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 21 of file openvas-krb5.c.

21#define GUARD_NULL(var, return_var) \
22 do \
23 { \
24 if (var != NULL) \
25 { \
26 return_var = O_KRB5_EXPECTED_NULL; \
27 goto result; \
28 } \
29 } \
30 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 68 of file openvas-krb5.c.

68#define IS_STR_EQUAL(line, line_len, start, cmp, cmp_len) \
69 ((line_len - start < cmp_len) ? 0 \
70 : (line_len == 0 && cmp_len == 0) \
71 ? 1 \
72 : (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 86 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 55 of file openvas-krb5.c.

55#define SKIP_WS(line, line_len, start, i) \
56 do \
57 { \
58 for (i = start; i < line_len; i++) \
59 { \
60 if (line[i] != ' ' && line[i] != '\t') \
61 { \
62 break; \
63 } \
64 } \
65 } \
66 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 251 of file openvas-krb5.c.

252{
254 FILE *file = NULL, *tmp = NULL;
255 char line[MAX_LINE_LENGTH] = {0};
256 char tmpfn[MAX_LINE_LENGTH] = {0};
257 int state, i;
258 char *cp = (char *) creds->config_path.data;
259
260 if ((file = fopen (cp, "r")) == NULL)
261 {
262 if ((file = fopen (cp, "w")) == NULL)
263 {
265 goto result;
266 }
267 CHECK_FPRINT (result, file, "[realms]\n");
268 o_krb5_write_realm (file, creds, kdc);
269 goto result;
270 }
271 snprintf (tmpfn, MAX_LINE_LENGTH, "%s.tmp", cp);
272 if ((tmp = fopen (tmpfn, "w")) == NULL)
273 {
275 goto result;
276 }
277 state = 0;
278 while (fgets (line, MAX_LINE_LENGTH, file))
279 {
280 fputs (line, tmp);
281 if (state == 0)
282 {
283 SKIP_WS (line, MAX_LINE_LENGTH, 0, i);
284 if (IS_STR_EQUAL (line, MAX_LINE_LENGTH, i, "[realms]", 8) == 1)
285 {
286 o_krb5_write_realm (file, creds, kdc);
287
288 state = 1;
289 }
290 }
291 }
292
293 if (rename (tmpfn, cp) != 0)
294 {
296 }
297
298result:
299 if (tmp != NULL)
300 fclose (tmp);
301 if (file != NULL)
302 fclose (file);
303 return result;
304}
#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 89 of file openvas-krb5.c.

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

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

577{
578 OM_uint32 maj_stat;
579 OM_uint32 min_stat;
581 gss_OID_desc gse_sesskey_inq_oid = {
584 };
585 gss_buffer_set_t set = GSS_C_NO_BUFFER_SET;
586
587 maj_stat = gss_inquire_sec_context_by_oid (&min_stat, gss_context->gss_ctx,
588 &gse_sesskey_inq_oid, &set);
589 if (maj_stat != GSS_S_COMPLETE)
590 {
591 result = O_KRB5_ERROR + maj_stat;
592 goto result;
593 }
594
595 if ((set == GSS_C_NO_BUFFER_SET) || (set->count == 0)
596 || (set->elements[0].length == 0))
597 {
598 result = O_KRB5_ERROR + GSS_S_BAD_SIG;
599 goto result;
600 }
601
602 *out = calloc (1, sizeof (struct OKrb5Slice));
603 (*out)->data = malloc (set->elements[0].length);
604 memcpy ((*out)->data, set->elements[0].value, set->elements[0].length);
605 (*out)->len = set->elements[0].length;
606 gss_release_buffer_set (&min_stat, &set);
607result:
608 return result;
609}
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 533 of file openvas-krb5.c.

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

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 219 of file openvas-krb5.c.

220{
222 CHECK_FPRINTF (result, file, "%s = {\n", (char *) creds->realm.data);
223 const char *kdc_delimiter = strchr (kdc, ',');
224 const char *kdc_start = kdc;
225 const char *kdc_first_start = kdc_start;
226 const char *kdc_first_end =
227 kdc_delimiter != NULL ? kdc_delimiter : kdc + strlen (kdc);
228
229 o_krb5_write_trimmed (file, " kdc", kdc_first_start, kdc_first_end);
230 if (kdc_delimiter != NULL)
231 {
232 kdc_start = kdc_delimiter + 1;
233 while ((kdc_delimiter = strchr (kdc_start, ',')) != NULL)
234 {
235 o_krb5_write_trimmed (file, " kdc", kdc_start, kdc_delimiter);
236 kdc_start = kdc_delimiter + 1;
237 }
238
239 o_krb5_write_trimmed (file, " kdc", kdc_start, kdc + strlen (kdc));
240 }
241 o_krb5_write_trimmed (file, " admin_server", kdc_first_start, kdc_first_end);
242 o_krb5_write_trimmed (file, " master_kdc", kdc_first_start, kdc_first_end);
243 CHECK_FPRINT (result, file, "\n}\n");
244
245result:
246 return result;
247}
#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 203 of file openvas-krb5.c.

205{
207 while (start < end && isspace ((unsigned char) *start))
208 start++;
209 while (end > start && isspace ((unsigned char) *(end - 1)))
210 end--;
211 CHECK_FPRINTF (result, file, "%s = %.*s\n", prefix, (int) (end - start),
212 start);
213
214result:
215 return result;
216}
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 612 of file openvas-krb5.c.

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

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

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

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 396 of file openvas-krb5.c.

397{
398 struct OKrb5GSSContext *context = calloc (1, sizeof (struct OKrb5GSSContext));
399 if (context == NULL)
400 {
401 return NULL;
402 }
403 context->gss_creds = GSS_C_NO_CREDENTIAL;
404 context->gss_ctx = GSS_C_NO_CONTEXT;
405 return context;
406}

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 80 of file openvas-krb5.c.

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