/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "md5.h"
#include "hash.h"
#include "hex-binary.h"
#include "base64.h"
#include "hostpid.h"
#include "hmac.h"
#include "pkcs5.h"
#include "hash-method.h"
#include "str.h"
#include "strescape.h"
#include "var-expand.h"
#include "var-expand-private.h"
#include <unistd.h>
#include <ctype.h>
#define TABLE_LAST(t) \
struct var_expand_modifier {
char key;
};
static const char *
{
return t_str_lcase(str);
}
static const char *
{
return t_str_ucase(str);
}
static const char *
{
return str_escape(str);
}
static const char *
{
unsigned long long l;
if (str_to_ullong(str, &l) < 0)
l = 0;
return t_strdup_printf("%llx", l);
}
static const char *
{
char *p, *rev;
*p-- = *str;
return rev;
}
{
}
}
static const char *
{
unsigned int i;
for (i = 0; i < sizeof(value); i++) {
value <<= 8;
}
}
}
static const char *
{
}
static const char *
{
while (*str != '\0') {
if (*str == '.')
else
str++;
}
return str_free_without_data(&ret);
}
static const char *
{
len--;
}
{ 'L', m_str_lcase },
{ 'U', m_str_ucase },
{ 'E', m_str_escape },
{ 'X', m_str_hex },
{ 'R', m_str_reverse },
{ 'H', m_str_hash },
{ 'N', m_str_newhash },
{ 'M', m_str_md5 },
{ 'D', m_str_ldap_dn },
{ 'T', m_str_trim },
{ '\0', NULL }
};
static int
{
const struct var_expand_table *t;
for (t = table; !TABLE_LAST(t); t++) {
return 1;
}
}
}
/* not found */
if (key == '%') {
*var_r = "%";
return 1;
}
return 0;
}
static int
{
enum {
const char *value;
int ret;
if (p != NULL) {
}
return 0;
}
return ret;
}
/* default values */
unsigned int truncbits = 0;
rounds = 2048;
}
args++;
continue;
} else {
value++;
}
if (strcmp(k, "rounds") == 0) {
"Cannot parse hash arguments:"
"'%s' is not number for rounds",
value);
return -1;
}
if (rounds < 1) {
"Cannot parse hash arguments:"
"rounds must be at least 1");
return -1;
}
} else if (strcmp(k, "truncate") == 0) {
"Cannot parse hash arguments:"
"'%s' is not number for truncbits",
value);
return -1;
}
} else if (strcmp(k, "salt") == 0) {
str_truncate(salt, 0);
error_r) < 0) {
return -1;
}
break;
} else if (strcmp(k, "format") == 0) {
format = FORMAT_HEX;
} else {
"Cannot parse hash arguments:"
"'%s' is not supported format",
value);
return -1;
}
}
args++;
}
str_truncate(tmp, 0);
*error_r = "Cannot hash: PKCS5_PBKDF2 failed";
return -1;
}
} else {
unsigned char *digest =
}
}
if (truncbits > 0)
switch(format) {
case FORMAT_HEX:
return 1;
case FORMAT_HEX_UC:
return 1;
case FORMAT_BASE64: {
return 1;
}
}
i_unreached();
}
static int
{
int ret;
return 1;
}
if (func_table != NULL) {
return ret;
}
}
}
return 0;
}
static int
{
int ret;
/* try with extensions */
const struct var_expand_extension_func_table *f;
/* ensure we won't match abbreviations */
}
}
return ret;
}
int
{
const struct var_expand_table *t;
return 1;
}
}
}
/* built-in variables: */
switch (key_len) {
case 3:
break;
case 8:
value = my_hostname;
break;
}
else
data = "";
value = "";
}
}
return ret;
}
const struct var_expand_table *table,
const struct var_expand_func_table *func_table,
{
const struct var_expand_modifier *m;
const char *var;
const char *(*modifier[MAX_MODIFIER_COUNT])
(const char *, struct var_expand_context *);
const char *end;
unsigned int i, modifier_count;
if (*str != '%')
else {
str++;
/* reset per-field modifiers */
/* [<offset>.]<width>[<modifiers>]<variable> */
if (*str == '-') {
sign = -1;
str++;
}
if (*str == '0') {
str++;
}
str++;
}
if (*str == '.') {
sign = 1;
str++;
/* if offset was prefixed with zero (or it was
plain zero), just ignore that. zero padding
is done with the width. */
if (*str == '0') {
str++;
}
if (*str == '-') {
sign = -1;
str++;
}
str++;
}
}
modifier_count = 0;
while (modifier_count < MAX_MODIFIER_COUNT) {
/* @UNSAFE */
m->func;
str++;
break;
}
}
break;
}
if (*str == '\0')
break;
/* %{long_key} */
continue;
}
if (escape) {
continue;
}
}
if (ctr == 0)
/* it needs to come back a bit */
end--;
/* if there is no } it will consume rest of the
string */
} else {
}
for (i = 0; i < modifier_count; i++)
/* if offset is < 0 then we want to
start at the end */
} else {
var++;
}
}
else if (!ctx.zero_padding) {
} else {
/* %05d -like padding. no truncation. */
}
}
}
}
}
return final_ret;
}
{
}
static bool
unsigned int *size_r)
{
const struct var_expand_modifier *m;
unsigned int i = 0;
/* [<offset>.]<width>[<modifiers>]<variable> */
i++;
if (str[i] == '.') {
i++;
i++;
}
do {
i++;
break;
}
}
} while (m->key != '\0');
if (str[i] != '{') {
/* short key */
*idx_r = i;
return FALSE;
} else {
/* long key */
*idx_r = ++i;
for (; str[i] != '\0'; i++) {
continue;
}
if (escape) {
continue;
}
if (str[i] == '{')
depth++;
if (str[i] == '}') {
if (--depth==0)
break;
}
}
return TRUE;
}
}
{
return '{';
}
unsigned int *size_r)
{
}
{
return FALSE;
return TRUE;
return FALSE;
}
{
char c;
str++;
c = var_get_key(str);
return TRUE;
return TRUE;
}
}
}
return FALSE;
}
void var_expand_extensions_deinit(void)
{
}
void var_expand_extensions_init(void)
{
/* put all hash methods there */
meth++) {
}
/* pkcs5 */
/* if */
}
void
{
ptr++) {
}
}
void
{
ptr++) {
for(unsigned int i = 0; i < array_count(&var_expand_extensions); i++) {
}
}
}
}
struct var_expand_table *
const struct var_expand_table *b)
{
}
}
return array_idx_modifiable(&table, 0);
}