sync sources with sourceforge repository, prompted by Mateusz Kocielski.

+ minor changes to free resources in error cases
+ update return values from some functions
+ wrap some long lines
+ more tests
+ add length argument to digest functions

an additional minor fix to make this build, and to libsaslc.3 man
page, by myself.
This commit is contained in:
agc 2011-01-29 23:35:30 +00:00
parent 9d4594cbe9
commit 6b63829157
37 changed files with 600 additions and 468 deletions

View File

@ -1,7 +1,7 @@
SASL client library - draft
---------------------------
Version: $Id: library.txt,v 1.1.1.1 2010/11/27 21:23:58 agc Exp $
Version: $Id: library.txt,v 1.2 2011/01/29 23:35:30 agc Exp $
1. Typedefs

View File

@ -1,4 +1,4 @@
/* $Id: saslc.h,v 1.1.1.1 2010/11/27 21:23:58 agc Exp $ */
/* $Id: saslc.h,v 1.2 2011/01/29 23:35:30 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -38,6 +38,7 @@
#ifndef _SASLC_H_
#define _SASLC_H_
#include <stdbool.h>
#include <stdlib.h>
typedef struct saslc_t saslc_t;
@ -46,7 +47,7 @@ typedef struct saslc_sess_t saslc_sess_t;
/* begin and end */
saslc_t *saslc_alloc(void);
int saslc_init(saslc_t *, const char *);
int saslc_end(saslc_t *);
int saslc_end(saslc_t *, bool);
/* error */
const char *saslc_strerror(saslc_t *);
@ -68,4 +69,4 @@ int saslc_sess_encode(saslc_sess_t *, const void *, size_t, void **,
int saslc_sess_decode(saslc_sess_t *, const void *, size_t, void **,
size_t *);
#endif /* !_SASLC_H_ */
#endif /* ! _SASLC_H_ */

View File

@ -46,33 +46,7 @@
<a name="status"></a>
<p class="header">Status</p>
<b>Project schedule:</b>
<ul>
<li> <b>August 23 - September 3:</b>
<ul>
<li>postfix integration</li>
<li>testing/fixing</li>
</ul>
</li>
</ul>
<ul>
<li> <b>September 4 - September 8:</b>
<ul>
<li>improving DIGEST-MD5 implementation</li>
<li>improving test infrastructure</li>
</ul>
</li>
</ul>
<ul>
<li> <b>September 8 - September 12:</b>
<ul>
<li>improving code quality</li>
<li>improving documentation</li>
</ul>
</li>
</ul>
Future plans involves implementing others mechanisms (i.e. S/KEY).
I'm working now on improving existing code and integration with the Postfix. I hope to be ready with it soon. My future plans involves implementing others mechanisms (i.e. S/KEY).
</div>
<div class="main">
@ -133,7 +107,7 @@
<td>
<table>
<tr> <td> Mateusz Kocielski &lt;<tt>m.kocielski@gmail.com</tt>&gt; </td> </tr>
<tr> <td> $Id: index.html,v 1.1.1.1 2010/11/27 21:23:58 agc Exp $ </td> </tr>
<tr> <td> $Id: index.html,v 1.2 2011/01/29 23:35:30 agc Exp $ </td> </tr>
</table>
</td>
</tr>

View File

@ -3,54 +3,64 @@
.Dt LIBSASLC 3
.Os
.Sh NAME
.Nm saslc_alloc ,
.Nm saslc_init ,
.Nm saslc_end ,
.Nm saslc_strerror ,
.Nm saslc_sess_strerror ,
.Nm saslc_sess_init ,
.Nm saslc_sess_end ,
.Nm saslc_sess_setprop ,
.Nm saslc_sess_getprop ,
.Nm saslc_sess_getmech ,
.Nm saslc_sess_cont ,
.Nm saslc_sess_encode ,
.Nm saslc_sess_decode
.Nm libsaslc
.Nd Simple Authentication and Security Layer client library
.Sh LIBRARY
.Lb libsaslc
.Sh SYNOPSIS
.In saslc.h
.Ft saslc_t *
.Fn saslc_alloc "void"
.Fo saslc_alloc
.Fa "void"
.Fc
.Ft int
.Fn saslc_end "saslc_t *ctx"
.Fo saslc_end
.Fa "saslc_t *ctx"
.Fc
.Ft int
.Fn saslc_init "saslc_t *ctx" "const char *appname"
.Fo saslc_init
.Fa "saslc_t *ctx" "const char *appname"
.Fc
.Ft int
.Fn saslc_sess_cont "saslc_sess_t *sess" "const void *in" "size_t inlen" \
"void* *out" "size_t *outlen"
.Fo saslc_sess_cont
.Fa "saslc_sess_t *sess" "const void *in" "size_t inlen" "void* *out" "size_t *outlen"
.Fc
.Ft int
.Fn saslc_sess_decode "saslc_sess_t *sess" "const void *in" "size_t inlen" \
"void* *out" "size_t *outlen"
.Fo saslc_sess_decode
.Fa "saslc_sess_t *sess" "const void *in" "size_t inlen" "void* *out" "size_t *outlen"
.Fc
.Ft int
.Fn saslc_sess_encode "saslc_sess_t *sess" "const void *in" "size_t inlen" \
"void* *out" "size_t *outlen"
.Fo saslc_sess_encode
.Fa "saslc_sess_t *sess" "const void *in" "size_t inlen" "void* *out" "size_t *outlen"
.Fc
.Ft void
.Fn saslc_sess_end "saslc_sess_t *sess"
.Fo saslc_sess_end
.Fa "saslc_sess_t *sess"
.Fc
.Ft const char *
.Fn saslc_sess_getprop "saslc_sess_t *sess" "const char *name"
.Fo saslc_sess_getprop
.Fa "saslc_sess_t *sess" "const char *name"
.Fc
.Ft saslc_sess_t *
.Fn saslc_sess_init "saslc_t *ctx" "const char *mechs"
.Fo saslc_sess_init
.Fa "saslc_t *ctx" "const char *mechs"
.Fc
.Ft int
.Fn saslc_sess_setprop "saslc_sess_t *sess" "const char *name" \
"const char *value"
.Fo saslc_sess_setprop
.Fa "saslc_sess_t *sess" "const char *name" "const char *value"
.Fc
.Ft const char *
.Fn saslc_sess_strerror "saslc_sess_t *sess"
.Fo saslc_sess_strerror
.Fa "saslc_sess_t *sess"
.Fc
.Ft const char *
.Fn saslc_sess_strmech "saslc_sess_t *sess"
.Fo saslc_sess_strmech
.Fa "saslc_sess_t *sess"
.Fc
.Ft const char *
.Fn saslc_strerror "saslc_t *ctx"
.Fo saslc_strerror
.Fa "saslc_t *ctx"
.Fc
.Sh DESCRIPTION
The
.Fn saslc_alloc
@ -149,6 +159,6 @@ to the "unknown error" string on failure.
.Sh STANDARDS
RFC 2195, RFC 2222, RFC 2245, RFC 2595, RFC 2831
.Sh OTHER IMPLEMENTATIONS
There exist other SASL client library implementations include Cyrus SASL
There exist other SASL client library implementations including Cyrus SASL
(http://asg.web.cmu.edu/sasl/sasl-library.html) and GNU SASL
(http://www.gnu.org/software/gsasl/).

View File

@ -240,7 +240,7 @@
<td>
<table>
<tr> <td> Mateusz Kocielski &lt;<tt>m.kocielski@gmail.com</tt>&gt; </td> </tr>
<tr> <td> $Id: soc.html,v 1.1.1.1 2010/11/27 21:23:58 agc Exp $ </td> </tr>
<tr> <td> $Id: soc.html,v 1.2 2011/01/29 23:35:30 agc Exp $ </td> </tr>
</table>
</td>
</tr>

View File

@ -1,6 +1,6 @@
# $Id: Makefile,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $
CC=gcc
CFLAGS=-I../include -Wall -pedantic -fPIC -ggdb
# $Id: Makefile,v 1.2 2011/01/29 23:35:31 agc Exp $
CFLAGS=-I../include -Wall -Werror -pedantic -fPIC -ggdb -D_GNU_SOURCE
LIBSASLC_OBJS=\
dict.o error.o mech_anonymous.o mech_digestmd5.o mech_gssapi.o mech.o parser.o \
xsess.o mech_crammd5.o mech_external.o mech_login.o mech_plain.o saslc.o crypto.o
@ -13,3 +13,6 @@ libsaslc.so: $(LIBSASLC_OBJS)
clean:
rm -f *.o *.so
splint:
splint -weak -I../include *.[ch]

View File

@ -1,10 +1,23 @@
# $Id: Makefile.bsd,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $
WARNS?=4
# $Id: Makefile.bsd,v 1.2 2011/01/29 23:35:31 agc Exp $
.include <bsd.own.mk>
USE_FORT?= yes
LIB=saslc
CPPFLAGS+=-I${.CURDIR}/../include
SRCS= dict.c error.c mech_anonymous.c mech_digestmd5.c mech_gssapi.c mech.c \
parser.c xsess.c mech_crammd5.c mech_external.c mech_login.c \
mech_plain.c saslc.c crypto.c
SRCS+= dict.c error.c mech_anonymous.c mech_digestmd5.c mech_gssapi.c mech.c
SRCS+= parser.c xsess.c mech_crammd5.c mech_external.c mech_login.c
SRCS+= mech_plain.c saslc.c crypto.c
CPPFLAGS+=-I${EXTDIST}/include
MAN=libsaslc.3
WARNS?=4
EXTDIST=${.CURDIR}/../dist
.PATH: ${EXTDIST}/include ${EXTDIST}/src ${EXTDIST}/man
INCS+= saslc.h
INCSDIR=/usr/include
LDADD+=-lssl -lgssapi
DPADD+=${LIBSSL}

View File

@ -1,4 +1,4 @@
/* $Id: crypto.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: crypto.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@ -46,39 +46,40 @@
#include <openssl/buffer.h>
#include "crypto.h"
/* local headers */
#define HMAC_MD5_KEYSIZE 64
#define HMAC_MD5_IPAD 0x36
#define HMAC_MD5_OPAD 0x5C
/* local header */
static const char saslc__hex[] = "0123456789abcdef";
static char * saslc__digest_to_ascii(const unsigned char *);
static char *saslc__digest_to_ascii(const unsigned char *);
/**
* @brief converts MD5 binary digest into text representation.
* @param d MD5 digest
* @brief converts MD5 binary digest into its text representation.
* @param d MD5 digest in binary form
* @return the text representation, note that user is responsible for freeing
* allocated memory.
*/
static char *
saslc__digest_to_ascii(const unsigned char *d)
saslc__digest_to_ascii(const unsigned char *digest)
{
char *r;
size_t i;
char *result;
size_t i,j;
if ((r = calloc((MD5_DIGEST_LENGTH << 1) + 1, sizeof(*r))) == NULL)
result = calloc((2 * MD5_DIGEST_LENGTH) + 1, sizeof(*result));
if (result == NULL)
return NULL;
for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
size_t j = i << 1;
r[j] = saslc__hex[(unsigned int)d[i] >> 4];
r[j + 1] = saslc__hex[d[i] & 0x0F];
j = 2*i;
result[j] = saslc__hex[(unsigned char)digest[i] >> 4];
result[j + 1] = saslc__hex[digest[i] & 0x0F];
}
return r;
return result;
}
/**
@ -102,23 +103,18 @@ saslc__crypto_base64(const unsigned char *in, size_t len)
/* base64 -> mem */
base64 = BIO_push(base64, m);
/*LINTED len should be size_t in api*/
BIO_write(base64, in, len);
BIO_write(base64, in, (int)len);
/*LINTED wrong argument, null effect*/
(void)BIO_flush(base64);
/*LINTED wrong argument, non-portable cast*/
BIO_get_mem_ptr(base64, &c);
#if 0
/* c->length is unsigned and cannot be < 0 */
if (c->length < 0)
return NULL;
#endif
(void)BIO_get_mem_ptr(base64, &c);
/*LINTED length should be size_t in api*/
r = calloc(c->length, sizeof(*r));
if (r == NULL)
goto end;
if (c->length != 0) {
/*LINTED length should be size_t in api*/
memcpy(r, c->data, c->length - 1);
memcpy(r, c->data, (size_t)(c->length - 1));
}
end:
BIO_free_all(base64);
@ -127,44 +123,46 @@ end:
}
/**
* @brief generates safe nonce basing on OpenSSL
* RAND_pseudo_bytes, which should be enough for our purposes.
* @brief generates safe nonce basing on the OpenSSL
* RAND_pseudo_bytes, which should be good enough for our purposes.
* @param b nonce length
* @return nonce, user is responsible for freeing nonce.
*/
unsigned char *
saslc__crypto_nonce(size_t b)
saslc__crypto_nonce(size_t len)
{
unsigned char *n;
unsigned char *nonce;
if ((n = calloc(b, sizeof(*n))) == NULL)
nonce = calloc(len, sizeof(*nonce));
if (nonce == NULL)
return NULL;
/*LINTED b should be size_t in api*/
if (RAND_pseudo_bytes(n, b) != 1) {
free(n);
if (RAND_pseudo_bytes(nonce, (int)len) != 1) {
free(nonce);
return NULL;
}
return n;
return nonce;
}
/**
* @brief computes md5(D)
* @param d data (string)
* @return the text representation of the computed digest, note that user is
* @param str data
* @param len data length
* @return text representation of the computed digest, note that user is
* responsible for freeing allocated memory.
*/
char *
saslc__crypto_md5(const char *d)
saslc__crypto_md5(const char *str, size_t len)
{
unsigned char digest[MD5_DIGEST_LENGTH];
MD5_CTX md5c;
MD5_Init(&md5c);
MD5_Update(&md5c, d, strlen(d));
MD5_Update(&md5c, str, len);
MD5_Final(digest, &md5c);
return saslc__digest_to_ascii(digest);
@ -176,7 +174,7 @@ saslc__crypto_md5(const char *d)
* @param keylen hmac_md5 key length
* @param in hmac_md5 input
* @param inlen hmac_md5 input length
* @return the text representation of the computed digest, note that user is
* @returntext representation of the computed digest, note that user is
* responsible for freeing allocated memory.
*/

View File

@ -1,4 +1,4 @@
/* $Id: crypto.h,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: crypto.h,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@ -39,9 +39,6 @@
#ifndef _CRYPTO_H_
#define _CRYPTO_H_
/* hmac md5 digest length in ascii format */
#define HMAC_MD5_DIGEST_LENGTH 32
/* nonce/random functions */
unsigned char *saslc__crypto_nonce(size_t);
@ -49,7 +46,7 @@ unsigned char *saslc__crypto_nonce(size_t);
char *saslc__crypto_base64(const unsigned char *, size_t);
/* hashing functions */
char *saslc__crypto_md5(const char *);
char *saslc__crypto_md5(const char *, size_t);
char *saslc__crypto_hmac_md5(const unsigned char *, size_t,
const unsigned char *, size_t);

View File

@ -1,4 +1,4 @@
/* $Id: dict.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: dict.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -48,7 +48,7 @@
/** dictionary */
LIST_HEAD(saslc__dict_t, saslc__dict_node_t);
/** linked list */
/** dictionary linked list */
typedef struct saslc__dict_node_t {
LIST_ENTRY(saslc__dict_node_t) nodes;
char *key; /**< key */
@ -70,10 +70,14 @@ static saslc__dict_node_t *saslc__get_node_by_key(saslc__dict_t *,
static bool
saslc__valid_key(const char *key)
{
size_t i; /* index */
size_t i;
for (i = 0; key[i]; i++) {
if (!isalnum((unsigned char)key[i]))
/* key is empty string */
if (key == NULL)
return false;
for (i = 0; key[i] != '\0'; i++) {
if (isalnum((unsigned char)key[i]) == 0)
return false;
}
@ -107,7 +111,8 @@ static saslc__dict_node_t *
saslc__get_node_by_key(saslc__dict_t *dict, const char *key)
{
saslc__dict_node_t *node;
for (node = dict->lh_first; node != NULL; node = node->nodes.le_next) {
LIST_FOREACH(node, dict, nodes) {
if (strcmp(node->key, key) == 0)
return node;
}
@ -123,8 +128,8 @@ saslc__get_node_by_key(saslc__dict_t *dict, const char *key)
void
saslc__dict_destroy(saslc__dict_t *dict)
{
while(dict->lh_first != NULL)
saslc__list_node_destroy(dict->lh_first);
while(!LIST_EMPTY(dict))
saslc__list_node_destroy(LIST_FIRST(dict));
free(dict);
}
@ -137,13 +142,12 @@ saslc__dict_destroy(saslc__dict_t *dict)
* does not exist in the dictionary.
*/
int
saslc__dict_result_t
saslc__dict_remove(saslc__dict_t *dict, const char *key)
{
saslc__dict_node_t *node;
for (node = dict->lh_first; node != NULL;
node = node->nodes.le_next) {
LIST_FOREACH(node, dict, nodes) {
if (strcmp(node->key, key) == 0) {
saslc__list_node_destroy(node);
return DICT_OK;
@ -219,13 +223,14 @@ saslc__dict_create(void)
* DICT_NOMEM - on allocation failure
*/
int
saslc__dict_result_t
saslc__dict_insert(saslc__dict_t *dict, const char *key, const char *val)
{
char *d_key, *d_val;
int err;
char *d_key = NULL, *d_val = NULL;
saslc__dict_node_t *node;
if (key == NULL || saslc__valid_key(key) == false)
if (saslc__valid_key(key) == false)
return DICT_KEYINVALID;
if (val == NULL)
@ -235,18 +240,13 @@ saslc__dict_insert(saslc__dict_t *dict, const char *key, const char *val)
if (saslc__dict_get(dict, key) != NULL)
return DICT_KEYEXISTS;
if ((d_key = strdup(key)) == NULL)
return DICT_NOMEM;
d_key = strdup(key);
d_val = strdup(val);
node = calloc(1, sizeof(*node));
if ((d_val = strdup(val)) == NULL) {
free(d_key);
return DICT_NOMEM;
}
if ((node = calloc(1, sizeof(*node))) == NULL) {
free(d_val);
free(d_key);
return DICT_NOMEM;
if (d_key == NULL || d_val == NULL || node == NULL) {
err = DICT_NOMEM;
goto error;
}
LIST_INSERT_HEAD(dict, node, nodes);
@ -255,4 +255,10 @@ saslc__dict_insert(saslc__dict_t *dict, const char *key, const char *val)
node->value_len = strlen(node->value);
return DICT_OK;
error:
free(d_val);
free(d_key);
free(node);
return err;
}

View File

@ -1,4 +1,4 @@
/* $Id: dict.h,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: dict.h,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -39,26 +39,25 @@
#ifndef _DICT_H_
#define _DICT_H_
#include <stdlib.h>
enum {
typedef enum {
DICT_OK = 0,
DICT_NOMEM,
DICT_KEYNOTFOUND,
DICT_KEYEXISTS,
DICT_KEYINVALID,
DICT_VALBAD
};
} saslc__dict_result_t;
/* dictionary type */
typedef struct saslc__dict_t saslc__dict_t;
/* interface */
saslc__dict_t *saslc__dict_create(void);
int saslc__dict_insert(saslc__dict_t *, const char *, const char *);
saslc__dict_result_t saslc__dict_insert(saslc__dict_t *, const char *,
const char *);
const char *saslc__dict_get(saslc__dict_t *, const char *);
size_t saslc__dict_get_len(saslc__dict_t *, const char *);
int saslc__dict_remove(saslc__dict_t *, const char *);
saslc__dict_result_t saslc__dict_remove(saslc__dict_t *, const char *);
void saslc__dict_destroy(saslc__dict_t *);
#endif /* ! _DICT_H_ */

View File

@ -1,4 +1,4 @@
/* $Id: error.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: error.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -39,9 +39,9 @@
#include "error.h"
/**
* @brief returns text representation of the error
* @brief returns error string
* @param err error
* @return pointer to the string with error message
* @return error string
*/
const char *

View File

@ -1,4 +1,4 @@
/* $Id: error.h,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: error.h,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -39,19 +39,19 @@
#define _ERROR_H_
/** error definitions */
enum {
typedef enum {
ERROR_GENERAL, /**< general error */
ERROR_NOMEM, /**< no memory available */
ERROR_BADARG, /**< bad argument passed to function */
ERROR_NOTEXISTS, /**< key/node does not exist */
ERROR_MECH, /**< mechanism error */
ERROR_PARSE /**< parse error */
};
} saslc__error_code_t;
/** error type */
typedef struct saslc__error_t {
int err_no; /**< error number */
const char *err_str; /**< string error */
saslc__error_code_t err_no; /**< error number */
const char *err_str; /**< string error */
} saslc__error_t;
/*

View File

@ -1,4 +1,4 @@
/* $Id: mech.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -47,6 +47,10 @@
/* local headers */
static int
saslc__mech_generic_seclayer(saslc_sess_t *, const void *, size_t, void **,
size_t *);
/* mechanisms */
extern const saslc__mech_t saslc__mech_anonymous;
extern const saslc__mech_t saslc__mech_crammd5;
@ -68,45 +72,39 @@ const saslc__mech_t *saslc__mechanisms[] = {
};
/**
* @brief creates lists of the mechanisms for the context,
* function only creates list, it means that it's not assigning mechanism_list
* with the context.
* @brief creates lists of the mechanisms for the context.
* @param ctx context
* @return pointer to head od the list, NULL if allocation failed
* @return 0 on success, -1 on error
*/
saslc__mech_list_t *
int
saslc__mech_list_create(saslc_t *ctx)
{
saslc__mech_list_t *head = NULL;
saslc__mech_list_node_t *node = NULL;
size_t i;
if ((head = calloc(1, sizeof(*head))) == NULL) {
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
return NULL;
}
LIST_INIT(&ctx->mechanisms);
for (i = 0; saslc__mechanisms[i] != NULL; i++) {
if ((node = calloc(1, sizeof(*node))) == NULL)
for (i = 0; saslc__mechanisms[i] != NULL; i++) {
node = calloc(1, sizeof(*node));
if (node == NULL)
goto error;
if ((node->prop = saslc__dict_create()) == NULL) {
free(node);
if ((node->prop = saslc__dict_create()) == NULL)
goto error;
}
node->mech = saslc__mechanisms[i];
LIST_INSERT_HEAD(head, node, nodes);
LIST_INSERT_HEAD(&ctx->mechanisms, node, nodes);
}
return head;
return 0;
error:
free(node);
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
saslc__mech_list_destroy(head);
return NULL;
saslc__mech_list_destroy(&ctx->mechanisms);
return -1;
}
/**
@ -121,9 +119,10 @@ saslc__mech_list_get(saslc__mech_list_t *list, const char *mech_name)
{
saslc__mech_list_node_t *node;
for (node = list->lh_first; node != NULL; node = node->nodes.le_next)
LIST_FOREACH(node, list, nodes) {
if (strcasecmp(node->mech->name, mech_name) == 0)
return node;
}
return NULL;
}
@ -138,14 +137,12 @@ saslc__mech_list_destroy(saslc__mech_list_t *list)
{
saslc__mech_list_node_t *node;
while((node = list->lh_first) != NULL) {
if (node != NULL)
saslc__dict_destroy(node->prop);
while(!LIST_EMPTY(list)) {
node = LIST_FIRST(list);
LIST_REMOVE(node, nodes);
saslc__dict_destroy(node->prop);
free(node);
}
free(list);
}
/**
@ -167,13 +164,15 @@ saslc__mech_strdup(saslc_sess_t *sess, char **out, size_t *outlen,
const char *value; /* property value */
/* get value */
if ((value = saslc_sess_getprop(sess, name)) == NULL) {
value = saslc_sess_getprop(sess, name);
if (value == NULL) {
saslc__error_set(ERR(sess), ERROR_MECH, error_msg);
return MECH_ERROR;
}
/* copy value */
if ((*out = strdup(value)) == NULL) {
*out = strdup(value);
if (*out == NULL) {
saslc__error_set_errno(ERR(sess), ERROR_NOMEM);
return MECH_ERROR;
}
@ -184,6 +183,80 @@ saslc__mech_strdup(saslc_sess_t *sess, char **out, size_t *outlen,
return MECH_OK;
}
/**
* @brief transparent security layer
* @param sess sasl session
* @param in input data
* @param inlen input data length
* @param out place to store output data
* @param outlen output data length
* @return MECH_OK - success,
* MECH_ERROR - error
*/
static int
saslc__mech_generic_seclayer(saslc_sess_t *sess, const void *in,
size_t inlen, void **out, size_t *outlen)
{
saslc__mech_sess_t *mech_sess = sess->mech_sess;
if (mech_sess->status != STATUS_AUTHENTICATED) {
saslc__error_set(ERR(sess), ERROR_MECH,
"session is not authenticated");
return MECH_ERROR;
}
*out = calloc(inlen, sizeof(char));
if (*out == NULL) {
saslc__error_set_errno(ERR(sess), ERROR_NOMEM);
return MECH_ERROR;
}
memcpy(*out, in, inlen);
*outlen = inlen;
return MECH_OK;
}
/**
* @brief encodes data using transparent security layer
* @param sess sasl session
* @param in input data
* @param inlen input data length
* @param out place to store output data
* @param outlen output data length
* @return MECH_OK - success,
* MECH_ERROR - error
*/
int
saslc__mech_generic_encode(saslc_sess_t *sess, const void *in,
size_t inlen, void **out, size_t *outlen)
{
return saslc__mech_generic_seclayer(sess, in, inlen, out, outlen);
}
/**
* @brief decodes data using transparent security layer
* @param sess sasl session
* @param in input data
* @param inlen input data length
* @param out place to store output data
* @param outlen output data length
* @return MECH_OK - success,
* MECH_ERROR - error
*/
int
saslc__mech_generic_decode(saslc_sess_t *sess, const void *in,
size_t inlen, void **out, size_t *outlen)
{
return saslc__mech_generic_seclayer(sess, in, inlen, out, outlen);
}
/**
* @brief generic session create function, this
* function is suitable for the most mechanisms.
@ -193,7 +266,9 @@ saslc__mech_strdup(saslc_sess_t *sess, char **out, size_t *outlen,
int
saslc__mech_generic_create(saslc_sess_t *sess)
{
if ((sess->mech_sess = calloc(1, sizeof(saslc__mech_sess_t))) == NULL) {
sess->mech_sess = calloc(1, sizeof(saslc__mech_sess_t));
if (sess->mech_sess == NULL) {
saslc__error_set(ERR(sess), ERROR_NOMEM, NULL);
return -1;
}

View File

@ -1,4 +1,4 @@
/* $Id: mech.h,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech.h,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -38,7 +38,6 @@
#ifndef _MECH_H_
#define _MECH_H_
#include <stdint.h>
#include <sys/queue.h>
#include "dict.h"
@ -46,19 +45,8 @@
enum {
STATUS_AUTHENTICATION, /**< authentication in progress */
STATUS_AUTHENTICATED /**< session authenticated. this value is used
after last step of the authentication and
means only that last step was performed. */
};
/** mechanism flags - currently unused */
enum {
FLAG_NONE = 0, /**< none flag */
FLAG_ANONYMOUS = 1 << 0, /**< anonymous authentication */
FLAG_DICTIONARY = 1 << 1, /**< dictionary attack against
* authentication is possible */
FLAG_PLAINTEXT = 1 << 2, /**< mechanism uses plaintext for sharing
secrets */
FLAG_MUTUAL = 1 << 3 /**< mutual authentication */
* after last step of the authentication and
* means only that last step was performed. */
};
/** mechanism cont return values - used by _cont() functions */
@ -70,8 +58,8 @@ enum {
/** mechanism session */
typedef struct saslc__mech_sess_t {
uint32_t status; /**< status of authentication */
uint32_t step; /**< step counter */
unsigned int status; /**< status of authentication */
unsigned int step; /**< step counter */
} saslc__mech_sess_t;
/* mechanism functions */
@ -86,29 +74,26 @@ typedef int (*saslc__mech_destroy_t)(saslc_sess_t *);
/** mechanism structure */
typedef struct saslc__mech_t {
const char *name; /**< mechanism name */
const uint32_t flags; /**< mechanism flags */
const char *name; /**< mechanism name */
saslc__mech_create_t create; /**< create function - creates mechanism
instance */
saslc__mech_cont_t cont; /**< step function - performs one step of
authentication */
* instance */
saslc__mech_cont_t cont; /**< step function - performs one step of
* authentication */
saslc__mech_encode_t encode; /**< encoding function - encodes input
according to negotiated security
layer */
* according to negotiated security
* layer */
saslc__mech_decode_t decode; /**< decoding function - decodes input
according to negotiated security
layer */
* according to negotiated security
* layer */
saslc__mech_destroy_t destroy; /**< destroy function - destroys
mechanism instance */
* mechanism instance */
} saslc__mech_t;
/** mechanism list */
/* mechanisms list node */
/** mechanisms list node */
typedef struct saslc__mech_list_node_t {
LIST_ENTRY(saslc__mech_list_node_t) nodes;
const saslc__mech_t *mech; /**< mechanism */
saslc__dict_t *prop; /**< mechanism configuration */
LIST_ENTRY(saslc__mech_list_node_t) nodes; /**< nodes */
const saslc__mech_t *mech; /**< mechanism */
saslc__dict_t *prop; /**< mechanism configuration */
} saslc__mech_list_node_t;
/* mechanisms list head */
@ -116,13 +101,18 @@ typedef struct saslc__mech_list_t saslc__mech_list_t;
LIST_HEAD(saslc__mech_list_t, saslc__mech_list_node_t);
/* mechanism list functions */
saslc__mech_list_t *saslc__mech_list_create(saslc_t *);
int saslc__mech_list_create(saslc_t *);
void saslc__mech_list_destroy(saslc__mech_list_t *);
saslc__mech_list_node_t *saslc__mech_list_get(saslc__mech_list_t *, const char *);
saslc__mech_list_node_t *saslc__mech_list_get(saslc__mech_list_t *,
const char *);
/* generic functions */
int saslc__mech_generic_create(saslc_sess_t *);
int saslc__mech_generic_destroy(saslc_sess_t *);
int saslc__mech_generic_encode(saslc_sess_t *, const void *, size_t, void **,
size_t *);
int saslc__mech_generic_decode(saslc_sess_t *, const void *, size_t, void **,
size_t *);
/* additional functions */
int saslc__mech_strdup(saslc_sess_t *, char **, size_t *, const char *,

View File

@ -1,4 +1,4 @@
/* $Id: mech_anonymous.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech_anonymous.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -76,10 +76,9 @@ saslc__mech_anonymous_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_anonymous = {
"ANONYMOUS", /* name */
FLAG_ANONYMOUS, /* flags */
saslc__mech_generic_create, /* create */
saslc__mech_anonymous_cont, /* step */
NULL, /* encode */
NULL, /* decode */
saslc__mech_generic_encode, /* encode */
saslc__mech_generic_decode, /* decode */
saslc__mech_generic_destroy /* destroy */
};

View File

@ -1,4 +1,4 @@
/* $Id: mech_crammd5.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech_crammd5.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -69,8 +69,22 @@ saslc__mech_crammd5_cont(saslc_sess_t *sess, const void *in, size_t inlen,
void **out, size_t *outlen)
{
const char *authid, *passwd;
char *digest, *name;
int len;
char *digest;
int len;
authid = saslc_sess_getprop(sess, SASLC_CRAM_MD5_AUTHID);
if (authid == NULL) {
saslc__error_set(ERR(sess), ERROR_MECH,
"authid is required for an authentication");
return MECH_ERROR;
}
passwd = saslc_sess_getprop(sess, SASLC_CRAM_MD5_PASSWORD);
if (passwd == NULL) {
saslc__error_set(ERR(sess), ERROR_MECH,
"passwd is required for an authentication");
return MECH_ERROR;
}
/* server is doing first step, but some clients may call this function
* before getting data from server */
@ -79,34 +93,26 @@ saslc__mech_crammd5_cont(saslc_sess_t *sess, const void *in, size_t inlen,
*outlen = 0;
return MECH_STEP;
}
if ((authid = saslc_sess_getprop(sess, SASLC_CRAM_MD5_AUTHID))
== NULL) {
saslc__error_set(ERR(sess), ERROR_MECH,
"authid is required for an authentication");
return MECH_ERROR;
}
if ((passwd = saslc_sess_getprop(sess, SASLC_CRAM_MD5_PASSWORD))
== NULL) {
saslc__error_set(ERR(sess), ERROR_MECH,
"passwd is required for an authentication");
return MECH_ERROR;
}
digest = saslc__crypto_hmac_md5((const unsigned char *)passwd,
strlen(passwd), in, inlen);
if ((len = asprintf(&name, "%s %s", authid, digest)) == -1) {
free(digest);
if (digest == NULL) {
saslc__error_set_errno(ERR(sess), ERROR_NOMEM);
return MECH_ERROR;
}
len = asprintf((char **)out, "%s %s", authid, digest);
/* no longer need to keep the digest */
free(digest);
if (len == -1) {
saslc__error_set_errno(ERR(sess), ERROR_NOMEM);
return MECH_ERROR;
}
*out = name;
*outlen = len + 1;
free(digest);
*outlen = (size_t)len + 1;
return MECH_OK;
}
@ -114,10 +120,9 @@ saslc__mech_crammd5_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_crammd5 = {
"CRAM-MD5", /* name */
FLAG_DICTIONARY, /* flags */
saslc__mech_generic_create, /* create */
saslc__mech_crammd5_cont, /* step */
NULL, /* encode */
NULL, /* decode */
saslc__mech_generic_encode, /* encode */
saslc__mech_generic_decode, /* decode */
saslc__mech_generic_destroy /* destroy */
};

View File

@ -1,4 +1,4 @@
/* $Id: mech_digestmd5.c,v 1.2 2010/12/18 18:22:24 christos Exp $ */
/* $Id: mech_digestmd5.c,v 1.3 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -146,7 +146,7 @@ saslc__mech_digestmd5_userhash(const char *username, const char *realm,
if (asprintf(&tmp, "%s:%s:%s", username, realm, password) == -1)
return NULL;
r = saslc__crypto_md5(tmp);
r = saslc__crypto_md5(tmp, strlen(tmp));
free(tmp);
return r;
@ -168,10 +168,10 @@ saslc__mech_digestmd5_a1(const char *userhash, const char *nonce,
char *tmp, *r;
if (asprintf(&tmp, "%s:%s:%s:%s", userhash, nonce, cnonce, authzid)
== -1 || tmp == NULL)
== -1)
return NULL;
r = saslc__crypto_md5(tmp);
r = saslc__crypto_md5(tmp, strlen(tmp));
free(tmp);
return r;
@ -193,7 +193,7 @@ saslc__mech_digestmd5_a2(const char *digesturi, int qop)
qop != QOP_AUTH ? AUTH_INT_CONF_SUFFIX : "") == -1)
return NULL;
r = saslc__crypto_md5(tmp);
r = saslc__crypto_md5(tmp, strlen(tmp));
free(tmp);
return r;
@ -229,7 +229,7 @@ saslc__mech_digestmd5_rhash(const char *a1, const char *a2, const char *nonce,
cnonce, saslc__qop_str[qop], a2) == -1)
return NULL;
r = saslc__crypto_md5(tmp);
r = saslc__crypto_md5(tmp, strlen(tmp));
free(tmp);
return r;
@ -355,6 +355,10 @@ saslc__mech_digestmd5_parse_challenge(saslc__mech_digestmd5_sess_t *mech_sess,
if (c == '\0')
goto out;
n = strchr(c, '=');
if (n == NULL) {
free(copy);
return -1;
}
c = n;
*c = '\0';
c++;
@ -556,6 +560,10 @@ saslc__mech_digestmd5_cont(saslc_sess_t *sess, const void *in, size_t inlen,
*out = saslc__mech_digestmd5_response(mech_sess, authid, pass,
authzid);
if (*out == NULL) {
saslc__error_set_errno(ERR(sess), ERROR_NOMEM);
return MECH_ERROR;
}
*outlen = strlen(*out);
return MECH_OK;
@ -568,10 +576,9 @@ saslc__mech_digestmd5_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_digestmd5 = {
"DIGEST-MD5", /* name */
FLAG_MUTUAL | FLAG_DICTIONARY, /* flags */
saslc__mech_digestmd5_create, /* create */
saslc__mech_digestmd5_cont, /* step */
NULL, /* encode */
NULL, /* decode */
saslc__mech_generic_encode, /* encode */
saslc__mech_generic_decode, /* decode */
saslc__mech_digestmd5_destroy /* destroy */
};

View File

@ -1,4 +1,4 @@
/* $Id: mech_external.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech_external.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -73,10 +73,9 @@ saslc__mech_external_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_external = {
"EXTERNAL", /* name */
FLAG_NONE, /* flags */
saslc__mech_generic_create, /* create */
saslc__mech_external_cont, /* step */
NULL, /* encode */
NULL, /* decode */
saslc__mech_generic_encode, /* encode */
saslc__mech_generic_decode, /* decode */
saslc__mech_generic_destroy /* destroy */
};

View File

@ -1,4 +1,4 @@
/* $Id: mech_gssapi.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech_gssapi.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -125,7 +125,7 @@ saslc__mech_gssapi_destroy(saslc_sess_t *sess)
saslc__mech_gssapi_sess_t *mech_sess = sess->mech_sess;
OM_uint32 min_s;
gss_release_name(&min_s, &mech_sess->name);
(void)gss_release_name(&min_s, &mech_sess->name);
free(sess->mech_sess);
sess->mech_sess = NULL;
@ -183,7 +183,7 @@ saslc__mech_gssapi_encode(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_ERROR;
}
memcpy(*out, output.value, *outlen);
gss_release_buffer(&min_s, &output);
(void)gss_release_buffer(&min_s, &output);
} else
*out = NULL;
@ -238,7 +238,7 @@ saslc__mech_gssapi_decode(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_ERROR;
}
memcpy(*out, output.value, *outlen);
gss_release_buffer(&min_s, &output);
(void)gss_release_buffer(&min_s, &output);
} else
*out = NULL;
@ -298,7 +298,7 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_ERROR;
}
name.value = input_name;
name.length = len + 1;
name.length = (size_t)len + 1;
maj_s = gss_import_name(&min_s, &name,
GSS_C_NT_HOSTBASED_SERVICE, &mech_sess->name);
@ -321,7 +321,7 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
maj_s = gss_init_sec_context(&min_s, GSS_C_NO_CREDENTIAL,
&mech_sess->context, mech_sess->name, GSS_C_NO_OID,
GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 0,
(OM_uint32)(GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG), 0,
GSS_C_NO_CHANNEL_BINDINGS, input_buf, NULL, &output, NULL,
NULL);
@ -340,7 +340,7 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_ERROR;
}
memcpy(*out, output.value, *outlen);
gss_release_buffer(&min_s, &output);
(void)gss_release_buffer(&min_s, &output);
} else
*out = NULL;
return MECH_STEP;
@ -369,8 +369,8 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_ERROR;
}
name.value = input_name;
input.length = len + 1;
gss_release_buffer(&min_s, &output);
input.length = (size_t)len + 1;
(void)gss_release_buffer(&min_s, &output);
maj_s = gss_wrap(&min_s, mech_sess->context,
0 /* FALSE - RFC2222 */, GSS_C_QOP_DEFAULT, &input, NULL,
@ -390,7 +390,7 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_ERROR;
}
memcpy(*out, output.value, *outlen);
gss_release_buffer(&min_s, &output);
(void)gss_release_buffer(&min_s, &output);
} else
*out = NULL;
@ -398,7 +398,7 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
return MECH_OK;
default:
assert(/*CONSTCOND*/0); /* impossible */
/* NOTREACHED */
/*NOTREACHED*/
return MECH_ERROR;
}
}
@ -406,7 +406,6 @@ saslc__mech_gssapi_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_gssapi = {
"GSSAPI", /* name */
FLAG_NONE, /* flags */
saslc__mech_gssapi_create, /* create */
saslc__mech_gssapi_cont, /* step */
saslc__mech_gssapi_encode, /* encode */

View File

@ -1,4 +1,4 @@
/* $Id: mech_login.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech_login.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -90,10 +90,9 @@ saslc__mech_login_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_login = {
"LOGIN", /* name */
FLAG_PLAINTEXT, /* flags */
saslc__mech_generic_create, /* create */
saslc__mech_login_cont, /* step */
NULL, /* encode */
NULL, /* decode */
saslc__mech_generic_encode, /* encode */
saslc__mech_generic_decode, /* decode */
saslc__mech_generic_destroy /* destroy */
};

View File

@ -1,4 +1,4 @@
/* $Id: mech_plain.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: mech_plain.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -109,10 +109,12 @@ saslc__mech_plain_cont(saslc_sess_t *sess, const void *in, size_t inlen,
len = asprintf(&outstr, "%s%c%s%c%s", authzid != NULL ?
authzid : "", NUL_DELIM, authcid, NUL_DELIM, passwd);
if (len == -1)
if (len == -1) {
saslc__error_set_errno(ERR(sess), ERROR_NOMEM);
return MECH_ERROR;
}
*out = outstr;
*outlen = len + 1;
*outlen = (size_t)len + 1;
return MECH_OK;
}
@ -121,10 +123,9 @@ saslc__mech_plain_cont(saslc_sess_t *sess, const void *in, size_t inlen,
/* mechanism definition */
const saslc__mech_t saslc__mech_plain = {
"PLAIN", /* name */
FLAG_PLAINTEXT, /* flags */
saslc__mech_generic_create, /* create */
saslc__mech_plain_cont, /* step */
NULL, /* encode */
NULL, /* decode */
saslc__mech_generic_encode, /* encode */
saslc__mech_generic_decode, /* decode */
saslc__mech_generic_destroy /* destroy */
};

View File

@ -1,4 +1,4 @@
/* $Id: parser.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: parser.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -209,8 +209,9 @@ saslc__get_tokens(char *line)
static int
saslc__parse_line(char *line, saslc__dict_t *dict)
{
char *opt, *val, len;
char *opt, *val;
int rv = -1;
size_t len;
saslc__token_t *token, *head;
token = saslc__get_tokens(line);
@ -244,7 +245,7 @@ saslc__parse_line(char *line, saslc__dict_t *dict)
TOKEN_NUM)
goto out;
/* insert (option, value) into dictionary */
if (saslc__dict_insert(dict, opt, val) < 0)
if (saslc__dict_insert(dict, opt, val) != DICT_OK)
goto out;
token = token->next; /* parse next token */
}
@ -274,12 +275,12 @@ saslc__parse_file(saslc_t *ctx, char *path, saslc__dict_t *dict)
fd = fopen(path, "r");
if (fd == NULL) {
/* XXX */
saslc__error_set(ERR(ctx), ERROR_PARSE, "can't open file");
saslc__error_set(ERR(ctx), ERROR_PARSE,
"can't open configuration file");
return 0;
}
while (fgets(input, sizeof(input), fd) != NULL) {
while (fgets(input, (int)sizeof(input), fd) != NULL) {
/* strip newline char */
c = strchr(input, '\n');
if (c != NULL)
@ -334,8 +335,7 @@ saslc__parser_config(saslc_t *ctx)
return -1;
/* parse mechs */
for (mech_node = ctx->mechanisms->lh_first; mech_node != NULL;
mech_node = mech_node->nodes.le_next) {
LIST_FOREACH(mech_node, &ctx->mechanisms, nodes) {
snprintf(path, sizeof(path), "%s/%s/%s/%s%s",
config_path, appname, SASLC__CONFIG_MECH_DIRECTORY,
mech_node->mech->name, SASLC__CONFIG_SUFFIX);

View File

@ -1,4 +1,4 @@
/* $Id: parser.h,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: parser.h,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -38,8 +38,6 @@
#ifndef _PARSER_H_
#define _PARSER_H_
#include <saslc.h>
#define SASLC__CONFIG_PATH "/etc/saslc.d"
#define SASLC__CONFIG_MAIN_FILE "saslc"
#define SASLC__CONFIG_MECH_DIRECTORY "mech"

View File

@ -1,4 +1,4 @@
/* $Id: saslc.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: saslc.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -25,7 +25,7 @@
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
@ -40,6 +40,7 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include "dict.h"
#include "parser.h"
#include "saslc_private.h"
@ -51,38 +52,38 @@
static bool saslc__valid_appname(const char *);
/**
* @brief checks if application name is legal
* @brief checks if application name is valid
* @param appname application name
* @return true if application name is legal, false otherwise
* @return true if application name is valid, false otherwise
*/
static bool
saslc__valid_appname(const char *appname)
{
const char *p;
const char *p;
for (p = appname; *p; p++)
if (!isalnum((unsigned char)*p))
return false;
for (p = appname; *p; p++)
if (!isalnum((unsigned char)*p))
return false;
return true;
return true;
}
/**
* @brief allocates new saslc context
* @return pointer to the saslc context
* @return saslc context
*/
saslc_t *
saslc_alloc(void)
{
return calloc(1, sizeof(saslc_t));
return calloc(1, sizeof(saslc_t));
}
/**
* @brief initializes sasl context, basing on application name function
* parses configuration files, sets up default peroperties, creates
* parses configuration files, sets up default peroperties and creates
* mechanisms list for the context.
* @param ctx sasl context
* @param appname application name, NULL could be used for generic aplication
@ -92,93 +93,104 @@ saslc_alloc(void)
int
saslc_init(saslc_t *ctx, const char *appname)
{
memset(ctx, 0, sizeof(*ctx));
/* reference counter */
ctx->refcnt = 0;
ctx->prop = saslc__dict_create();
LIST_INIT(&ctx->sessions);
/* appname */
if (appname != NULL) {
/* check if appname is valid */
if (saslc__valid_appname(appname) == false) {
saslc__error_set(ERR(ctx), ERROR_BADARG,
"application name is not permited");
free(ctx->prop);
ctx->prop = NULL;
return -1;
}
ctx->prop = saslc__dict_create();
if ((ctx->appname = strdup(appname)) == NULL) {
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
free(ctx->prop);
ctx->prop = NULL;
return -1;
}
} else
ctx->appname = NULL;
if (ctx->prop == NULL)
return -1;
/* mechanisms list */
ctx->mechanisms = saslc__mech_list_create(ctx);
/* appname */
if (appname != NULL) {
/* check if appname is valid */
if (saslc__valid_appname(appname) == false) {
saslc__error_set(ERR(ctx), ERROR_BADARG,
"application name is not permited");
goto error;
}
if (ctx->mechanisms == NULL)
return -1;
ctx->appname = strdup(appname);
if (ctx->appname == NULL) {
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
goto error;
}
} else
ctx->appname = NULL;
/* @param configuration default properties */
if (saslc__parser_config(ctx) < 0) {
free((void *)(intptr_t)ctx->appname);
ctx->appname = NULL;
saslc__dict_destroy(ctx->prop);
ctx->prop = NULL;
saslc__mech_list_destroy(ctx->mechanisms);
ctx->mechanisms = NULL;
return -1;
}
/* mechanisms list */
if (saslc__mech_list_create(ctx) == -1)
goto error;
return 0;
/* parse configuration files */
if (saslc__parser_config(ctx) == -1)
/* errno is set up by parser */
goto error;
return 0;
error:
if (ctx->appname != NULL)
free((void *)ctx->appname);
if (ctx->prop != NULL)
saslc__dict_destroy(ctx->prop);
ctx->appname = NULL;
ctx->prop = NULL;
return -1;
}
/**
* @brief gets string message of the error.
* @brief gets string message of last error.
* @param ctx context
* @return pointer to the error message.
* @return error string
*/
const char *
saslc_strerror(saslc_t *ctx)
{
return saslc__error_get_strerror(ERR(ctx));
return saslc__error_get_strerror(ERR(ctx));
}
/**
* @brief destroys and deallocate resources used by the context.
* Context shouldn't have got any sessions assigned to it.
* @param ctx context
* @return 0 on success, -1 on failure.
* @param destroy_sessions indicates if all existing sessions assigned to
* the context (if any) should be destroyed
* @return 0 on success, -1 on failure
*/
int
saslc_end(saslc_t *ctx)
saslc_end(saslc_t *ctx, bool destroy_sessions)
{
if (ctx->refcnt > 0) {
saslc__error_set(ERR(ctx), ERROR_GENERAL,
"context has got assigned active sessions");
return -1;
}
/* check if there're any assigned sessions */
if (!LIST_EMPTY(&ctx->sessions) && destroy_sessions == false) {
saslc__error_set(ERR(ctx), ERROR_GENERAL,
"context has got assigned active sessions");
return -1;
}
/* mechanism list */
if (ctx->mechanisms != NULL)
saslc__mech_list_destroy(ctx->mechanisms);
/* destroy all assigned sessions (note that if any nodes are assigned,
* then destroy_sessions == true) */
assert(LIST_EMPTY(&ctx->sessions) || destroy_sessions == true);
while (!LIST_EMPTY(&ctx->sessions))
saslc_sess_end(LIST_FIRST(&ctx->sessions));
/* properties */
if (ctx->prop != NULL)
saslc__dict_destroy(ctx->prop);
/* mechanism list */
if (!LIST_EMPTY(&ctx->mechanisms))
saslc__mech_list_destroy(&ctx->mechanisms);
/* application name */
if (ctx->appname != NULL)
free((void *)(intptr_t)ctx->appname);
/* properties */
if (ctx->prop != NULL)
saslc__dict_destroy(ctx->prop);
/* free context */
free(ctx);
/* application name */
free(ctx->appname);
return 0;
/* free context */
free(ctx);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $Id: saslc_private.h,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: saslc_private.h,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -39,27 +39,31 @@
#define _SASLC_PRIVATE_H_
#include <saslc.h>
#include <stdint.h>
#include <sys/queue.h>
#include "dict.h"
#include "mech.h"
#include "error.h"
typedef struct saslc__sess_list_t saslc__sess_list_t;
LIST_HEAD(saslc__sess_list_t, saslc_sess_t);
/** library context structure */
struct saslc_t {
const char *appname; /**< application name */
saslc__dict_t *prop; /**< configuration options */
saslc__mech_list_t *mechanisms; /**< avaiable mechanisms */
uint32_t refcnt; /**< reference count */
saslc__error_t err; /**< error */
char *appname; /**< application name */
saslc__dict_t *prop; /**< configuration options */
saslc__mech_list_t mechanisms; /**< available mechanisms */
saslc__error_t err; /**< error */
saslc__sess_list_t sessions; /**< sessions */
};
/** session context structure */
struct saslc_sess_t {
saslc_t *context; /**< library context */
const saslc__mech_t *mech; /**< mechanism */
void *mech_sess; /**< mechanism session */
saslc__dict_t *prop; /**< session properties */
saslc__error_t err; /**< error */
saslc_t *context; /**< library context */
const saslc__mech_t *mech; /**< mechanism */
void *mech_sess; /**< mechanism session */
saslc__dict_t *prop; /**< session properties */
saslc__error_t err; /**< error */
LIST_ENTRY(saslc_sess_t) nodes; /**< nodes */
};
#endif /* ! _SASLC_PRIVATE_H_ */

View File

@ -1,4 +1,4 @@
/* $Id: xsess.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: xsess.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/*
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@ -39,6 +39,7 @@
#include <stdio.h>
#include <string.h>
#include <saslc.h>
#include <sys/queue.h>
#include <assert.h>
#include "dict.h"
#include "error.h"
@ -51,12 +52,11 @@ static const saslc__mech_t *
saslc__sess_choose_mech(saslc_t *, const char *);
/**
* @brief chooses best mechanism form the mechs list for
* the sasl session.
* @brief chooses best mechanism from the mechs list for the sasl session.
* @param ctx sasl context
* @param mechs comma separated list of mechanisms eg. "PLAIN,LOGIN", note that
* this function is not case sensitive
* @return pointer to the mech on success, NULL if none mechanism was chose
* @return pointer to the mech on success, NULL if none mechanism is chosen
*/
static const saslc__mech_t *
@ -66,7 +66,8 @@ saslc__sess_choose_mech(saslc_t *ctx, const char *mechs)
const char *mech_name;
const saslc__mech_list_node_t *m = NULL;
if ((c = strdup(mechs)) == NULL) {
c = strdup(mechs);
if (c == NULL) {
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
return NULL;
}
@ -78,15 +79,17 @@ saslc__sess_choose_mech(saslc_t *ctx, const char *mechs)
if (strchr(e, ',') != NULL) {
while ((e = strchr(e, ',')) != NULL) {
*e = '\0';
if ((m = saslc__mech_list_get(ctx->mechanisms,
mech_name)) != NULL)
goto out;
m = saslc__mech_list_get(&ctx->mechanisms,
mech_name);
if (m != NULL)
goto out;
e++;
mech_name = e;
}
}
m = saslc__mech_list_get(ctx->mechanisms, mech_name);
m = saslc__mech_list_get(&ctx->mechanisms, mech_name);
out:
free(c);
return m != NULL ? m->mech : NULL;
@ -96,46 +99,52 @@ out:
* @brief sasl session initializaion. Function initializes session
* property dictionary, chooses best mechanism, creates mech session.
* @param ctx sasl context
* @param mechs comma separated list of mechanisms eg. "PLAIN,LOGIN", note that
* this function is not case sensitive
* @param mechs comma separated list of mechanisms eg. "PLAIN,LOGIN", note
* that this function is not case sensitive
* @return pointer to the sasl session on success, NULL on failure
*/
saslc_sess_t *
saslc_sess_init(saslc_t *ctx, const char *mechs)
{
saslc_sess_t *sess;
saslc_sess_t *sess = NULL;
if ((sess = calloc(1, sizeof(*sess))) == NULL) {
sess = calloc(1, sizeof(*sess));
if (sess == NULL) {
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
return NULL;
}
/* mechanism initialization */
if ((sess->mech = saslc__sess_choose_mech(ctx, mechs)) == NULL) {
free(sess);
sess->mech = saslc__sess_choose_mech(ctx, mechs);
if (sess->mech == NULL) {
saslc__error_set(ERR(ctx), ERROR_MECH,
"mechanism is not supported");
return NULL;
goto error;
}
/* create mechanism session */
if (sess->mech->create(sess) < 0) {
free(sess);
return NULL;
}
if (sess->mech->create(sess) < 0)
/* error is set by mech's create function */
goto error;
/* properties */
if ((sess->prop = saslc__dict_create()) == NULL) {
free(sess);
sess->prop = saslc__dict_create();
if (sess->prop == NULL) {
saslc__error_set(ERR(ctx), ERROR_NOMEM, NULL);
return NULL;
goto error;
}
sess->context = ctx;
ctx->refcnt++;
LIST_INSERT_HEAD(&ctx->sessions, sess, nodes);
return sess;
error:
free(sess);
return NULL;
}
/**
@ -149,7 +158,7 @@ saslc_sess_end(saslc_sess_t *sess)
{
sess->mech->destroy(sess);
saslc__dict_destroy(sess->prop);
sess->context->refcnt--;
LIST_REMOVE(sess, nodes);
free(sess);
}
@ -165,8 +174,7 @@ saslc_sess_end(saslc_sess_t *sess)
int
saslc_sess_setprop(saslc_sess_t *sess, const char *name, const char *value)
{
/* check if key exists, if so then remove it from dictionary */
/* check if key exists, if so then remove it from the dictionary */
if (saslc__dict_get(sess->prop, name) != NULL) {
if (saslc__dict_remove(sess->prop, name) != DICT_OK)
assert(/*CONSTCOND*/0);
@ -198,7 +206,7 @@ saslc_sess_setprop(saslc_sess_t *sess, const char *name, const char *value)
* configuration), mechanism dicionary.
* @param sess sasl session
* @param name property name
* @return property value on success, NULL on failure.
* @return property value, NULL on failure.
*/
const char *
@ -208,23 +216,24 @@ saslc_sess_getprop(saslc_sess_t *sess, const char *name)
saslc__mech_list_node_t *m;
/* get property from the session dictionary */
if ((r = saslc__dict_get(sess->prop, name)) != NULL)
r = saslc__dict_get(sess->prop, name);
if (r != NULL)
return r;
/* get property from the context dictionary */
if ((r = saslc__dict_get(sess->context->prop, name)) != NULL)
r = saslc__dict_get(sess->context->prop, name);
if (r != NULL)
return r;
/* get property form the mechanism dictionary */
if ((m = saslc__mech_list_get(sess->context->mechanisms,
sess->mech->name)) == NULL)
return NULL;
m = saslc__mech_list_get(&sess->context->mechanisms,
sess->mech->name);
return saslc__dict_get(m->prop, name);
return m != NULL ? saslc__dict_get(m->prop, name) : NULL;
}
/**
* @brief do one step of the sasl authentication, input data
* @brief does one step of the sasl authentication, input data
* and its lenght are stored in in and inlen, output is stored in out and
* outlen. This function is and wrapper for mechanism step functions.
* Additionaly it checks if session is not already authorized and handles
@ -241,12 +250,12 @@ saslc_sess_getprop(saslc_sess_t *sess, const char *name)
int
saslc_sess_cont(saslc_sess_t *sess, const void *in, size_t inlen, void **out,
size_t *outlen)
size_t *outlen)
{
int r;
saslc__mech_sess_t *ms = sess->mech_sess;
saslc__mech_sess_t *mech_sess = sess->mech_sess;
if (ms->status == STATUS_AUTHENTICATED) {
if (mech_sess->status == STATUS_AUTHENTICATED) {
saslc__error_set(ERR(sess), ERROR_MECH,
"session authenticated");
return MECH_ERROR;
@ -255,9 +264,10 @@ saslc_sess_cont(saslc_sess_t *sess, const void *in, size_t inlen, void **out,
r = sess->mech->cont(sess, in, inlen, out, outlen);
if (r == MECH_OK)
ms->status = STATUS_AUTHENTICATED;
mech_sess->status = STATUS_AUTHENTICATED;
mech_sess->step++;
ms->step++;
return r;
}

View File

@ -1,4 +1,4 @@
/* $Id: style.css,v 1.1.1.1 2010/11/27 21:23:58 agc Exp $ */
/* $Id: style.css,v 1.2 2011/01/29 23:35:30 agc Exp $ */
body
{

View File

@ -2,6 +2,7 @@ Content-Type: application/X-atf-atffile; version="1"
prop: test-suite = saslc
tp: t_mech
tp: t_crypto
tp: t_dict
tp: t_error

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $
# $Id: Makefile,v 1.2 2011/01/29 23:35:31 agc Exp $
CC=gcc
SRC_PREFIX=../src
@ -6,24 +6,39 @@ CFLAGS=-I../include -I$(SRC_PREFIX)
ENV=PATH=/usr/local/bin:${PATH}
ATFLIBS=-latf-c -lssl
LDFLAGS=`pwd`/$(SRC_PREFIX)/libsaslc.so -ggdb
TEST_CASES=t_dict t_session t_crypto t_error t_saslc t_parser
TEST_CASES_C=t_dict t_session t_crypto t_error t_saslc t_parser
TEST_CASES_SH=t_mech
TEST_CASES=$(TEST_CASES_C)
VALGRIND=valgrind
VALGRIND_OPTS=--leak-check=full -q
all: build
build: $(TEST_CASES) example_client
build: $(TEST_CASES_SH) $(TEST_CASES_C) example_client
$(TEST_CASES):
$(CC) -o $@.o -c $@.c $(CFLAGS) -I/usr/include/local
$(CC) -o $@ $@.o $(LDFLAGS) $(ATFLIBS)
$(TEST_CASES_SH):
@echo "building $@"
@$(ENV) atf-compile -o $@ $@.sh
$(TEST_CASES_C):
@echo "building $@"
@$(CC) -o $@.o -c $@.c $(CFLAGS) -I/usr/include/local
@$(CC) -o $@ $@.o $(LDFLAGS) $(ATFLIBS)
atf:
@echo "atf tests:"
@$(ENV) atf-run | $(ENV) atf-report
@echo ""
@echo "*************************************"
@echo "* ATF TESTS: *"
@echo "*************************************"
@echo ""
@$(ENV) atf-run -v test_dir=`pwd` | $(ENV) atf-report
valgrind:
@echo "valgrind tests:"
@echo ""
@echo "*************************************"
@echo "* VALGRIND TESTS: *"
@echo "*************************************"
@echo ""
@for prog in $(TEST_CASES); do \
echo "$$prog:"; \
for testcase in `./$$prog -l | grep ident | awk {'print $$2'}`; do \
@ -37,4 +52,5 @@ tests: build atf valgrind
example_client: example_client.c
clean:
rm -f $(TEST_CASES) *.o resfile example_client
@rm -f $(TEST_CASES_C) $(TEST_CASES_SH) *.o resfile \
example_client

View File

@ -1,4 +1,4 @@
/* $Id: example_client.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: example_client.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -41,8 +41,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 1024
#include <limits.h>
static void
print_help(void)
@ -82,7 +81,7 @@ main(int argc, char **argv)
char *mechanism = NULL;
saslc_t *ctx;
saslc_sess_t *sess;
char input[MAX_LINE];
char input[LINE_MAX];
char *option, *var;
char *output;
static char empty[] = "";
@ -148,14 +147,14 @@ main(int argc, char **argv)
cont = saslc_sess_cont(sess, input, input_len, (void **)&output,
&output_len);
if (cont < 0)
goto error_sess;
printf("%s\n", output);
goto error_sess;
printf("%s\n", output==NULL?"empty line":output);
if (cont == 0)
break;
break;
}
saslc_sess_end(sess);
if (saslc_end(ctx) < 0)
if (saslc_end(ctx, true) < 0)
goto error;
return 0;

View File

@ -1,4 +1,4 @@
/* $Id: t_crypto.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: t_crypto.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -168,7 +168,9 @@ ATF_TC_BODY(t_crypto_md5, tc)
const char *digest;
int i;
for (i = 0; i < MD5_TEST_CASES; i++) {
digest = saslc__crypto_md5(md5_test_cases[i].in);
digest =
saslc__crypto_md5(md5_test_cases[i].in,
strlen(md5_test_cases[i].in));
ATF_CHECK_STREQ_MSG(digest, md5_test_cases[i].out,
"saslc__crypto_md5() failed on %s got %s should be: %s",
md5_test_cases[i].in, digest, md5_test_cases[i].out);

View File

@ -1,4 +1,4 @@
/* $Id: t_dict.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: t_dict.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.

View File

@ -1,4 +1,4 @@
/* $Id: t_error.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: t_error.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -45,7 +45,7 @@
ATF_TC(t_saslc__error);
ATF_TC_HEAD(t_saslc__error, tc)
{
atf_tc_set_md_var(tc, "descr", "saslc__error_*() tests");
atf_tc_set_md_var(tc, "descr", "saslc__error_*() tests");
}
ATF_TC_BODY(t_saslc__error, tc)
{
@ -58,12 +58,11 @@ ATF_TC_BODY(t_saslc__error, tc)
ATF_CHECK_STREQ(saslc_strerror(ctx), "test");
saslc__error_set_errno(ERR(ctx), ERROR_NOMEM);
ATF_CHECK_STREQ(saslc_strerror(ctx), "no memory available");
ATF_REQUIRE_EQ(saslc_end(ctx), 0);
ATF_REQUIRE_EQ(saslc_end(ctx, false), 0);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, t_saslc__error);
ATF_TP_ADD_TC(tp, t_saslc__error);
return atf_no_error();
}

View File

@ -1,4 +1,4 @@
/* $Id: t_parser.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: t_parser.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -40,28 +40,44 @@
#include <dict.h>
#include <saslc.h>
#include "parser.h"
//#include "saslc_private.h"
/* src/parser.c test cases */
static void set_env(atf_tc_t *tc)
{
char *dir;
asprintf(&dir, "%s/%s/", atf_tc_get_config_var(tc, "srcdir"),
"parser_tests");
if (dir == NULL)
exit(-1);
setenv(SASLC__ENV_PATH, dir, 1);
free(dir);
}
ATF_TC(t_parser_test1);
ATF_TC_HEAD(t_parser_test1, tc)
{
set_env(tc);
atf_tc_set_md_var(tc, "descr", "parser test1");
}
ATF_TC_BODY(t_parser_test1, tc)
{
saslc_t *ctx;
ATF_REQUIRE(ctx = saslc_alloc());
ATF_CHECK_EQ(saslc_init(ctx, "test1"), 0);
ATF_REQUIRE_EQ(saslc_end(ctx), 0);
ATF_REQUIRE_EQ(saslc_end(ctx, true), 0);
}
ATF_TC(t_parser_test2);
ATF_TC_HEAD(t_parser_test2, tc)
{
atf_tc_set_md_var(tc, "descr", "parser test2");
set_env(tc);
}
ATF_TC_BODY(t_parser_test2, tc)
{
@ -72,22 +88,21 @@ ATF_TC_BODY(t_parser_test2, tc)
ATF_REQUIRE(ctx = saslc_alloc());
ATF_CHECK_EQ(saslc_init(ctx, "test2"), 0);
ATF_REQUIRE((sess = saslc_sess_init(ctx, "ANONYMOUS")));
ATF_REQUIRE(val = saslc_sess_getprop(sess, "TEST"));
ATF_CHECK_STREQ(val, "one");
ATF_REQUIRE(val = saslc_sess_getprop(sess, "TEST2"));
ATF_CHECK_STREQ(val, "one two");
ATF_REQUIRE(val = saslc_sess_getprop(sess, "TEST3"));
ATF_CHECK_STREQ(val, "one two three");
ATF_REQUIRE(val = saslc_sess_getprop(sess, "HOSTNAME"));
ATF_CHECK_STREQ(val, "szefpodworka.pl");
ATF_REQUIRE(val = saslc_sess_getprop(sess, "AUTHZID"));
ATF_CHECK_STREQ(val, "test1");
ATF_REQUIRE(val = saslc_sess_getprop(sess, "ID"));
ATF_CHECK_STREQ(val, "6669");
saslc_sess_end(sess);
ATF_REQUIRE_EQ(saslc_end(ctx), 0);
saslc_sess_end(sess);
ATF_REQUIRE_EQ(saslc_end(ctx, false), 0);
}
ATF_TC(t_parser_test3);
ATF_TC_HEAD(t_parser_test3, tc)
{
atf_tc_set_md_var(tc, "descr", "parser test3");
set_env(tc);
}
ATF_TC_BODY(t_parser_test3, tc)
{
@ -96,7 +111,7 @@ ATF_TC_BODY(t_parser_test3, tc)
ATF_REQUIRE(ctx = saslc_alloc());
ATF_CHECK_EQ(saslc_init(ctx, "test3"), -1);
ATF_REQUIRE_EQ(saslc_end(ctx), 0);
ATF_REQUIRE_EQ(saslc_end(ctx, false), 0);
}
@ -104,7 +119,7 @@ ATF_TC_BODY(t_parser_test3, tc)
ATF_TP_ADD_TCS(tp)
{
setenv(SASLC__ENV_PATH, "parser_tests/", 1);
ATF_TP_ADD_TC(tp, t_parser_test1);
ATF_TP_ADD_TC(tp, t_parser_test2);
ATF_TP_ADD_TC(tp, t_parser_test3);

View File

@ -1,4 +1,4 @@
/* $Id: t_saslc.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: t_saslc.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -49,7 +49,7 @@ ATF_TC_BODY(t_session_init, tc)
saslc_t *ctx;
ATF_REQUIRE(ctx = saslc_alloc());
ATF_REQUIRE_EQ(saslc_init(ctx, NULL), 0);
ATF_REQUIRE_EQ(saslc_end(ctx), 0);
ATF_REQUIRE_EQ(saslc_end(ctx, true), 0);
}
ATF_TP_ADD_TCS(tp)

View File

@ -1,4 +1,4 @@
/* $Id: t_session.c,v 1.1.1.1 2010/11/27 21:23:59 agc Exp $ */
/* $Id: t_session.c,v 1.2 2011/01/29 23:35:31 agc Exp $ */
/* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -46,10 +46,10 @@ ATF_TC_HEAD(t_sess, tc)
}
ATF_TC_BODY(t_sess, tc)
{
saslc_t *ctx;
saslc_t *ctx;
saslc_sess_t *sess;
ATF_REQUIRE(ctx = saslc_alloc());
ATF_REQUIRE_EQ(saslc_init(ctx, NULL), 0);
ATF_REQUIRE(ctx = saslc_alloc());
ATF_REQUIRE_EQ(saslc_init(ctx, NULL), 0);
ATF_CHECK(sess = saslc_sess_init(ctx, "PLAIN"));
if (sess != NULL)
saslc_sess_end(sess);
@ -60,15 +60,16 @@ ATF_TC_BODY(t_sess, tc)
ATF_CHECK(sess = saslc_sess_init(ctx, "LOGIN,NOTEXISTS"));
if (sess != NULL)
saslc_sess_end(sess);
ATF_REQUIRE(sess = saslc_sess_init(ctx, "LOGiN"));
ATF_REQUIRE(sess = saslc_sess_init(ctx, "LOGiN"));
ATF_CHECK_STREQ(saslc_sess_strmech(sess), "LOGIN");
ATF_REQUIRE_EQ(saslc_end(ctx, false), -1);
saslc_sess_end(sess);
ATF_REQUIRE_EQ(saslc_end(ctx), 0);
ATF_REQUIRE_EQ(saslc_end(ctx, false), 0);
}
ATF_TP_ADD_TCS(tp)
{
/* context initialization */
ATF_TP_ADD_TC(tp, t_sess);
ATF_TP_ADD_TC(tp, t_sess);
return atf_no_error();
}