File: plugin-cvm-validate.c

package info (click to toggle)
mailfront 2.12-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,072 kB
  • sloc: sh: 5,549; ansic: 5,083; makefile: 35
file content (80 lines) | stat: -rw-r--r-- 2,466 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdlib.h>
#include <string.h>
#include "mailfront.h"
#include <cvm/v2client.h>
#include <cvm/credentials.h>

static const char* lookup_secret;
static const char* cvm_lookup;
static int cred_count;

static RESPONSE(norcpt,553,"5.1.1 Sorry, that recipient does not exist.");
static RESPONSE(failed,451,"4.1.0 Sorry, I could not verify that recipient (internal temporary error).");

static const response* validate_init(void)
{
  if ((cvm_lookup = getenv("CVM_LOOKUP")) != 0) {

    if ((lookup_secret = getenv("CVM_LOOKUP_SECRET")) == 0)
      lookup_secret = getenv("LOOKUP_SECRET");

    /* Invoking CVMs in cvm-command mode without $CVM_LOOKUP_SECRET set
     * will fail, since the CVM will be expecting additional credentials
     * to validate.  To prevent this failure, set $CVM_LOOKUP_SECRET to
     * an empty string. */
    if (lookup_secret == 0) {
      if (putenv("CVM_LOOKUP_SECRET=") != 0)
	return &resp_oom;
      /* Also set the lookup secret to an empty string internally to
       * avoid NULL pointer issues later. */
      lookup_secret = "";
    }

    /* Match the behavior of the current CVM code base: If
     * $CVM_LOOKUP_SECRET is set to an empty string, treat it as if no
     * lookup secret is required. */
    cred_count = (*lookup_secret == 0) ? 2 : 3;
  }
  return 0;
}

static const response* validate_recipient(str* recipient, str* params)
{
  struct cvm_credential creds[3];
  unsigned i;
  unsigned long u;
  const response* r = &resp_failed;

  if (cvm_lookup == 0) return 0;
  if ((i = str_findlast(recipient, '@')) == (unsigned)-1)
    return 0;
  memset(creds, 0, sizeof creds);
  creds[0].type = CVM_CRED_ACCOUNT;
  creds[1].type = CVM_CRED_DOMAIN;
  creds[2].type = CVM_CRED_SECRET;
  if (str_copyb(&creds[0].value, recipient->s, i)
      && str_copyb(&creds[1].value, recipient->s+i+1, recipient->len-i-1)
      && str_copys(&creds[2].value, lookup_secret)) {
    switch (cvm_authenticate(cvm_lookup, cred_count, creds)) {
    case 0: r = 0; break;
    case CVME_PERMFAIL:
      /* Return a "pass" result if the CVM declared the address to be
       * out of scope. */
      r = (cvm_client_fact_uint(CVM_FACT_OUTOFSCOPE, &u) == 0
	   && u == 1)
	? 0
	: &resp_norcpt;
    }
  }
  str_free(&creds[0].value);
  str_free(&creds[1].value);
  str_free(&creds[2].value);
  return r;
  (void)params;
}

struct plugin plugin = {
  .version = PLUGIN_VERSION,
  .init = validate_init,
  .recipient = validate_recipient,
};