[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-30 Thread cron2 (Code Review)
cron2 has uploaded a new patch set (#6) to the change originally created by 
flichtenheld. ( http://gerrit.openvpn.net/c/openvpn/+/476?usp=email )

The following approvals got outdated and were removed:
Code-Review+2 by cron2


Change subject: misc: make get_auth_challenge static
..

misc: make get_auth_challenge static

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 
Acked-by: Gert Doering 
Message-Id: <20231230143248.1625-1-g...@greenie.muc.de>
URL: 
https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg27864.html
Signed-off-by: Gert Doering 
---
M src/openvpn/misc.c
M src/openvpn/misc.h
M src/openvpn/ssl.h
3 files changed, 79 insertions(+), 85 deletions(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/76/476/6

diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index bce63ed..08f274d 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -124,6 +124,83 @@
 }
 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(, (const uint8_t *)auth_challenge, len);
+
+ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
+
+/* parse prefix */
+if (!buf_parse(, ':', work, len))
+{
+return NULL;
+}
+if (strcmp(work, "CRV1"))
+{
+return NULL;
+}
+
+/* parse flags */
+if (!buf_parse(, ':', 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(, ':', work, len))
+{
+return NULL;
+}
+ac->state_id = string_alloc(work, gc);
+
+/* parse user name */
+if (!buf_parse(, ':', 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(), gc);
+
+return ac;
+}
+
 #endif /* ifdef ENABLE_MANAGEMENT */

 /*
@@ -287,7 +364,7 @@
 #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, );
+struct auth_challenge_info *ac = 
parse_auth_challenge(auth_challenge, );
 if (ac)
 {
 char *response = (char *) gc_malloc(USER_PASS_LEN, false, 
);
@@ -392,83 +469,6 @@
 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(, (const uint8_t *)auth_challenge, len);
-
-ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
-
-/* parse prefix */
-if (!buf_parse(, ':', work, len))
-{
-return NULL;
-}
-if (strcmp(work, "CRV1"))
-{
-return NULL;
-}
-
-/* parse flags */
-if (!buf_parse(, ':', work, len))
-{
-return NULL;
-}
-for (cp = work; *cp != '\0'; ++cp)
-{
-const char c = *cp;
-if (c == 'E')
-{
-ac->flags |= CR_ECHO;
-}
- 

[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-30 Thread cron2 (Code Review)
cron2 has submitted this change. ( 
http://gerrit.openvpn.net/c/openvpn/+/476?usp=email )

Change subject: misc: make get_auth_challenge static
..

misc: make get_auth_challenge static

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 
Acked-by: Gert Doering 
Message-Id: <20231230143248.1625-1-g...@greenie.muc.de>
URL: 
https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg27864.html
Signed-off-by: Gert Doering 
---
M src/openvpn/misc.c
M src/openvpn/misc.h
M src/openvpn/ssl.h
3 files changed, 79 insertions(+), 85 deletions(-)




diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index bce63ed..08f274d 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -124,6 +124,83 @@
 }
 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(, (const uint8_t *)auth_challenge, len);
+
+ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
+
+/* parse prefix */
+if (!buf_parse(, ':', work, len))
+{
+return NULL;
+}
+if (strcmp(work, "CRV1"))
+{
+return NULL;
+}
+
+/* parse flags */
+if (!buf_parse(, ':', 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(, ':', work, len))
+{
+return NULL;
+}
+ac->state_id = string_alloc(work, gc);
+
+/* parse user name */
+if (!buf_parse(, ':', 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(), gc);
+
+return ac;
+}
+
 #endif /* ifdef ENABLE_MANAGEMENT */

 /*
@@ -287,7 +364,7 @@
 #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, );
+struct auth_challenge_info *ac = 
parse_auth_challenge(auth_challenge, );
 if (ac)
 {
 char *response = (char *) gc_malloc(USER_PASS_LEN, false, 
);
@@ -392,83 +469,6 @@
 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(, (const uint8_t *)auth_challenge, len);
-
-ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
-
-/* parse prefix */
-if (!buf_parse(, ':', work, len))
-{
-return NULL;
-}
-if (strcmp(work, "CRV1"))
-{
-return NULL;
-}
-
-/* parse flags */
-if (!buf_parse(, ':', 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(, ':', work, len))
-{
-

[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-30 Thread cron2 (Code Review)
Attention is currently required from: flichtenheld, plaisthos.

cron2 has posted comments on this change. ( 
http://gerrit.openvpn.net/c/openvpn/+/476?usp=email )

Change subject: misc: make get_auth_challenge static
..


Patch Set 5: Code-Review+2


--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/476?usp=email
To unsubscribe, or for help writing mail filters, visit 
http://gerrit.openvpn.net/settings

Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613
Gerrit-Change-Number: 476
Gerrit-PatchSet: 5
Gerrit-Owner: flichtenheld 
Gerrit-Reviewer: cron2 
Gerrit-Reviewer: plaisthos 
Gerrit-CC: openvpn-devel 
Gerrit-Attention: plaisthos 
Gerrit-Attention: flichtenheld 
Gerrit-Comment-Date: Sat, 30 Dec 2023 14:30:28 +
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-12 Thread flichtenheld (Code Review)
Attention is currently required from: flichtenheld, plaisthos.

Hello plaisthos,

I'd like you to reexamine a change. Please visit

http://gerrit.openvpn.net/c/openvpn/+/476?usp=email

to look at the new patch set (#3).

The following approvals got outdated and were removed:
Code-Review+2 by plaisthos


Change subject: misc: make get_auth_challenge static
..

misc: make get_auth_challenge static

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 
---
M src/openvpn/misc.c
M src/openvpn/misc.h
M src/openvpn/ssl.h
3 files changed, 98 insertions(+), 85 deletions(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/76/476/3

diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index bce63ed..08f274d 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -124,6 +124,83 @@
 }
 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(, (const uint8_t *)auth_challenge, len);
+
+ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
+
+/* parse prefix */
+if (!buf_parse(, ':', work, len))
+{
+return NULL;
+}
+if (strcmp(work, "CRV1"))
+{
+return NULL;
+}
+
+/* parse flags */
+if (!buf_parse(, ':', 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(, ':', work, len))
+{
+return NULL;
+}
+ac->state_id = string_alloc(work, gc);
+
+/* parse user name */
+if (!buf_parse(, ':', 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(), gc);
+
+return ac;
+}
+
 #endif /* ifdef ENABLE_MANAGEMENT */

 /*
@@ -287,7 +364,7 @@
 #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, );
+struct auth_challenge_info *ac = 
parse_auth_challenge(auth_challenge, );
 if (ac)
 {
 char *response = (char *) gc_malloc(USER_PASS_LEN, false, 
);
@@ -392,83 +469,6 @@
 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(, (const uint8_t *)auth_challenge, len);
-
-ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
-
-/* parse prefix */
-if (!buf_parse(, ':', work, len))
-{
-return NULL;
-}
-if (strcmp(work, "CRV1"))
-{
-return NULL;
-}
-
-/* parse flags */
-if (!buf_parse(, ':', 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;
-}
-}
-
-

[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-12 Thread flichtenheld (Code Review)
Attention is currently required from: cron2, plaisthos.

flichtenheld has posted comments on this change. ( 
http://gerrit.openvpn.net/c/openvpn/+/476?usp=email )

Change subject: misc: make get_auth_challenge static
..


Patch Set 3:

(1 comment)

File src/openvpn/misc.c:

http://gerrit.openvpn.net/c/openvpn/+/476/comment/74d2e778_f96f18de :
PS2, Line 143: if (auth_challenge)
> If moving this around anyway, we could convert this function to early-return, 
> or even make it an ASS […]
Done



--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/476?usp=email
To unsubscribe, or for help writing mail filters, visit 
http://gerrit.openvpn.net/settings

Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613
Gerrit-Change-Number: 476
Gerrit-PatchSet: 3
Gerrit-Owner: flichtenheld 
Gerrit-Reviewer: plaisthos 
Gerrit-CC: cron2 
Gerrit-CC: openvpn-devel 
Gerrit-Attention: plaisthos 
Gerrit-Attention: cron2 
Gerrit-Comment-Date: Tue, 12 Dec 2023 13:56:40 +
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: cron2 
Gerrit-MessageType: comment
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-11 Thread cron2 (Code Review)
Attention is currently required from: flichtenheld.

cron2 has posted comments on this change. ( 
http://gerrit.openvpn.net/c/openvpn/+/476?usp=email )

Change subject: misc: make get_auth_challenge static
..


Patch Set 2:

(1 comment)

File src/openvpn/misc.c:

http://gerrit.openvpn.net/c/openvpn/+/476/comment/12421107_520d82c3 :
PS2, Line 143: if (auth_challenge)
If moving this around anyway, we could convert this function to early-return, 
or even make it an ASSERT(auth_challenge) since the caller is only ever calling 
it from an "if (auth_challenge & ...") block...



--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/476?usp=email
To unsubscribe, or for help writing mail filters, visit 
http://gerrit.openvpn.net/settings

Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613
Gerrit-Change-Number: 476
Gerrit-PatchSet: 2
Gerrit-Owner: flichtenheld 
Gerrit-Reviewer: plaisthos 
Gerrit-CC: cron2 
Gerrit-CC: openvpn-devel 
Gerrit-Attention: flichtenheld 
Gerrit-Comment-Date: Tue, 12 Dec 2023 07:51:03 +
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-11 Thread plaisthos (Code Review)
Attention is currently required from: flichtenheld.

plaisthos has posted comments on this change. ( 
http://gerrit.openvpn.net/c/openvpn/+/476?usp=email )

Change subject: misc: make get_auth_challenge static
..


Patch Set 2: Code-Review+2


--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/476?usp=email
To unsubscribe, or for help writing mail filters, visit 
http://gerrit.openvpn.net/settings

Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613
Gerrit-Change-Number: 476
Gerrit-PatchSet: 2
Gerrit-Owner: flichtenheld 
Gerrit-Reviewer: plaisthos 
Gerrit-CC: openvpn-devel 
Gerrit-Attention: flichtenheld 
Gerrit-Comment-Date: Mon, 11 Dec 2023 14:59:05 +
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
___
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel


[Openvpn-devel] [M] Change in openvpn[master]: misc: make get_auth_challenge static

2023-12-08 Thread flichtenheld (Code Review)
Attention is currently required from: plaisthos.

Hello plaisthos,

I'd like you to do a code review.
Please visit

http://gerrit.openvpn.net/c/openvpn/+/476?usp=email

to review the following change.


Change subject: misc: make get_auth_challenge static
..

misc: make get_auth_challenge static

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.

Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613
Signed-off-by: Frank Lichtenheld 
---
M src/openvpn/misc.c
M src/openvpn/misc.h
M src/openvpn/ssl.h
3 files changed, 103 insertions(+), 85 deletions(-)



  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/76/476/1

diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
index ce6e4fd..9352843 100644
--- a/src/openvpn/misc.c
+++ b/src/openvpn/misc.c
@@ -124,6 +124,88 @@
 }
 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.
+ * @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)
+{
+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(, (const uint8_t *)auth_challenge, len);
+
+ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
+
+/* parse prefix */
+if (!buf_parse(, ':', work, len))
+{
+return NULL;
+}
+if (strcmp(work, "CRV1"))
+{
+return NULL;
+}
+
+/* parse flags */
+if (!buf_parse(, ':', 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(, ':', work, len))
+{
+return NULL;
+}
+ac->state_id = string_alloc(work, gc);
+
+/* parse user name */
+if (!buf_parse(, ':', 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(), gc);
+
+return ac;
+}
+else
+{
+return NULL;
+}
+}
+
 #endif /* ifdef ENABLE_MANAGEMENT */

 /*
@@ -287,7 +369,7 @@
 #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, );
+struct auth_challenge_info *ac = 
parse_auth_challenge(auth_challenge, );
 if (ac)
 {
 char *response = (char *) gc_malloc(USER_PASS_LEN, false, 
);
@@ -392,83 +474,6 @@
 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(, (const uint8_t *)auth_challenge, len);
-
-ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc);
-
-/* parse prefix */
-if (!buf_parse(, ':', work, len))
-{
-return NULL;
-}
-if (strcmp(work, "CRV1"))
-{
-return NULL;
-}
-
-/* parse flags */
-if (!buf_parse(, ':', 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')
-{
-