Skip to content

Commit

Permalink
Add additional functions for krb5
Browse files Browse the repository at this point in the history
This allows to authenticate against a kdc as well as creating data to
send to and from the target.
  • Loading branch information
nichtsfrei committed Oct 3, 2024
1 parent ab0a27c commit 044a251
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 33 deletions.
32 changes: 17 additions & 15 deletions kerberos/authenticate_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@
#include <stdlib.h>
#include <string.h>

#define GUARD_ENV_SET(var, env) \
do \
{ \
var = okrb5_slice_from_str (getenv (env)); \
if (var.len == 0) \
{ \
fprintf (stderr, env " is not set\n"); \
return 1; \
} \
} \
#define GUARD_ENV_SET(var, env) \
do \
{ \
okrb5_set_slice_from_str (var, getenv (env)); \
if (var.len == 0) \
{ \
fprintf (stderr, env " is not set\n"); \
return 1; \
} \
} \
while (0)

struct OKrb5GSSContext *cached_gss_context = NULL;
int
main ()
{
char *kdc = NULL;
OKrb5ErrorCode result = O_KRB5_SUCCESS;
OKrb5Credential credentials;
OKrb5GSSContext *context = NULL;

memset (&credentials, 0, sizeof (OKrb5Credential));
struct OKrb5Slice from_application = {.data = NULL, .len = 0};
struct OKrb5Slice *to_application = NULL;
bool more = false;
Expand Down Expand Up @@ -50,17 +52,17 @@ main ()
// printf ("Using kdc: %s\n", kdc);
// free (kdc);
// }
context = okrb5_gss_init_context ();
cached_gss_context = okrb5_gss_init_context ();
printf ("Using realm: %s\n", (char *) credentials.realm.data);
if ((result = o_krb5_gss_prepare_context (&credentials, context)))
if ((result = o_krb5_gss_prepare_context (&credentials, cached_gss_context)))
{
fprintf (stderr, "Unable to prepare context: %d\n", result);
return 1;
}
printf ("Using realm: %s\n", (char *) credentials.realm.data);
// first call always empty
if ((result = o_krb5_gss_update_context (context, &from_application,
&to_application, &more)))
if ((result = o_krb5_gss_update_context (
cached_gss_context, &from_application, &to_application, &more)))
{
fprintf (stderr, "Unable to update context: %d\n", result);
return 1;
Expand Down
1 change: 1 addition & 0 deletions misc/openvas-krb5.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ o_krb5_gss_prepare_context (const OKrb5Credential *creds,
gss_buffer_desc targetbuf = GSS_C_EMPTY_BUFFER;
const struct OKrb5Target *target = &creds->target;


if (gss_context->gss_creds == GSS_C_NO_CREDENTIAL)
{
if ((result = okrb5_gss_authenticate (creds, gss_context)))
Expand Down
1 change: 1 addition & 0 deletions misc/openvas-krb5.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ o_krb5_gss_session_key_context (struct OKrb5GSSContext *gss_context,
struct OKrb5Slice **out);

struct OKrb5GSSContext *okrb5_gss_init_context (void);

void okrb5_gss_free_context (struct OKrb5GSSContext *context);

OKrb5ErrorCode
Expand Down
14 changes: 10 additions & 4 deletions nasl/nasl_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@
#include "nasl_http.h"
#include "nasl_http2.h"
#include "nasl_isotime.h"
#include "nasl_krb5.h"
#include "nasl_lex_ctxt.h"
#include "nasl_misc_funcs.h"
#include "nasl_packet_forgery.h"
#include "nasl_packet_forgery_v6.h"
#include "nasl_krb5.h"


#include <stdlib.h> /* for getenv. */
#include <string.h> /* for memset */
Expand Down Expand Up @@ -91,7 +90,7 @@ static init_func libfuncs[] = {
{"get_host_kb_index", get_host_kb_index},
{"security_message", security_message},
{"log_message", log_message},
{"error_message", error_message},
{"error_message", error_message2},
{"open_sock_tcp", nasl_open_sock_tcp},
{"open_sock_udp", nasl_open_sock_udp},
{"open_priv_sock_tcp", nasl_open_priv_sock_tcp},
Expand Down Expand Up @@ -417,7 +416,14 @@ static init_func libfuncs[] = {
{"isotime_print", nasl_isotime_print},
{"isotime_add", nasl_isotime_add},
// krb5
{"krb5_find_kdc", nasl_okrb5_find_kdc },
{"krb5_find_kdc", nasl_okrb5_find_kdc},
{"krb5_is_success", nasl_okrb5_is_success},
{"krb5_is_failure", nasl_okrb5_is_failure},
{"krb5_gss_init", nasl_okrb5_gss_init},
{"krb5_gss_prepare_context", nasl_okrb5_gss_prepare_context},
{"krb5_gss_update_context", nasl_okrb5_gss_update_context},
{"krb5_gss_update_context_needs_more", nasl_okrb5_gss_update_context_needs_more},
{"krb5_gss_update_context_out", nasl_okrb5_gss_update_context_out},
{NULL, NULL}};

/* String variables */
Expand Down
194 changes: 182 additions & 12 deletions nasl/nasl_krb5.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
#include "nasl_lex_ctxt.h"
#include "nasl_tree.h"
#include "nasl_var.h"

#include <stdio.h>
// TODO: add string function for result
#define nasl_print_krb_error(lexic, credential, result) \
nasl_perror (lexic, "%s[config_path: %s realm: %s user: %s] => %d", \
__func__, credential.config_path, credential.realm, \
credential.user, result);
#define nasl_print_krb_error(lexic, credential, result) \
nasl_perror (lexic, "%s[config_path: '%s' realm: '%s' user: '%s'] => %d", \
__func__, credential.config_path.data, credential.realm.data, \
credential.user.user.data, result);

OKrb5ErrorCode last_okrb5_result;

Expand All @@ -26,6 +28,18 @@ OKrb5ErrorCode last_okrb5_result;
} \
while (0)

#define perror_set_slice_from_lex_or_env(lexic, slice, name, env_name) \
do \
{ \
set_slice_from_lex_or_env (lexic, slice, name, env_name); \
if (slice.len == 0) \
{ \
nasl_perror (lexic, "Expected %s or env variable %s", name, \
env_name); \
} \
} \
while (0)

static OKrb5Credential
build_krb5_credential (lex_ctxt *lexic)
{
Expand All @@ -39,11 +53,24 @@ build_krb5_credential (lex_ctxt *lexic)
okrb5_set_slice_from_str (credential.config_path, "/etc/krb5.conf");
}
// TODO: enhance with redis check? maybe.
set_slice_from_lex_or_env (lexic, credential.realm, "realm", "KRB5_REALM");
if (credential.realm.len == 0)

perror_set_slice_from_lex_or_env (lexic, credential.realm, "realm",
"KRB5_REALM");
perror_set_slice_from_lex_or_env (lexic, credential.user.user, "user",
"KRB5_USER");
perror_set_slice_from_lex_or_env (lexic, credential.user.password, "password",
"KRB5_PASSWORD");
perror_set_slice_from_lex_or_env (lexic, credential.target.host_name, "host",
"KRB5_TARGET_HOST");
// set_slice_from_lex_or_env (lexic, credential.target.service, "service",
// "KRB5_TARGET_SERVICE");
if (credential.target.service.len == 0)
{
nasl_print_krb_error (lexic, credential, O_KRB5_REALM_NOT_FOUND);
okrb5_set_slice_from_str (credential.target.service, "cifs");
}
set_slice_from_lex_or_env (lexic, credential.kdc, "kdc", "KRB5_KDC");

memset (&credential.target.domain, 0, sizeof (struct OKrb5Slice));

return credential;
}
Expand Down Expand Up @@ -79,7 +106,7 @@ nasl_okrb5_find_kdc (lex_ctxt *lexic)
if ((last_okrb5_result = o_krb5_find_kdc (&credential, &kdc)))
{
nasl_print_krb_error (lexic, credential, last_okrb5_result);
return NULL;
return FAKE_CELL;
}

retc = alloc_typed_cell (CONST_DATA);
Expand Down Expand Up @@ -142,8 +169,7 @@ nasl_okrb5_result (lex_ctxt *lexic)
tree_cell *
nasl_okrb5_is_success (lex_ctxt *lexic)
{
OKrb5ErrorCode result =
get_int_var_by_name (lexic, "retval", last_okrb5_result);
OKrb5ErrorCode result = get_int_var_by_num (lexic, 0, last_okrb5_result);
tree_cell *retc = alloc_typed_cell (CONST_INT);
retc->x.i_val = result == O_KRB5_SUCCESS;
return retc;
Expand All @@ -164,9 +190,153 @@ nasl_okrb5_is_success (lex_ctxt *lexic)
tree_cell *
nasl_okrb5_is_failure (lex_ctxt *lexic)
{
OKrb5ErrorCode result =
get_int_var_by_name (lexic, "retval", last_okrb5_result);
OKrb5ErrorCode result = get_int_var_by_num (lexic, 0, last_okrb5_result);
tree_cell *retc = alloc_typed_cell (CONST_INT);
retc->x.i_val = result != O_KRB5_SUCCESS;
return retc;
}

// TODO: may need a cacing mechanism for different configurations
// for now we just use one
struct OKrb5GSSContext *cached_gss_context = NULL;

tree_cell *
nasl_okrb5_gss_init (lex_ctxt *lexic)
{
(void) lexic;
if (cached_gss_context != NULL)
{
okrb5_gss_free_context (cached_gss_context);
}
cached_gss_context = okrb5_gss_init_context ();
if (cached_gss_context == NULL)
{
last_okrb5_result = O_KRB5_EXPECTED_NOT_NULL;
}
else
{
last_okrb5_result = O_KRB5_SUCCESS;
};
tree_cell *retc = alloc_typed_cell (CONST_INT);
retc->x.i_val = last_okrb5_result;
return retc;
}
tree_cell *
nasl_okrb5_gss_prepare_context (lex_ctxt *lexic)
{
(void) lexic;

OKrb5Credential credential;
credential = build_krb5_credential (lexic);
OKrb5ErrorCode result = O_KRB5_SUCCESS;
if (cached_gss_context == NULL)
{
cached_gss_context = okrb5_gss_init_context ();
}
result = o_krb5_gss_prepare_context (&credential, cached_gss_context);
tree_cell *retc = alloc_typed_cell (CONST_INT);
retc->x.i_val = result;
last_okrb5_result = result;
return retc;
}

struct OKrb5Slice *to_application = NULL;
bool gss_update_context_more = false;

tree_cell *
nasl_okrb5_gss_update_context (lex_ctxt *lexic)
{
(void) lexic;
OKrb5ErrorCode result = O_KRB5_SUCCESS;
tree_cell *retc;
struct OKrb5Slice from_application;

if (to_application != NULL)
{
free (to_application->data);
free (to_application);
to_application = NULL;
}

okrb5_set_slice_from_str (from_application, get_str_var_by_num (lexic, 0));

if (cached_gss_context == NULL)
{
last_okrb5_result = O_KRB5_EXPECTED_NOT_NULL;
goto result;
}
result =
o_krb5_gss_update_context (cached_gss_context, &from_application,
&to_application, &gss_update_context_more);
result:
retc = alloc_typed_cell (CONST_INT);
retc->x.i_val = result;
last_okrb5_result = result;
return retc;
}

tree_cell *
nasl_okrb5_gss_update_context_needs_more (lex_ctxt *lexic)
{
(void) lexic;
tree_cell *retc = alloc_typed_cell (CONST_INT);
retc->x.i_val = gss_update_context_more;
return retc;
}

tree_cell *
nasl_okrb5_gss_update_context_out (lex_ctxt *lexic)
{
(void) lexic;
if (to_application == NULL)
{
return FAKE_CELL;
}
tree_cell *retc = alloc_typed_cell (CONST_DATA);
retc->x.str_val = to_application->data;
retc->size = to_application->len;
return retc;
}

/*
context = okrb5_gss_init_context ();
printf ("Using realm: %s\n", (char *) credentials.realm.data);
if ((result = o_krb5_gss_prepare_context (&credentials, context)))
{
return 1;
}
printf ("Using realm: %s\n", (char *) credentials.realm.data);
// first call always empty
if ((result = o_krb5_gss_update_context (context, &from_application,
&to_application, &more)))
{
return 1;
}
printf ("success: %d: outdata_len: %zu\n", result, to_application->len);
for (size_t i = 0; i < to_application->len; i++)
{
printf ("%02x", ((char *) to_application->data)[i]);
}
printf ("\n");
*/

/*
*OKrb5ErrorCode
o_krb5_gss_session_key_context (struct OKrb5GSSContext *gss_context,
struct OKrb5Slice **out);
struct OKrb5GSSContext *okrb5_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);
*/
17 changes: 17 additions & 0 deletions nasl/nasl_krb5.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,20 @@ nasl_okrb5_is_success (lex_ctxt *lexic);
tree_cell *
nasl_okrb5_is_failure (lex_ctxt *lexic);

tree_cell *
nasl_okrb5_gss_init (lex_ctxt *lexic);


tree_cell *
nasl_okrb5_gss_prepare_context (lex_ctxt *lexic);


tree_cell *
nasl_okrb5_gss_update_context (lex_ctxt *lexic);


tree_cell *
nasl_okrb5_gss_update_context_needs_more(lex_ctxt *lexic);

tree_cell *
nasl_okrb5_gss_update_context_out (lex_ctxt *lexic);
3 changes: 2 additions & 1 deletion nasl/nasl_scanner_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,8 +1024,9 @@ log_message (lex_ctxt *lexic)
return security_something (lexic, proto_post_log, post_log_with_uri);
}

// FIXME: the name of the function is too broad, krb5 people also hate prefixes
tree_cell *
error_message (lex_ctxt *lexic)
error_message2 (lex_ctxt *lexic)
{
return security_something (lexic, proto_post_error, post_error);
}
Expand Down
2 changes: 1 addition & 1 deletion nasl/nasl_scanner_glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ tree_cell *
log_message (lex_ctxt *);

tree_cell *
error_message (lex_ctxt *);
error_message2 (lex_ctxt *);

tree_cell *
nasl_scanner_get_port (lex_ctxt *);
Expand Down
1 change: 1 addition & 0 deletions rust/examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test.sh
Loading

0 comments on commit 044a251

Please sign in to comment.