#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#ifndef macintosh
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <fcntl.h>
#include <ctype.h>
#include <openssl/md5.h>
#include <sasl.h>
#ifdef WITH_DES
# ifdef WITH_SSL_DES
# include <openssl/des.h>
# else
# include <des.h>
# endif
#endif
#ifdef WIN32
# include <winsock.h>
#else
# include <netinet/in.h>
#endif
#ifdef WIN32
#include "saslDIGESTMD5.h"
#else
extern int strcasecmp(const char *s1, const char *s2);
#endif
#ifdef macintosh
#endif
#ifdef sun
extern int gethostname(char *, int);
#endif
#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif
#define kDumpablePrefix "Digest "
#define NONCE_SIZE (32)
#define DIGEST_NOLAYER (1)
#define DIGEST_INTEGRITY (2)
#define DIGEST_PRIVACY (4)
#define HASHLEN 16
typedef unsigned char HASH[HASHLEN + 1];
#define HASHHEXLEN 32
typedef unsigned char HASHHEX[HASHHEXLEN + 1];
#define MAC_SIZE 10
#define MAC_OFFS 2
#define HT (9)
#define CR (13)
#define LF (10)
#define SP (32)
#define DEL (127)
typedef int cipher_function_t(void *,
const char *,
unsigned,
unsigned char[],
char *,
unsigned *);
typedef int cipher_init_t(void *, char [16], char [16]);
typedef void cipher_free_t(void *);
enum Context_type { DIGEST_SERVER_TYPE = 0, DIGEST_CLIENT_TYPE = 1 };
#ifdef WITH_RC4
typedef struct rc4_context_s rc4_context_t;
#endif
typedef struct buffer_info
{
char *data;
unsigned curlen;
unsigned reallen;
} buffer_info_t;
typedef struct global_context {
char *authid;
char *realm;
char *method;
unsigned char *nonce;
unsigned int nonce_count;
unsigned char *cnonce;
char isreplay;
char isOldMD5;
char noReauth;
time_t timeout;
time_t timestamp;
char *serverFQDN;
char *qop;
struct digest_cipher *bestcipher;
unsigned int server_maxbuf;
} global_context_t;
typedef struct context {
int state;
enum Context_type i_am;
global_context_t *global;
char *username;
char *authorization_id;
char *realm;
unsigned char *cnonce;
unsigned int noncecount;
char *qop;
char *digesturi;
unsigned int client_maxbuf;
int maxbuf_count;
char *charset;
char *userid;
char *cipher;
unsigned int n;
char *response;
char *response_value;
unsigned int seqnum;
unsigned int rec_seqnum;
HASH Ki_send;
HASH Ki_receive;
HASH HA1;
char *out_buf;
unsigned long out_buf_len;
buffer_info_t *enc_in_buf;
char *encode_buf, *decode_buf, *decode_once_buf;
unsigned encode_buf_len, decode_buf_len, decode_once_buf_len;
char *decode_tmp_buf;
unsigned decode_tmp_buf_len;
char *MAC_buf;
unsigned MAC_buf_len;
char *buffer;
char sizebuf[4];
int cursize;
int size;
int needsize;
unsigned int maxbuf;
cipher_function_t *cipher_enc;
cipher_function_t *cipher_dec;
cipher_init_t *cipher_init;
cipher_free_t *cipher_free;
#ifdef WITH_DES
des_key_schedule keysched_enc;
des_cblock ivec_enc;
des_key_schedule keysched_dec;
des_cblock ivec_dec;
des_key_schedule keysched_enc2;
des_key_schedule keysched_dec2;
#endif
#ifdef WITH_RC4
rc4_context_t *rc4_enc_context;
rc4_context_t *rc4_dec_context;
#endif
} digest_context_t;
typedef struct client_context {
digest_context_t common;
char *realm;
sasl_secret_t *password;
unsigned int free_password;
} client_context_t;
struct digest_cipher {
char *name;
unsigned ssf;
int n;
int flag;
cipher_function_t *cipher_enc;
cipher_function_t *cipher_dec;
cipher_init_t *cipher_init;
cipher_free_t *cipher_free;
};
typedef struct server_context {
digest_context_t common;
int stale;
} server_context_t;
void digest_dispose(void *conn_context);
int digest_server_parse(
const char *serverChallengeStr,
unsigned serverChallengeStrLen,
const char *clientin,
digest_context_t *outContext);
int digest_verify(digest_context_t *inContext,
const char *inPassword,
unsigned int inPasswordLength,
char **serverout,
unsigned *serveroutlen);
#ifdef __cplusplus
};
#endif