Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
119 lines (95 sloc) 2.51 KB
/*
Copyright (c) 2008-2012 NFG Net Facilities Group BV support@nfg.nl
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dbmail.h"
#include "dm_cram.h"
#define THIS_MODULE "CRAM"
/*
*/
#define T Cram_T
struct T {
char *challenge;
char *username;
char *response;
};
T Cram_new(void)
{
T C;
C = g_malloc0(sizeof(*C));
return C;
}
static gchar * init_challenge(void)
{
char name[255];
memset(name,0, sizeof(name));
if (getdomainname(name,sizeof(name))) {
if (gethostname(name, sizeof(name)))
strcpy(name,"(none)");
}
return g_mime_utils_generate_message_id(name);
}
void Cram_setChallenge(T C, const char *challenge)
{
if (! challenge)
C->challenge = init_challenge();
else
C->challenge = g_strdup(challenge);
}
const gchar * Cram_getChallenge(T C)
{
if (! C->challenge)
Cram_setChallenge(C, NULL);
return (const gchar *)C->challenge;
}
const gchar * Cram_getUsername(T C)
{
assert(C->username);
return C->username;
}
gboolean Cram_decode(T C, const char * response)
{
gsize len = 0, space = 0;
gchar *s = dm_base64_decode(response, &len);
space = stridx((const char *)s,' ');
if (space == len)
return FALSE;
C->username = g_strndup(s, space);
space++;
C->response = g_strndup(s + space, len - space);
g_free(s);
return TRUE;
}
gboolean Cram_verify(T C, const char *credentials)
{
gboolean r = FALSE;
unsigned char d[1024];
memset(d,0,sizeof(d));
MHASH ctx = mhash_hmac_init(MHASH_MD5, (void *)credentials, strlen(credentials), mhash_get_hash_pblock(MHASH_MD5));
mhash(ctx, C->challenge, strlen(C->challenge));
mhash_hmac_deinit(ctx, (gpointer)d);
char *result = dm_digest(d, MHASH_MD5);
if (strncmp(C->response, result, strlen(C->response))==0)
r = TRUE;
g_free(result);
return r;
}
void Cram_free(T *C)
{
T c = *C;
if (c->challenge) g_free(c->challenge);
if (c->username) g_free(c->username);
if (c->response) g_free(c->response);
if (c) g_free(c);
}
Something went wrong with that request. Please try again.