Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix openconnect_base64_decode() to return the buffer
Taking a (void **) in which to return the buffer causes complaints about
type-punning pointers in some call sites. Swap the arguments round to return
the buffer instead, and take an (int *) pointer into which we can place the
length (or error) that was previously the return value.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jul 21, 2014
1 parent 1599822 commit 764ce6b
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 30 deletions.
7 changes: 4 additions & 3 deletions gssapi.c
Expand Up @@ -89,9 +89,10 @@ int gssapi_authorization(struct openconnect_info *vpninfo, struct oc_text_buf *h
}

if (vpninfo->auth[AUTH_TYPE_GSSAPI].challenge && *vpninfo->auth[AUTH_TYPE_GSSAPI].challenge) {
int len = openconnect_base64_decode(&in.value, vpninfo->auth[AUTH_TYPE_GSSAPI].challenge);
if (len < 0)
return -EINVAL;
int len = -EINVAL;
in.value = openconnect_base64_decode(&len, vpninfo->auth[AUTH_TYPE_GSSAPI].challenge);
if (!in.value)
return len;
in.length = len;
} else if (vpninfo->auth[AUTH_TYPE_GSSAPI].state > AUTH_AVAILABLE) {
/* This indicates failure. We were trying, but got an empty
Expand Down
32 changes: 17 additions & 15 deletions http.c
Expand Up @@ -1668,18 +1668,22 @@ static inline int b64_char(char c)
return -1;
}

int openconnect_base64_decode(void **out, const char *in)
void *openconnect_base64_decode(int *ret_len, const char *in)
{
unsigned char *buf;
int b[4];
int len = strlen(in);

if (len & 3)
return -EINVAL;
if (len & 3) {
*ret_len = -EINVAL;
return NULL;
}
len = (len * 3) / 4;
*out = buf = malloc(len);
if (!buf)
return -ENOMEM;
buf = malloc(len);
if (!buf) {
*ret_len = -ENOMEM;
return NULL;
}

len = 0;
while (*in) {
Expand All @@ -1689,37 +1693,35 @@ int openconnect_base64_decode(void **out, const char *in)
b[1] = b64_char(in[1]);
if (b[0] < 0 || b[1] < 0)
goto err;
*(buf++) = (b[0] << 2) | (b[1] >> 4);
buf[len++] = (b[0] << 2) | (b[1] >> 4);

if (in[2] == '=') {
if (in[3] != '=' || in[4] != 0)
goto err;
len += 1;
break;
}
b[2] = b64_char(in[2]);
if (b[2] < 0)
goto err;
*(buf++) = (b[1] << 4) | (b[2] >> 2);
buf[len++] = (b[1] << 4) | (b[2] >> 2);
if (in[3] == '=') {
if (in[4] != 0)
goto err;
len += 2;
break;
}
b[3] = b64_char(in[3]);
if (b[3] < 0)
goto err;
*(buf++) = (b[2] << 6) | b[3];
len += 3;
buf[len++] = (b[2] << 6) | b[3];
in += 4;
}
return len;
*ret_len = len;
return buf;

err:
free(buf);
*out = NULL;
return -EINVAL;
*ret_len = EINVAL;
return NULL;
}

static const char b64_table[] = {
Expand Down
14 changes: 7 additions & 7 deletions ntlm.c
Expand Up @@ -51,15 +51,15 @@ static int ntlm_sspi(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
ULONG ret_flags;

if (challenge) {
int token_len;
int token_len = -EINVAL;

input_desc.cBuffers = 1;
input_desc.pBuffers = &in_token;
input_desc.ulVersion = SECBUFFER_VERSION;

in_token.BufferType = SECBUFFER_TOKEN;
token_len = openconnect_base64_decode(&in_token.pvBuffer, challenge);
if (token_len < 0)
in_token.pvBuffer = openconnect_base64_decode(&token_len, challenge);
if (!in_token.pvBuffer)
return token_len;
in_token.cbBuffer = token_len;
}
Expand Down Expand Up @@ -954,7 +954,7 @@ static int ntlm_manual_challenge(struct openconnect_info *vpninfo, struct oc_tex
char *user;
unsigned char nonce[8], hash[21], lm_resp[24], nt_resp[24];
unsigned char *token;
int token_len;
int token_len = -EINVAL;
int ntlmver;

if (!vpninfo->auth[AUTH_TYPE_NTLM].challenge)
Expand All @@ -963,9 +963,9 @@ static int ntlm_manual_challenge(struct openconnect_info *vpninfo, struct oc_tex
if (ntlm_nt_hash (vpninfo->proxy_pass, (char *) hash))
return -EINVAL;

token_len = openconnect_base64_decode((void **)&token,
vpninfo->auth[AUTH_TYPE_NTLM].challenge);
if (token_len < 0)
token = openconnect_base64_decode(&token_len,
vpninfo->auth[AUTH_TYPE_NTLM].challenge);
if (!token)
return token_len;

if (token_len < NTLM_CHALLENGE_NONCE_OFFSET + 8 || token[0] != 'N' ||
Expand Down
2 changes: 1 addition & 1 deletion openconnect-internal.h
Expand Up @@ -606,7 +606,7 @@ void __attribute__ ((format (printf, 2, 3)))
buf_append(struct oc_text_buf *buf, const char *fmt, ...);
void buf_append_bytes(struct oc_text_buf *buf, const void *bytes, int len);
void buf_append_base64(struct oc_text_buf *buf, const void *bytes, int len);
int openconnect_base64_decode(void **out, const char *in);
void *openconnect_base64_decode(int *len, const char *in);
int buf_error(struct oc_text_buf *buf);
int buf_free(struct oc_text_buf *buf);
char *openconnect_create_useragent(const char *base);
Expand Down
8 changes: 4 additions & 4 deletions sspi.c
Expand Up @@ -57,16 +57,16 @@ int gssapi_authorization(struct openconnect_info *vpninfo, struct oc_text_buf *h
}

if (vpninfo->auth[AUTH_TYPE_GSSAPI].challenge && *vpninfo->auth[AUTH_TYPE_GSSAPI].challenge) {
int token_len;
int token_len = -EINVAL;

input_desc.cBuffers = 1;
input_desc.pBuffers = &in_token;
input_desc.ulVersion = SECBUFFER_VERSION;

in_token.BufferType = SECBUFFER_TOKEN;
token_len = openconnect_base64_decode(&in_token.pvBuffer,
vpninfo->auth[AUTH_TYPE_GSSAPI].challenge);
if (token_len < 0)
in_token.pvBuffer = openconnect_base64_decode(&token_len,
vpninfo->auth[AUTH_TYPE_GSSAPI].challenge);
if (!in_token.pvBuffer)
return token_len;
in_token.cbBuffer = token_len;

Expand Down

0 comments on commit 764ce6b

Please sign in to comment.