#include "lib.h"
#include "buffer.h"
#include "str.h"
#include "hex-binary.h"
#include "urlauth-plugin.h"
#include <openssl/hmac.h>
#define URLAUTH_URLAUTH_INTERNAL_VERSION "d1"
void urlauth_urlauth_generate_internal(const char *rump,
const buffer_t *key,
string_t *urlauth)
{
const void *key_data;
size_t key_len = 0;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int mac_len = 0;
key_data = buffer_get_data(key, &key_len);
i_assert(key_len > 0);
HMAC(EVP_sha1(), key_data, key_len, (const unsigned char *) rump,
strlen(rump), mac, &mac_len);
str_append(urlauth, URLAUTH_URLAUTH_INTERNAL_VERSION);
str_append(urlauth, binary_to_hex(mac, mac_len));
}
bool urlauth_url_validate(const struct imap_url_parts *parts, bool full,
const char **error)
{
if (parts->user == NULL ||
!imap_url_astring_validate(parts->user)) {
*error = "missing or invalid user ID";
return FALSE;
}
if (parts->auth_type != NULL &&
!imap_url_atom_validate(parts->auth_type)) {
*error = "invalid auth type";
return FALSE;
}
if (parts->hostport == NULL ||
!imap_url_hostport_validate(parts->hostport)) {
*error = "missing or invalid server";
return FALSE;
}
if (parts->mailbox == NULL ||
!imap_url_mailbox_validate(parts->mailbox)) {
*error = "missing or invalid mailbox";
return FALSE;
}
if (parts->uidvalidity != NULL &&
!imap_url_nz_number_validate(parts->uidvalidity)) {
*error = "invalid uidvalidity";
return FALSE;
}
if (parts->uid == NULL ||
!imap_url_nz_number_validate(parts->uid)) {
*error = "missing or invalid uid";
return FALSE;
}
if (parts->section != NULL &&
!imap_url_section_validate(parts->section)) {
*error = "invalid section";
return FALSE;
}
if (parts->expiration != NULL &&
(!imap_url_datetime_validate(parts->expiration) ||
parts->expiration_time == 0)) {
*error = "invalid expiration";
return FALSE;
}
if (parts->access == NULL ||
!imap_url_access_validate(parts->access)) {
*error = "missing or invalid access ID";
return FALSE;
}
if (full) {
if (parts->mechanism == NULL ||
!imap_url_mechanism_validate(parts->mechanism)) {
*error = "missing or invalid mechanism";
return FALSE;
}
if (parts->urlauth == NULL ||
!imap_url_urlauth_validate(parts->urlauth)) {
*error = "missing or invalid access token";
return FALSE;
}
} else {
if (parts->mechanism != NULL) {
*error = "mechanism present";
return FALSE;
}
if (parts->urlauth != NULL) {
*error = "access token present";
return FALSE;
}
}
return TRUE;
}