<commit_before>/* Copyright (C) 2002 <NAME> */

/* Digest-MD5 SASL authentication, see rfc-2831 */

#include "common.h"
#include "base64.h"
#include "buffer.h"
#include "hex-binary.h"
#include "md5.h"
#include "randgen.h"
#include "str.h"

#include "auth.h"
#include "cookie.h"
#include "userinfo.h"

#include <stdlib.h>

#define SERVICE_TYPE "imap"

/* Linear whitespace */
#define IS_LWS(c) ((c) == ' ' || (c) == '\t')

typedef enum {
	QOP_AUTH	= 0x01,	/* authenticate */
	QOP_AUTH_INT	= 0x02, /* + integrity protection, not supported yet */
	QOP_AUTH_CONF	= 0x04, /* + encryption, not supported yet */

	QOP_COUNT	= 3
} QopOption;

static char *qop_names[] = { "auth", "auth-int", "auth-conf" };

typedef struct {
	Pool pool;
	unsigned int authenticated:1;

	/* requested: */
	char *nonce;
	QopOption qop;

	/* received: */
	char *realm; /* may be NULL */
	char *username;
	char *cnonce;
	char *nonce_count;
	char *qop_value;
	char *digest_uri; /* may be NULL */
	unsigned char response[32];
	unsigned long maxbuf;
	unsigned int nonce_found:1;

	/* final reply: */
	char *rspauth;
        AuthCookieReplyData cookie_reply;
} AuthData;

static const char *get_digest_challenge(AuthData *auth)
{
	String *qoplist, *realms;
	Buffer *buf;
	const char *const *tmp;
	unsigned char nonce[16];
	int i;

	/*
	   realm="hostname" (multiple allowed)
	   nonce="randomized data, at least 64bit"
	   qop-options="auth,auth-int,auth-conf"
	   maxbuf=number (with auth-int, auth-conf, defaults to 64k)
	   charset="utf-8" (iso-8859-1 if it doesn't exist)
	   algorithm="md5-sess"
	   cipher="3des,des,rc4-40,rc4,rc4-56" (with auth-conf)
	*/

	/* get 128bit of random data as nonce */
	random_fill(nonce, sizeof(nonce));

	t_push();
	buf = buffer_create_static(data_stack_pool,
				   MAX_BASE64_ENCODED_SIZE(sizeof(nonce))+1);

	base64_encode(nonce, sizeof(nonce), buf);
	buffer_append_c(buf, '\0');
	auth->nonce = p_strdup(auth->pool, buffer_get_data(buf, NULL));
	t_pop();

	/* get list of allowed QoPs */
	qoplist = t_str_new(32);
	for (i = 0; i < QOP_COUNT; i++) {
		if (auth->qop & (1 << i)) {
			if (str_len(qoplist) > 0)
				str_append_c(qoplist, ',');
			str_append(qoplist, qop_names[i]);
		}
	}

	realms = t_str_new(128);
	for (tmp = auth_realms; *tmp != NULL; tmp++) {
		str_printfa(realms, "realm=\"%s\"", *tmp);
		str_append_c(realms, ',');
	}

	return t_strconcat(str_c(realms),
			   "nonce=\"", auth->nonce, "\",",
			   "qop-options=\"", str_c(qoplist), "\",",
			   "charset=\"utf-8\",",
			   "algorithm=\"md5-sess\"",
			   NULL);
}

static int verify_auth(AuthData *auth)
{
	MD5Context ctx;
	unsigned char digest[16];
	const char *a1_hex, *a2_hex, *response_hex;<commit_msg>s/qop-options/qop/, fixes compatibility problem with Cyrus SASL library.<commit_after>/* Copyright (C) 2002 <NAME> */

/* Digest-MD5 SASL authentication, see rfc-2831 */

#include "common.h"
#include "base64.h"
#include "buffer.h"
#include "hex-binary.h"
#include "md5.h"
#include "randgen.h"
#include "str.h"

#include "auth.h"
#include "cookie.h"
#include "userinfo.h"

#include <stdlib.h>

#define SERVICE_TYPE "imap"

/* Linear whitespace */
#define IS_LWS(c) ((c) == ' ' || (c) == '\t')

typedef enum {
	QOP_AUTH	= 0x01,	/* authenticate */
	QOP_AUTH_INT	= 0x02, /* + integrity protection, not supported yet */
	QOP_AUTH_CONF	= 0x04, /* + encryption, not supported yet */

	QOP_COUNT	= 3
} QopOption;

static char *qop_names[] = { "auth", "auth-int", "auth-conf" };

typedef struct {
	Pool pool;
	unsigned int authenticated:1;

	/* requested: */
	char *nonce;
	QopOption qop;

	/* received: */
	char *realm; /* may be NULL */
	char *username;
	char *cnonce;
	char *nonce_count;
	char *qop_value;
	char *digest_uri; /* may be NULL */
	unsigned char response[32];
	unsigned long maxbuf;
	unsigned int nonce_found:1;

	/* final reply: */
	char *rspauth;
        AuthCookieReplyData cookie_reply;
} AuthData;

static const char *get_digest_challenge(AuthData *auth)
{
	String *qoplist, *realms;
	Buffer *buf;
	const char *const *tmp;
	unsigned char nonce[16];
	int i;

	/*
	   realm="hostname" (multiple allowed)
	   nonce="randomized data, at least 64bit"
	   qop="auth,auth-int,auth-conf"
	   maxbuf=number (with auth-int, auth-conf, defaults to 64k)
	   charset="utf-8" (iso-8859-1 if it doesn't exist)
	   algorithm="md5-sess"
	   cipher="3des,des,rc4-40,rc4,rc4-56" (with auth-conf)
	*/

	/* get 128bit of random data as nonce */
	random_fill(nonce, sizeof(nonce));

	t_push();
	buf = buffer_create_static(data_stack_pool,
				   MAX_BASE64_ENCODED_SIZE(sizeof(nonce))+1);

	base64_encode(nonce, sizeof(nonce), buf);
	buffer_append_c(buf, '\0');
	auth->nonce = p_strdup(auth->pool, buffer_get_data(buf, NULL));
	t_pop();

	/* get list of allowed QoPs */
	qoplist = t_str_new(32);
	for (i = 0; i < QOP_COUNT; i++) {
		if (auth->qop & (1 << i)) {
			if (str_len(qoplist) > 0)
				str_append_c(qoplist, ',');
			str_append(qoplist, qop_names[i]);
		}
	}

	realms = t_str_new(128);
	for (tmp = auth_realms; *tmp != NULL; tmp++) {
		str_printfa(realms, "realm=\"%s\"", *tmp);
		str_append_c(realms, ',');
	}

	return t_strconcat(str_c(realms),
			   "nonce=\"", auth->nonce, "\",",
			   "qop=\"", str_c(qoplist), "\",",
			   "charset=\"utf-8\",",
			   "algorithm=\"md5-sess\"",
			   NULL);
}

static int verify_auth(AuthData *auth)
{
	MD5Context ctx;
	unsigned char digest[16];
	const char *a1_hex, *a2_hex, *response_hex;
{'fraction_non_alphanumeric': 0.172305416897763, 'fraction_numerical': 0.026252542059530412, 'mean_word_length': 3.913714804722979, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1522931', 'n_tokens_mistral': 2357, 'n_tokens_neox': 2163, 'n_words': 490}