[libfko] dedicated parsing functions for decoding client timeout and server auth SPA fields
This commit is contained in:
parent
5baf8a3fa9
commit
da09ba7300
163
lib/fko_decode.c
163
lib/fko_decode.c
@ -34,7 +34,7 @@
|
||||
#include "base64.h"
|
||||
#include "digest.h"
|
||||
|
||||
#define LOOP_PARSERS 7
|
||||
#define FIELD_PARSERS 9
|
||||
|
||||
static int
|
||||
verify_digest(char *tbuf, int t_size, fko_ctx_t ctx)
|
||||
@ -194,17 +194,61 @@ parse_nat_msg(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx)
|
||||
static int
|
||||
parse_server_auth(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx)
|
||||
{
|
||||
strlcpy(tbuf, *ndx, *t_size+1);
|
||||
if((*t_size = strlen(*ndx)) > 0)
|
||||
{
|
||||
if (*t_size > MAX_SPA_MESSAGE_SIZE)
|
||||
{
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING);
|
||||
}
|
||||
}
|
||||
else
|
||||
return FKO_SUCCESS;
|
||||
|
||||
if(ctx->server_auth != NULL)
|
||||
free(ctx->server_auth);
|
||||
if( ctx->message_type == FKO_CLIENT_TIMEOUT_ACCESS_MSG
|
||||
|| ctx->message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG
|
||||
|| ctx->message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG)
|
||||
{
|
||||
/* If we are here then we may still have a server_auth string,
|
||||
* or a timeout, or both. So we look for a ':' delimiter. If
|
||||
* it is there we have both, if not we check the message_type
|
||||
* again.
|
||||
*/
|
||||
if(strchr(*ndx, ':'))
|
||||
{
|
||||
*t_size = strcspn(*ndx, ":");
|
||||
|
||||
ctx->server_auth = calloc(1, *t_size+1); /* Yes, more than we need */
|
||||
if(ctx->server_auth == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
if (*t_size > MAX_SPA_MESSAGE_SIZE)
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG);
|
||||
|
||||
if(b64_decode(tbuf, (unsigned char*)ctx->server_auth) < 0)
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL);
|
||||
strlcpy(tbuf, *ndx, *t_size+1);
|
||||
|
||||
if(ctx->server_auth != NULL)
|
||||
free(ctx->server_auth);
|
||||
|
||||
ctx->server_auth = calloc(1, *t_size+1); /* Yes, more than we need */
|
||||
if(ctx->server_auth == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
if(b64_decode(tbuf, (unsigned char*)ctx->server_auth) < 0)
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL);
|
||||
|
||||
*ndx += *t_size + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strlcpy(tbuf, *ndx, *t_size+1);
|
||||
|
||||
if(ctx->server_auth != NULL)
|
||||
free(ctx->server_auth);
|
||||
|
||||
ctx->server_auth = calloc(1, *t_size+1); /* Yes, more than we need */
|
||||
if(ctx->server_auth == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
if(b64_decode(tbuf, (unsigned char*)ctx->server_auth) < 0)
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_DECODEFAIL);
|
||||
}
|
||||
|
||||
return FKO_SUCCESS;
|
||||
}
|
||||
@ -370,14 +414,17 @@ fko_decode_spa_data(fko_ctx_t ctx)
|
||||
|
||||
/* Array of function pointers to SPA field parsing functions
|
||||
*/
|
||||
int (*field_parser[LOOP_PARSERS])(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx)
|
||||
= { parse_rand_val, /* Extract random value */
|
||||
parse_username, /* Extract username */
|
||||
parse_timestamp, /* Client timestamp */
|
||||
parse_version, /* SPA version */
|
||||
parse_msg_type, /* SPA msg type */
|
||||
parse_msg, /* SPA msg string */
|
||||
parse_nat_msg };
|
||||
int (*field_parser[FIELD_PARSERS])(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx)
|
||||
= { parse_rand_val, /* Extract random value */
|
||||
parse_username, /* Extract username */
|
||||
parse_timestamp, /* Client timestamp */
|
||||
parse_version, /* SPA version */
|
||||
parse_msg_type, /* SPA msg type */
|
||||
parse_msg, /* SPA msg string */
|
||||
parse_nat_msg, /* SPA NAT msg string */
|
||||
parse_server_auth, /* optional server authentication method */
|
||||
parse_client_timeout /* client defined timeout */
|
||||
};
|
||||
|
||||
if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL);
|
||||
@ -450,7 +497,7 @@ fko_decode_spa_data(fko_ctx_t ctx)
|
||||
*/
|
||||
ndx = ctx->encoded_msg;
|
||||
|
||||
for (i=0; i < LOOP_PARSERS; i++)
|
||||
for (i=0; i < FIELD_PARSERS; i++)
|
||||
{
|
||||
res = (*field_parser[i])(tbuf, &ndx, &t_size, ctx);
|
||||
if(res != FKO_SUCCESS)
|
||||
@ -460,86 +507,6 @@ fko_decode_spa_data(fko_ctx_t ctx)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now look for a server_auth string.
|
||||
*/
|
||||
if((t_size = strlen(ndx)) > 0)
|
||||
{
|
||||
if (t_size > MAX_SPA_MESSAGE_SIZE)
|
||||
{
|
||||
free(tbuf);
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_SRVAUTH_MISSING);
|
||||
}
|
||||
|
||||
/* There is data, but what is it?
|
||||
* If the message_type does not have a timeout, assume it is a
|
||||
* server_auth field.
|
||||
*/
|
||||
if( ctx->message_type != FKO_CLIENT_TIMEOUT_ACCESS_MSG
|
||||
&& ctx->message_type != FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG
|
||||
&& ctx->message_type != FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG)
|
||||
{
|
||||
res = parse_server_auth(tbuf, &ndx, &t_size, ctx);
|
||||
|
||||
/* At this point we should be done.
|
||||
*/
|
||||
free(tbuf);
|
||||
|
||||
if(res == FKO_SUCCESS)
|
||||
{
|
||||
/* Call the context initialized.
|
||||
*/
|
||||
ctx->initval = FKO_CTX_INITIALIZED;
|
||||
FKO_SET_CTX_INITIALIZED(ctx);
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* If we are here then we may still have a server_auth string,
|
||||
* or a timeout, or both. So we look for a ':' delimiter. If
|
||||
* it is there we have both, if not we check the message_type
|
||||
* again.
|
||||
*/
|
||||
if(strchr(ndx, ':'))
|
||||
{
|
||||
t_size = strcspn(ndx, ":");
|
||||
|
||||
if (t_size > MAX_SPA_MESSAGE_SIZE)
|
||||
{
|
||||
free(tbuf);
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_EXTRA_TOOBIG);
|
||||
}
|
||||
|
||||
strlcpy(tbuf, ndx, t_size+1);
|
||||
|
||||
if(ctx->server_auth != NULL)
|
||||
free(ctx->server_auth);
|
||||
|
||||
ctx->server_auth = calloc(1, t_size+1); /* Yes, more than we need */
|
||||
if(ctx->server_auth == NULL)
|
||||
{
|
||||
free(tbuf);
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
}
|
||||
|
||||
if(b64_decode(tbuf, (unsigned char*)ctx->server_auth) < 0)
|
||||
{
|
||||
free(tbuf);
|
||||
return(FKO_ERROR_INVALID_DATA_DECODE_EXTRA_DECODEFAIL);
|
||||
}
|
||||
|
||||
ndx += t_size + 1;
|
||||
}
|
||||
|
||||
/* Now we look for a timeout value if one is supposed to be there.
|
||||
*/
|
||||
res = parse_client_timeout(tbuf, &ndx, &t_size, ctx);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
free(tbuf);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done with the tmp buffer.
|
||||
*/
|
||||
free(tbuf);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user