105 #ifdef HAVE_SASL_AUTH_CACHE
109 SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache_init(
const char *map,
int ttl)
111 const char *myname =
"smtp_sasl_auth_cache_init";
112 SMTP_SASL_AUTH_CACHE *auth_cache;
117 #define HAS_MULTIPLE_VALUES(s) ((s)[strcspn((s), CHARS_COMMA_SP)] != 0)
120 msg_panic(
"%s: empty SASL authentication cache name", myname);
122 msg_panic(
"%s: bad SASL authentication cache ttl: %d", myname, ttl);
123 if (HAS_MULTIPLE_VALUES(map))
124 msg_fatal(
"SASL authentication cache name \"%s\" "
125 "contains multiple values", map);
133 #define CACHE_DICT_OPEN_FLAGS \
134 (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE | DICT_FLAG_UTF8_REQUEST)
135 #define PROXY_COLON DICT_TYPE_PROXY ":"
136 #define PROXY_COLON_LEN (sizeof(PROXY_COLON) - 1)
139 msg_fatal(
"SASL authentication cache name \"%s\" must start with \""
142 auth_cache = (SMTP_SASL_AUTH_CACHE *)
mymalloc(
sizeof(*auth_cache));
143 auth_cache->dict =
dict_open(map, O_CREAT | O_RDWR, CACHE_DICT_OPEN_FLAGS);
144 auth_cache->ttl = ttl;
160 static char *smtp_sasl_auth_cache_make_key(
const char *host,
const char *user)
170 static char *smtp_sasl_auth_cache_make_pass(
const char *password)
174 base64_encode(buf, (
const char *) SHA1((
const unsigned char *) password,
175 strlen(password), 0),
182 static char *smtp_sasl_auth_cache_make_value(
const char *password,
188 unsigned long now = (
unsigned long) time((time_t *) 0);
190 pwd_hash = smtp_sasl_auth_cache_make_pass(password);
198 static int smtp_sasl_auth_cache_valid_value(SMTP_SASL_AUTH_CACHE *auth_cache,
200 const char *password)
202 ssize_t len = strlen(entry);
205 unsigned long now = (
unsigned long) time((time_t *) 0);
206 unsigned long time_stamp;
209 auth_cache->dsn =
myrealloc(auth_cache->dsn, len);
210 auth_cache->text =
myrealloc(auth_cache->text, len);
212 if (sscanf(entry,
"%lu;%[^;];%[^;];%[^\n]", &time_stamp, cache_hash,
213 auth_cache->dsn, auth_cache->text) != 4
215 msg_warn(
"bad smtp_sasl_auth_cache entry: %.100s", entry);
217 }
else if (time_stamp + auth_cache->ttl < now) {
220 curr_hash = smtp_sasl_auth_cache_make_pass(password);
221 valid = (strcmp(cache_hash, curr_hash) == 0);
230 int smtp_sasl_auth_cache_find(SMTP_SASL_AUTH_CACHE *auth_cache,
238 key = smtp_sasl_auth_cache_make_key(
STR(iter->
host), session->sasl_username);
239 if ((entry =
dict_get(auth_cache->dict, key)) != 0)
240 if ((valid = smtp_sasl_auth_cache_valid_value(auth_cache, entry,
241 session->sasl_passwd)) == 0)
243 if (
dict_del(auth_cache->dict, key) != 0)
244 msg_warn(
"SASL auth failure map %s: entry not deleted: %s",
245 auth_cache->dict->name, key);
246 if (auth_cache->dict->error)
247 msg_warn(
"SASL auth failure map %s: lookup failed for %s",
248 auth_cache->dict->name, key);
255 void smtp_sasl_auth_cache_store(SMTP_SASL_AUTH_CACHE *auth_cache,
263 key = smtp_sasl_auth_cache_make_key(
STR(iter->
host), session->sasl_username);
264 value = smtp_sasl_auth_cache_make_value(session->sasl_passwd,
266 dict_put(auth_cache->dict, key, value);
size_t dsn_valid(const char *text)
char * mystrdup(const char *str)
#define dict_put(dp, key, val)
NORETURN msg_panic(const char *fmt,...)
void * myrealloc(void *ptr, ssize_t len)
DICT * dict_open(const char *, int, int)
#define dict_get(dp, key)
void msg_warn(const char *fmt,...)
VSTRING * vstring_alloc(ssize_t len)
VSTRING * vstring_sprintf(VSTRING *vp, const char *format,...)
NORETURN msg_fatal(const char *fmt,...)
VSTRING * base64_encode(VSTRING *, const char *, ssize_t)
#define dict_del(dp, key)
char * vstring_export(VSTRING *vp)
void * mymalloc(ssize_t len)