~ubuntu-branches/ubuntu/vivid/postfix/vivid-proposed

« back to all changes in this revision

Viewing changes to src/global/valid_mailhost_addr.c

Tags: upstream-2.2.6
ImportĀ upstreamĀ versionĀ 2.2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*++
 
2
/* NAME
 
3
/*      valid_mailhost_addr 3
 
4
/* SUMMARY
 
5
/*      mailhost address syntax validation
 
6
/* SYNOPSIS
 
7
/*      #include <valid_mailhost_addr.h>
 
8
/*
 
9
/*      const char *valid_mailhost_addr(name, gripe)
 
10
/*      const char *name;
 
11
/*      int     gripe;
 
12
/*
 
13
/*      int     valid_mailhost_literal(addr, gripe)
 
14
/*      const char *addr;
 
15
/*      int     gripe;
 
16
/* DESCRIPTION
 
17
/*      valid_mailhost_addr() requires that the input is a valid
 
18
/*      RFC 2821 string representation of an IPv4 or IPv6 network
 
19
/*      address.  A valid IPv4 address is in dotted quad decimal
 
20
/*      form.  A valid IPv6 address includes the "IPV6:" prefix as
 
21
/*      required by RFC 2821, and is in valid hexadecimal form or
 
22
/*      in valid IPv4-in-IPv6 form.  The result value is the bare
 
23
/*      address in the input argument (i.e. text after "IPV6:"
 
24
/*      prefix, if any) in case of success, a null pointer in case
 
25
/*      of failure.
 
26
/*
 
27
/*      valid_mailhost_literal() requires an address enclosed in
 
28
/*      [].  The result is non-zero in case of success, zero in
 
29
/*      case of failure.
 
30
/*
 
31
/*      These routines operate silently unless the gripe parameter
 
32
/*      specifies a non-zero value. The macros DO_GRIPE and DONT_GRIPE
 
33
/*      provide suitable constants.
 
34
/*
 
35
/*      The IPV6_COL macro defines the "IPv6:" prefix.
 
36
/* DIAGNOSTICS
 
37
/*      Warnings are logged with msg_warn().
 
38
/* SEE ALSO
 
39
/*      valid_hostname(3)
 
40
/*      RFC 952, RFC 1123, RFC 1035, RFC 2821
 
41
/* LICENSE
 
42
/* .ad
 
43
/* .fi
 
44
/*      The Secure Mailer license must be distributed with this software.
 
45
/* AUTHOR(S)
 
46
/*      Wietse Venema
 
47
/*      IBM T.J. Watson Research
 
48
/*      P.O. Box 704
 
49
/*      Yorktown Heights, NY 10598, USA
 
50
/*--*/
 
51
 
 
52
 
 
53
/* System library. */
 
54
 
 
55
#include <sys_defs.h>
 
56
#include <string.h>
 
57
 
 
58
#ifdef STRCASECMP_IN_STRINGS_H
 
59
#include <strings.h>
 
60
#endif
 
61
 
 
62
/* Utility library. */
 
63
 
 
64
#include <msg.h>
 
65
#include <myaddrinfo.h>
 
66
 
 
67
/* Global library. */
 
68
 
 
69
#include <valid_mailhost_addr.h>
 
70
 
 
71
/* Application-specific. */
 
72
 
 
73
#define IPV6_COL_LEN       (sizeof(IPV6_COL) - 1)
 
74
#define HAS_IPV6_COL(str)  (strncasecmp((str), IPV6_COL, IPV6_COL_LEN) == 0)
 
75
#define SKIP_IPV6_COL(str) (HAS_IPV6_COL(str) ? (str) + IPV6_COL_LEN : (str))
 
76
 
 
77
/* valid_mailhost_addr - validate RFC 2821 numerical address form */
 
78
 
 
79
const char *valid_mailhost_addr(const char *addr, int gripe)
 
80
{
 
81
    const char *bare_addr;
 
82
 
 
83
    bare_addr = SKIP_IPV6_COL(addr);
 
84
    return ((bare_addr != addr ? valid_ipv6_hostaddr : valid_ipv4_hostaddr)
 
85
            (bare_addr, gripe) ? bare_addr : 0);
 
86
}
 
87
 
 
88
/* valid_mailhost_literal - validate [RFC 2821 numerical address] form */
 
89
 
 
90
int     valid_mailhost_literal(const char *addr, int gripe)
 
91
{
 
92
    const char *myname = "valid_mailhost_literal";
 
93
    MAI_HOSTADDR_STR hostaddr;
 
94
    const char *last;
 
95
    size_t address_bytes;
 
96
 
 
97
    if (*addr != '[') {
 
98
        if (gripe)
 
99
            msg_warn("%s: '[' expected at start: %.100s", myname, addr);
 
100
        return (0);
 
101
    }
 
102
    if ((last = strchr(addr, ']')) == 0) {
 
103
        if (gripe)
 
104
            msg_warn("%s: ']' expected at end: %.100s", myname, addr);
 
105
        return (0);
 
106
    }
 
107
    if (last[1]) {
 
108
        if (gripe)
 
109
            msg_warn("%s: unexpected text after ']': %.100s", myname, addr);
 
110
        return (0);
 
111
    }
 
112
    if ((address_bytes = last - addr - 1) >= sizeof(hostaddr.buf)) {
 
113
        if (gripe)
 
114
            msg_warn("%s: too much text: %.100s", myname, addr);
 
115
        return (0);
 
116
    }
 
117
    strncpy(hostaddr.buf, addr + 1, address_bytes);
 
118
    hostaddr.buf[address_bytes] = 0;
 
119
    return (valid_mailhost_addr(hostaddr.buf, gripe) != 0);
 
120
}
 
121
 
 
122
#ifdef TEST
 
123
 
 
124
 /*
 
125
  * Test program - reads hostnames from stdin, reports invalid hostnames to
 
126
  * stderr.
 
127
  */
 
128
#include <stdlib.h>
 
129
 
 
130
#include <vstring.h>
 
131
#include <vstream.h>
 
132
#include <vstring_vstream.h>
 
133
#include <msg_vstream.h>
 
134
 
 
135
int     main(int unused_argc, char **argv)
 
136
{
 
137
    VSTRING *buffer = vstring_alloc(1);
 
138
 
 
139
    msg_vstream_init(argv[0], VSTREAM_ERR);
 
140
    msg_verbose = 1;
 
141
 
 
142
    while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
 
143
        msg_info("testing: \"%s\"", vstring_str(buffer));
 
144
        if (vstring_str(buffer)[0] == '[')
 
145
            valid_mailhost_literal(vstring_str(buffer), DO_GRIPE);
 
146
        else
 
147
            valid_mailhost_addr(vstring_str(buffer), DO_GRIPE);
 
148
    }
 
149
    exit(0);
 
150
}
 
151
 
 
152
#endif