/*
* Copyright (c) 2004 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: nameok.c,v 1.5 2006/12/27 23:41:09 ca Exp $")
#include "sm/types.h"
#include "sm/error.h"
#include "sm/mta.h" /* MAXDOMAINLEN */
#include "nameok.h"
#define PERIOD 0x2e
#define ishyphenchar(c) ((c) == 0x2d)
#define isunderscorechar(c) ((c) == 0x5f)
#define isbslashchar(c) ((c) == 0x5c)
#define isperiodchar(c) ((c) == PERIOD)
#define isasterchar(c) ((c) == 0x2a)
#define ISALPHACHAR(c) (((c) >= 0x41 && (c) <= 0x5a) \
|| ((c) >= 0x61 && (c) <= 0x7a))
#define ISDIGITCHAR(c) ((c) >= 0x30 && (c) <= 0x39)
#define ISBORDERCHAR(c) (ISALPHACHAR(c) || ISDIGITCHAR(c))
#define ISMIDDLECHAR(c) (ISBORDERCHAR(c) || hyphenchar(c))
#define ISDOMAINCHAR(c) ((c) > 0x20 && (c) < 0x7f)
/*
** VALIDDNSDOMAIN -- check whether a dns domain is syntactically valid
**
** Parameters:
** dn -- domain
** flags -- flags
**
** Returns:
** true iff domain is syntactically valid
*/
bool
validdnsdomain(const uchar *dn, uint flags)
{
uchar ch, pch;
uint tl, ll, lp;
if (dn == NULL || *dn == '\0')
return false;
pch = ch = '\0';
tl = 0;
/*
** Grammar:
** domain ::= label ['.' domain ] ['.']
** label ::= alnum [ ['-'] alnum ]*
** Note: this grammar doesn't allow adjacent '-'.
** That's ok for RFC 2821 addresses but RFC 952 allows it.
*/
if (SM_IS_FLAG(flags, DNS_DOT) && '.' == *dn && '\0' == *(dn + 1))
return true;
#define MaxLL 64 /* Maximum label length */
do {
ll = 0;
do {
lp = 0;
pch = ch;
ch = *dn++;
while (ISBORDERCHAR(ch)
|| (SM_IS_FLAG(flags, DNS__OK) && isunderscorechar(ch))
|| (SM_IS_FLAG(flags, DNS_HYPHENS) && ishyphenchar(ch) && lp > 0
)
)
{
pch = ch;
ch = *dn++;
++tl;
++ll;
++lp;
}
} while (ishyphenchar(ch) && lp > 0 && ll <= MaxLL);
/* last character must not be '-' */
if (SM_IS_FLAG(flags, DNS_HYPHENS) && ishyphenchar(pch))
return false;
/* allow trailing dot */
if (lp == 0 && isperiodchar(pch) && ch == '\0')
return true;
if (lp == 0 || ll > MaxLL || ll == 0)
return false;
} while (isperiodchar(ch) && ll > 0 && ll <= MaxLL);
if (tl > MAXDOMAINLEN)
return false;
return ('\0' == ch);
}
#if 0
BIND 9.x code; slightly modified:
int ch, pch, nch;
pch = '\0';
ch = *dn++;
while (ch != '\0')
{
nch = *dn++;
if (isperiodchar(ch))
{
if (!isborderchar(pch))
return false;
}
else if (isperiodchar(pch))
{
if (!isborderchar(ch))
return false;
}
else if (isperiodchar(nch) || nch == '\0')
{
if (!isborderchar(ch))
return false;
}
else
{
if (!ismiddlechar(ch))
return false;
}
ppch = pch, pch = ch, ch = nch;
}
return true;
}
#endif /* 0 */
syntax highlighted by Code2HTML, v. 0.9.1