const char *value;
};
-static
-int auth_policy_attribute_comparator(const struct policy_template_keyvalue *a,
- const struct policy_template_keyvalue *b)
+static int
+auth_policy_attribute_comparator(const struct policy_template_keyvalue *a,
+ const struct policy_template_keyvalue *b)
{
return strcmp(a->key, b->key);
}
-static
-int auth_policy_strptrcmp(const char *a0, const char *a1,
- const char *b0, const char *b1)
+static int
+auth_policy_strptrcmp(const char *a0, const char *a1,
+ const char *b0, const char *b1)
{
i_assert(a0 <= a1 && b0 <= b1);
return memcmp(a0, b0, I_MIN((a1-a0),(b1-b0)));
}
-static
-void auth_policy_open_key(const char *key, string_t *template)
+static void auth_policy_open_key(const char *key, string_t *template)
{
const char *ptr;
+
while((ptr = strchr(key, '/')) != NULL) {
str_append_c(template,'"');
json_append_escaped(template, t_strndup(key, (ptr-key)));
}
}
-static
-void auth_policy_close_key(const char *key, string_t *template)
+static void auth_policy_close_key(const char *key, string_t *template)
{
- while((key = strchr(key, '/')) != NULL) { str_append_c(template,'}'); key++; }
+ while ((key = strchr(key, '/')) != NULL) {
+ str_append_c(template,'}');
+ key++;
+ }
}
-static
-void auth_policy_open_and_close_to_key(const char *fromkey, const char *tokey, string_t *template)
+static void
+auth_policy_open_and_close_to_key(const char *fromkey, const char *tokey,
+ string_t *template)
{
const char *fptr,*tptr,*fdash,*tdash;
struct ssl_iostream_settings ssl_set;
i_zero(&ssl_set);
- http_client_set.request_absolute_timeout_msecs = global_auth_settings->policy_server_timeout_msecs;
+ http_client_set.request_absolute_timeout_msecs =
+ global_auth_settings->policy_server_timeout_msecs;
if (global_auth_settings->debug)
http_client_set.debug = 1;
- master_service_ssl_client_settings_to_iostream_set(master_ssl_set,
- pool_datastack_create(), &ssl_set);
+ master_service_ssl_client_settings_to_iostream_set(
+ master_ssl_set, pool_datastack_create(), &ssl_set);
http_client_set.ssl = &ssl_set;
http_client_set.event_parent = auth_event;
http_client = http_client_init(&http_client_set);
string_t *template = t_str_new(64);
const char **ptr;
const char *key = NULL;
- const char **list = t_strsplit_spaces(global_auth_settings->policy_request_attributes, "= ");
+ const char **list = t_strsplit_spaces(
+ global_auth_settings->policy_request_attributes, "= ");
t_array_init(&attribute_pairs, 8);
- for(ptr = list; *ptr != NULL; ptr++) {
+ for (ptr = list; *ptr != NULL; ptr++) {
struct policy_template_keyvalue pair;
+
if (key == NULL) {
key = *ptr;
} else {
array_push_back(&attribute_pairs, &pair);
}
}
- if (key != NULL) {
+ if (key != NULL)
i_fatal("auth_policy_request_attributes contains invalid value");
- }
/* then we sort it */
array_sort(&attribute_pairs, auth_policy_attribute_comparator);
array_foreach(&attribute_pairs, kvptr) {
const char *kptr = strchr(kvptr->key, '/');
+
auth_policy_open_and_close_to_key(prevkey, kvptr->key, template);
str_append_c(template,'"');
json_append_escaped(template, (kptr != NULL?kptr+1:kvptr->key));
str_truncate(template, str_len(template)-1);
auth_policy_json_template = i_strdup(str_c(template));
- if (global_auth_settings->policy_log_only)
+ if (global_auth_settings->policy_log_only) {
e_warning(auth_event,
"auth-policy: Currently in log-only mode. Ignoring "
"tarpit and disconnect instructions from policy server");
+ }
}
void auth_policy_deinit(void)
i_free(auth_policy_json_template);
}
-static
-void auth_policy_log_result(struct policy_lookup_ctx *context)
+static void auth_policy_log_result(struct policy_lookup_ctx *context)
{
const char *action;
struct event_passthrough *e = event_create_passthrough(context->event)->
action = "continue";
else
action = t_strdup_printf("tarpit %d second(s)", context->result);
- if (context->request->set->policy_log_only && result != 0)
+ if (context->request->set->policy_log_only && result != 0) {
e_info(e->event(), "Policy check action '%s' ignored",
action);
- else if (result != 0)
+ } else if (result != 0) {
e_info(e->event(), "Policy check action is %s",
action);
- else
+ } else {
e_debug(e->event(), "Policy check action is %s",
action);
+ }
}
-static
-void auth_policy_finish(struct policy_lookup_ctx *context)
+static void auth_policy_finish(struct policy_lookup_ctx *context)
{
if (context->parser != NULL) {
const char *error ATTR_UNUSED;
pool_unref(&context->pool);
}
-static
-void auth_policy_callback(struct policy_lookup_ctx *context)
+static void auth_policy_callback(struct policy_lookup_ctx *context)
{
if (context->callback != NULL)
context->callback(context->result, context->callback_context);
auth_policy_log_result(context);
}
-static
-void auth_policy_parse_response(struct policy_lookup_ctx *context)
+static void auth_policy_parse_response(struct policy_lookup_ctx *context)
{
enum json_type type;
const char *value;
else
continue;
} else if (context->parse_state == POLICY_RESULT_VALUE_STATUS) {
- if (type != JSON_TYPE_NUMBER || str_to_int(value, &context->result) != 0)
+ if (type != JSON_TYPE_NUMBER ||
+ str_to_int(value, &context->result) != 0)
break;
context->parse_state = POLICY_RESULT;
} else if (context->parse_state == POLICY_RESULT_VALUE_MESSAGE) {
"Policy server response was malformed");
} else {
const char *error = "unknown";
- if (json_parser_deinit(&context->parser, &error) != 0)
+ if (json_parser_deinit(&context->parser, &error) != 0) {
e_error(context->event,
- "Policy server response JSON parse error: %s", error);
- else if (context->parse_state == POLICY_RESULT)
+ "Policy server response JSON parse error: %s",
+ error);
+ } else if (context->parse_state == POLICY_RESULT) {
context->parse_error = FALSE;
+ }
}
if (context->parse_error) {
- context->result = (context->set->policy_reject_on_fail ? -1 : 0);
+ context->result = (context->set->policy_reject_on_fail ?
+ -1 : 0);
}
context->request->policy_refusal = FALSE;
e_debug(context->event,
"Policy response %d with message: %s",
context->result, context->message);
- auth_request_set_field(context->request, "reason", context->message, NULL);
+ auth_request_set_field(context->request, "reason",
+ context->message, NULL);
}
context->request->policy_refusal = TRUE;
} else {
}
if (context->request->policy_refusal) {
- e_info(context->event, "Authentication failure due to policy server refusal%s%s",
+ e_info(context->event,
+ "Authentication failure due to policy server refusal%s%s",
(context->message!=NULL?": ":""),
(context->message!=NULL?context->message:""));
}
i_stream_unref(&context->payload);
}
-static
-void auth_policy_process_response(const struct http_response *response,
- void *ctx)
+static void
+auth_policy_process_response(const struct http_response *response, void *ctx)
{
struct policy_lookup_ctx *context = ctx;
if (context->expect_result) {
i_stream_ref(response->payload);
- context->io = io_add_istream(response->payload, auth_policy_parse_response, context);
+ context->io = io_add_istream(
+ response->payload, auth_policy_parse_response, context);
context->parser = json_parser_init(response->payload);
auth_policy_parse_response(ctx);
} else {
}
}
-static
-void auth_policy_send_request(struct policy_lookup_ctx *context)
+static void auth_policy_send_request(struct policy_lookup_ctx *context)
{
const char *error;
struct http_url *url;
auth_policy_finish(context);
return;
}
+
context->http_request = http_client_request_url(http_client,
"POST", url, auth_policy_process_response, (void*)context);
- http_client_request_set_destroy_callback(context->http_request, auth_policy_finish, context);
- http_client_request_add_header(context->http_request, "Content-Type", "application/json");
+ http_client_request_set_destroy_callback(
+ context->http_request, auth_policy_finish, context);
+ http_client_request_add_header(context->http_request,
+ "Content-Type", "application/json");
if (*context->set->policy_server_api_header != 0) {
const char *ptr;
- if ((ptr = strstr(context->set->policy_server_api_header, ":")) != NULL) {
- const char *header = t_strcut(context->set->policy_server_api_header, ':');
- http_client_request_add_header(context->http_request, header, ptr + 1);
- } else {
+
+ ptr = strstr(context->set->policy_server_api_header, ":");
+ if (ptr != NULL) {
+ const char *header = t_strcut(
+ context->set->policy_server_api_header, ':');
http_client_request_add_header(context->http_request,
- "X-API-Key", context->set->policy_server_api_header);
+ header, ptr + 1);
+ } else {
+ http_client_request_add_header(
+ context->http_request, "X-API-Key",
+ context->set->policy_server_api_header);
}
}
if (url->user != NULL) {
/* allow empty password */
- http_client_request_set_auth_simple(context->http_request, url->user,
+ http_client_request_set_auth_simple(
+ context->http_request, url->user,
(url->password != NULL ? url->password : ""));
}
+
struct istream *is = i_stream_create_from_buffer(context->json);
http_client_request_set_payload(context->http_request, is, FALSE);
i_stream_unref(&is);
http_client_request_submit(context->http_request);
}
-static
-const char *auth_policy_escape_function(const char *string,
- const struct auth_request *auth_request ATTR_UNUSED)
+static const char *
+auth_policy_escape_function(const char *string,
+ const struct auth_request *auth_request ATTR_UNUSED)
{
string_t *tmp = t_str_new(64);
json_append_escaped(tmp, string);
i_unreached();
}
-
-static
-const struct var_expand_table *policy_get_var_expand_table(struct auth_request *auth_request,
- const char *hashed_password, const char *requested_username)
+static const struct var_expand_table *
+policy_get_var_expand_table(struct auth_request *auth_request,
+ const char *hashed_password,
+ const char *requested_username)
{
struct var_expand_table *table;
unsigned int count = 3;
- table = auth_request_get_var_expand_table_full(auth_request,
- auth_request->fields.user, auth_policy_escape_function, &count);
+ table = auth_request_get_var_expand_table_full(
+ auth_request, auth_request->fields.user,
+ auth_policy_escape_function, &count);
table[0].key = '\0';
table[0].long_key = "hashed_password";
table[0].value = hashed_password;
table[2].key = '\0';
table[2].long_key = "fail_type";
table[2].value = auth_policy_fail_type(auth_request);
- if (table[0].value != NULL)
- table[0].value = auth_policy_escape_function(table[0].value, auth_request);
- if (table[1].value != NULL)
- table[1].value = auth_policy_escape_function(table[1].value, auth_request);
+ if (table[0].value != NULL) {
+ table[0].value = auth_policy_escape_function(table[0].value,
+ auth_request);
+ }
+ if (table[1].value != NULL) {
+ table[1].value = auth_policy_escape_function(table[1].value,
+ auth_request);
+ }
return table;
}
-static
-void auth_policy_create_json(struct policy_lookup_ctx *context,
- const char *password, bool include_success)
+static void
+auth_policy_create_json(struct policy_lookup_ctx *context,
+ const char *password, bool include_success)
{
const struct var_expand_table *var_table;
context->json = str_new(context->pool, 64);
unsigned char *ptr;
const char *requested_username;
- const struct hash_method *digest = hash_method_lookup(context->set->policy_hash_mech);
+ const struct hash_method *digest =
+ hash_method_lookup(context->set->policy_hash_mech);
i_assert(digest != NULL);
buffer_t *buffer = t_buffer_create(64);
digest->init(ctx);
- digest->loop(ctx,
- context->set->policy_hash_nonce,
- strlen(context->set->policy_hash_nonce));
- if (context->request->fields.requested_login_user != NULL)
- requested_username = context->request->fields.requested_login_user;
- else if (context->request->fields.user != NULL)
+ digest->loop(ctx, context->set->policy_hash_nonce,
+ strlen(context->set->policy_hash_nonce));
+ if (context->request->fields.requested_login_user != NULL) {
+ requested_username =
+ context->request->fields.requested_login_user;
+ } else if (context->request->fields.user != NULL) {
requested_username = context->request->fields.user;
- else
+ } else {
requested_username = "";
+ }
+
/* use +1 to make sure \0 gets included */
digest->loop(ctx, requested_username, strlen(requested_username)+1);
if (password != NULL)
digest->result(ctx, ptr);
buffer_set_used_size(buffer, digest->digest_size);
if (context->set->policy_hash_truncate > 0) {
- buffer_truncate_rshift_bits(buffer, context->set->policy_hash_truncate);
+ buffer_truncate_rshift_bits(
+ buffer, context->set->policy_hash_truncate);
}
+
const char *hashed_password = binary_to_hex(buffer->data, buffer->used);
- str_append_c(context->json, '{');
- var_table = policy_get_var_expand_table(context->request, hashed_password, requested_username);
const char *error;
- if (auth_request_var_expand_with_table(context->json, auth_policy_json_template,
+ str_append_c(context->json, '{');
+ var_table = policy_get_var_expand_table(
+ context->request, hashed_password, requested_username);
+ if (auth_request_var_expand_with_table(context->json,
+ auth_policy_json_template,
context->request, var_table,
- auth_policy_escape_function, &error) <= 0) {
+ auth_policy_escape_function,
+ &error) <= 0) {
e_error(context->event,
"Failed to expand auth policy template: %s", error);
}
else
str_append(context->json, "false");
str_append(context->json, ",\"policy_reject\":");
- str_append(context->json, context->request->policy_refusal ? "true" : "false");
+ str_append(context->json,
+ (context->request->policy_refusal ?
+ "true" : "false"));
}
str_append(context->json, ",\"tls\":");
if (context->request->fields.conn_secured == AUTH_REQUEST_CONN_SECURED_TLS)
"Policy server request JSON: %s", str_c(context->json));
}
-static
-void auth_policy_url(struct policy_lookup_ctx *context, const char *command)
+static void auth_policy_url(struct policy_lookup_ctx *context,
+ const char *command)
{
size_t len = strlen(context->set->policy_server_url);
- if (context->set->policy_server_url[len-1] == '&')
- context->url = p_strdup_printf(context->pool, "%scommand=%s",
+ if (context->set->policy_server_url[len-1] == '&') {
+ context->url = p_strdup_printf(
+ context->pool, "%scommand=%s",
context->set->policy_server_url, command);
- else
- context->url = p_strdup_printf(context->pool, "%s?command=%s",
+ } else {
+ context->url = p_strdup_printf(
+ context->pool, "%s?command=%s",
context->set->policy_server_url, command);
+ }
}
static const char *auth_policy_get_prefix(struct auth_request *request)
void auth_policy_check(struct auth_request *request, const char *password,
auth_policy_callback_t cb, void *context)
{
- if (request->master != NULL || *(request->set->policy_server_url) == '\0') {
+ if (request->master != NULL ||
+ *(request->set->policy_server_url) == '\0') {
cb(0, context);
return;
}
+
pool_t pool = pool_alloconly_create("auth policy", 512);
- struct policy_lookup_ctx *ctx = p_new(pool, struct policy_lookup_ctx, 1);
+ struct policy_lookup_ctx *ctx =
+ p_new(pool, struct policy_lookup_ctx, 1);
+
ctx->pool = pool;
ctx->request = request;
ctx->expect_result = TRUE;
ctx->set = request->set;
ctx->event = event_create(request->event);
event_add_str(ctx->event, "mode", "allow");
- event_set_append_log_prefix(ctx->event, auth_policy_get_prefix(request));
+ event_set_append_log_prefix(ctx->event,
+ auth_policy_get_prefix(request));
auth_policy_url(ctx, "allow");
ctx->result = (ctx->set->policy_reject_on_fail ? -1 : 0);
e_debug(ctx->event, "Policy request %s", ctx->url);
if (*(request->set->policy_server_url) == '\0')
return;
+
pool_t pool = pool_alloconly_create("auth policy", 512);
- struct policy_lookup_ctx *ctx = p_new(pool, struct policy_lookup_ctx, 1);
+ struct policy_lookup_ctx *ctx =
+ p_new(pool, struct policy_lookup_ctx, 1);
+
ctx->pool = pool;
ctx->request = request;
ctx->expect_result = FALSE;
ctx->set = request->set;
ctx->event = event_create(request->event);
event_add_str(ctx->event, "mode", "report");
- event_set_append_log_prefix(ctx->event, auth_policy_get_prefix(request));
+ event_set_append_log_prefix(ctx->event,
+ auth_policy_get_prefix(request));
auth_policy_url(ctx, "report");
e_debug(ctx->event, "Policy request %s", ctx->url);
T_BEGIN {