Skip to content

Commit

Permalink
misc: make get_auth_challenge static
Browse files Browse the repository at this point in the history
Not used outside of misc.c.

Rename to parse_auth_challenge since it really just parses
the string that you put in into the struct.

Add doxygen documentation.

v2:
 - change if(auth_challenge) to ASSERT(auth_challenge)

Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613
Signed-off-by: Frank Lichtenheld <[email protected]>
Acked-by: Gert Doering <[email protected]>
Message-Id: <[email protected]>
URL: https://www.mail-archive.com/[email protected]/msg27864.html
Signed-off-by: Gert Doering <[email protected]>
  • Loading branch information
flichtenheld authored and cron2 committed Dec 30, 2023
1 parent bfcad5c commit 3075163
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 85 deletions.
156 changes: 78 additions & 78 deletions src/openvpn/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,83 @@ auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int
}
return true;
}

/**
* Parses an authentication challenge string and returns an auth_challenge_info structure.
* The authentication challenge string should follow the dynamic challenge/response protocol.
*
* See doc/management-notes.txt for more info on the the dynamic challenge/response protocol
* implemented here.
*
* @param auth_challenge The authentication challenge string to parse. Can't be NULL.
* @param gc The gc_arena structure for memory allocation.
*
* @return A pointer to the parsed auth_challenge_info structure, or NULL if parsing fails.
*/
static struct auth_challenge_info *
parse_auth_challenge(const char *auth_challenge, struct gc_arena *gc)
{
ASSERT(auth_challenge);

struct auth_challenge_info *ac;
const int len = strlen(auth_challenge);
char *work = (char *) gc_malloc(len+1, false, gc);
char *cp;

struct buffer b;
buf_set_read(&b, (const uint8_t *)auth_challenge, len);

ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);

/* parse prefix */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
if (strcmp(work, "CRV1"))
{
return NULL;
}

/* parse flags */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
for (cp = work; *cp != '\0'; ++cp)
{
const char c = *cp;
if (c == 'E')
{
ac->flags |= CR_ECHO;
}
else if (c == 'R')
{
ac->flags |= CR_RESPONSE;
}
}

/* parse state ID */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
ac->state_id = string_alloc(work, gc);

/* parse user name */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
ac->user = (char *) gc_malloc(strlen(work)+1, true, gc);
openvpn_base64_decode(work, (void *)ac->user, -1);

/* parse challenge text */
ac->challenge_text = string_alloc(BSTR(&b), gc);

return ac;
}

#endif /* ifdef ENABLE_MANAGEMENT */

/*
Expand Down Expand Up @@ -287,7 +364,7 @@ get_user_pass_cr(struct user_pass *up,
#ifdef ENABLE_MANAGEMENT
if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin)
{
struct auth_challenge_info *ac = get_auth_challenge(auth_challenge, &gc);
struct auth_challenge_info *ac = parse_auth_challenge(auth_challenge, &gc);
if (ac)
{
char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
Expand Down Expand Up @@ -392,83 +469,6 @@ get_user_pass_cr(struct user_pass *up,
return true;
}

#ifdef ENABLE_MANAGEMENT

/*
* See management/management-notes.txt for more info on the
* the dynamic challenge/response protocol implemented here.
*/
struct auth_challenge_info *
get_auth_challenge(const char *auth_challenge, struct gc_arena *gc)
{
if (auth_challenge)
{
struct auth_challenge_info *ac;
const int len = strlen(auth_challenge);
char *work = (char *) gc_malloc(len+1, false, gc);
char *cp;

struct buffer b;
buf_set_read(&b, (const uint8_t *)auth_challenge, len);

ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);

/* parse prefix */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
if (strcmp(work, "CRV1"))
{
return NULL;
}

/* parse flags */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
for (cp = work; *cp != '\0'; ++cp)
{
const char c = *cp;
if (c == 'E')
{
ac->flags |= CR_ECHO;
}
else if (c == 'R')
{
ac->flags |= CR_RESPONSE;
}
}

/* parse state ID */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
ac->state_id = string_alloc(work, gc);

/* parse user name */
if (!buf_parse(&b, ':', work, len))
{
return NULL;
}
ac->user = (char *) gc_malloc(strlen(work)+1, true, gc);
openvpn_base64_decode(work, (void *)ac->user, -1);

/* parse challenge text */
ac->challenge_text = string_alloc(BSTR(&b), gc);

return ac;
}
else
{
return NULL;
}
}

#endif /* ifdef ENABLE_MANAGEMENT */

void
purge_user_pass(struct user_pass *up, const bool force)
{
Expand Down
2 changes: 0 additions & 2 deletions src/openvpn/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ struct auth_challenge_info {
const char *challenge_text;
};

struct auth_challenge_info *get_auth_challenge(const char *auth_challenge, struct gc_arena *gc);

/*
* Challenge response info on client as pushed by server.
*/
Expand Down
6 changes: 1 addition & 5 deletions src/openvpn/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,7 @@ void ssl_set_auth_token_user(const char *username);
bool ssl_clean_auth_token(void);

#ifdef ENABLE_MANAGEMENT
/*
* ssl_get_auth_challenge will parse the server-pushed auth-failed
* reason string and return a dynamically allocated
* auth_challenge_info struct.
*/

void ssl_purge_auth_challenge(void);

void ssl_put_auth_challenge(const char *cr_str);
Expand Down

0 comments on commit 3075163

Please sign in to comment.