mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-23 08:09:34 -05:00
Handle full syntax of Generalized Time and UTC Time.
No longer accept initial and trailing spaces in these syntaxes.
This commit is contained in:
parent
281627d81d
commit
2d48b5dc99
1 changed files with 185 additions and 134 deletions
|
|
@ -1996,172 +1996,189 @@ certificateExactNormalize(
|
||||||
#endif /* HAVE_TLS */
|
#endif /* HAVE_TLS */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SUPPORT_OBSOLETE_UTC_SYNTAX
|
||||||
|
/* slight optimization - does not need the start parameter */
|
||||||
|
#define check_time_syntax(v, start, p, f) (check_time_syntax)(v, p, f)
|
||||||
|
enum { start = 0 };
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_time_syntax (struct berval *val,
|
check_time_syntax (struct berval *val,
|
||||||
int start,
|
int start,
|
||||||
int *parts)
|
int *parts,
|
||||||
|
struct berval *fraction)
|
||||||
{
|
{
|
||||||
static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
|
/*
|
||||||
static int mdays[2][12] = {
|
* start=0 GeneralizedTime YYYYmmddHH[MM[SS]][(./,)d...](Z|(+/-)HH[MM])
|
||||||
|
* start=1 UTCTime YYmmddHHMM[SS][Z|(+/-)HHMM]
|
||||||
|
* GeneralizedTime supports leap seconds, UTCTime does not.
|
||||||
|
*/
|
||||||
|
static const int ceiling[9] = { 100, 100, 12, 31, 24, 60, 60, 24, 60 };
|
||||||
|
static const int mdays[2][12] = {
|
||||||
/* non-leap years */
|
/* non-leap years */
|
||||||
{ 30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 },
|
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||||
/* leap years */
|
/* leap years */
|
||||||
{ 30, 28, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30 }
|
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||||
};
|
};
|
||||||
char *p, *e;
|
char *p, *e;
|
||||||
int part, c, tzoffset, leapyear = 0 ;
|
int part, c, c1, c2, tzoffset, leapyear = 0;
|
||||||
|
|
||||||
if( val->bv_len == 0 ) {
|
p = val->bv_val;
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = (char *)val->bv_val;
|
|
||||||
e = p + val->bv_len;
|
e = p + val->bv_len;
|
||||||
|
|
||||||
/* Ignore initial whitespace */
|
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
|
||||||
while ( ( p < e ) && ASCII_SPACE( *p ) ) {
|
parts[0] = 20; /* century - any multiple of 4 from 04 to 96 */
|
||||||
p++;
|
#endif
|
||||||
}
|
for (part = start; part < 7 && p < e; part++) {
|
||||||
|
c1 = *p;
|
||||||
if (e - p < 13 - (2 * start)) {
|
if (!ASCII_DIGIT(c1)) {
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (part = 0; part < 9; part++) {
|
|
||||||
parts[part] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (part = start; part < 7; part++) {
|
|
||||||
c = *p;
|
|
||||||
if ((part == 6) && (c == 'Z' || c == '+' || c == '-')) {
|
|
||||||
part++;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
c -= '0';
|
|
||||||
if (p == e) {
|
if (p == e) {
|
||||||
return LDAP_INVALID_SYNTAX;
|
return LDAP_INVALID_SYNTAX;
|
||||||
}
|
}
|
||||||
if (c < 0 || c > 9) {
|
c = *p++;
|
||||||
|
if (!ASCII_DIGIT(c)) {
|
||||||
return LDAP_INVALID_SYNTAX;
|
return LDAP_INVALID_SYNTAX;
|
||||||
}
|
}
|
||||||
|
c += c1 * 10 - '0' * 11;
|
||||||
|
if ((part | 1) == 3) {
|
||||||
|
--c;
|
||||||
|
if (c < 0) {
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c >= ceiling[part]) {
|
||||||
|
if (! (c == 60 && part == 6 && start == 0))
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
parts[part] = c;
|
parts[part] = c;
|
||||||
|
}
|
||||||
c = *p++ - '0';
|
if (part < 5 + start) {
|
||||||
if (p == e) {
|
return LDAP_INVALID_SYNTAX;
|
||||||
return LDAP_INVALID_SYNTAX;
|
}
|
||||||
}
|
for (; part < 9; part++) {
|
||||||
if (c < 0 || c > 9) {
|
parts[part] = 0;
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
}
|
|
||||||
parts[part] *= 10;
|
|
||||||
parts[part] += c;
|
|
||||||
|
|
||||||
if (part == 2 || part == 3) {
|
|
||||||
parts[part]--;
|
|
||||||
}
|
|
||||||
if (parts[part] < 0) {
|
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
}
|
|
||||||
if (parts[part] > ceiling[part]) {
|
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* leapyear check for the Gregorian calendar (year>1581) */
|
/* leapyear check for the Gregorian calendar (year>1581) */
|
||||||
if (((parts[1] % 4 == 0) && (parts[1] != 0)) ||
|
if (parts[parts[1] == 0 ? 0 : 1] % 4 == 0)
|
||||||
((parts[0] % 4 == 0) && (parts[1] == 0)))
|
|
||||||
{
|
{
|
||||||
leapyear = 1;
|
leapyear = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts[3] > mdays[leapyear][parts[2]]) {
|
if (parts[3] >= mdays[leapyear][parts[2]]) {
|
||||||
return LDAP_INVALID_SYNTAX;
|
return LDAP_INVALID_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = *p++;
|
|
||||||
if (c == 'Z') {
|
|
||||||
tzoffset = 0; /* UTC */
|
|
||||||
} else if (c != '+' && c != '-') {
|
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
} else {
|
|
||||||
if (c == '-') {
|
|
||||||
tzoffset = -1;
|
|
||||||
} else /* c == '+' */ {
|
|
||||||
tzoffset = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p > e - 4) {
|
if (start == 0) {
|
||||||
|
fraction->bv_val = p;
|
||||||
|
fraction->bv_len = 0;
|
||||||
|
if (p < e && (*p == '.' || *p == ',')) {
|
||||||
|
char *end_num;
|
||||||
|
while (++p < e && ASCII_DIGIT(*p))
|
||||||
|
;
|
||||||
|
if (p - fraction->bv_val == 1) {
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
|
for (end_num = p; end_num[-1] == '0'; --end_num)
|
||||||
|
;
|
||||||
|
c = end_num - fraction->bv_val;
|
||||||
|
if (c != 1)
|
||||||
|
fraction->bv_len = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == e) {
|
||||||
|
/* no time zone */
|
||||||
|
return start == 0 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
tzoffset = *p++;
|
||||||
|
switch (tzoffset) {
|
||||||
|
default:
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
case 'Z':
|
||||||
|
/* UTC */
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
for (part = 7; part < 9 && p < e; part++) {
|
||||||
|
c1 = *p;
|
||||||
|
if (!ASCII_DIGIT(c1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
if (p == e) {
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
|
c2 = *p++;
|
||||||
|
if (!ASCII_DIGIT(c2)) {
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
|
parts[part] = c1 * 10 + c2 - '0' * 11;
|
||||||
|
if (parts[part] >= ceiling[part]) {
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (part < 8 + start) {
|
||||||
return LDAP_INVALID_SYNTAX;
|
return LDAP_INVALID_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (part = 7; part < 9; part++) {
|
if (tzoffset == '-') {
|
||||||
c = *p++ - '0';
|
/* negative offset to UTC, ie west of Greenwich */
|
||||||
if (c < 0 || c > 9) {
|
parts[4] += parts[7];
|
||||||
return LDAP_INVALID_SYNTAX;
|
parts[5] += parts[8];
|
||||||
|
/* offset is just hhmm, no seconds */
|
||||||
|
for (part = 6; --part >= 0; ) {
|
||||||
|
if (part != 3) {
|
||||||
|
c = ceiling[part];
|
||||||
|
} else {
|
||||||
|
c = mdays[leapyear][parts[2]];
|
||||||
|
}
|
||||||
|
if (parts[part] >= c) {
|
||||||
|
if (part == 0) {
|
||||||
|
return LDAP_INVALID_SYNTAX;
|
||||||
|
}
|
||||||
|
parts[part] -= c;
|
||||||
|
parts[part - 1]++;
|
||||||
|
continue;
|
||||||
|
} else if (part != 5) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parts[part] = c;
|
} else {
|
||||||
|
/* positive offset to UTC, ie east of Greenwich */
|
||||||
c = *p++ - '0';
|
parts[4] -= parts[7];
|
||||||
if (c < 0 || c > 9) {
|
parts[5] -= parts[8];
|
||||||
return LDAP_INVALID_SYNTAX;
|
for (part = 6; --part >= 0; ) {
|
||||||
}
|
if (parts[part] < 0) {
|
||||||
parts[part] *= 10;
|
if (part == 0) {
|
||||||
parts[part] += c;
|
return LDAP_INVALID_SYNTAX;
|
||||||
if (parts[part] < 0 || parts[part] > ceiling[part]) {
|
}
|
||||||
return LDAP_INVALID_SYNTAX;
|
if (part != 3) {
|
||||||
|
c = ceiling[part];
|
||||||
|
} else {
|
||||||
|
/* make first arg to % non-negative */
|
||||||
|
c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
|
||||||
|
}
|
||||||
|
parts[part] += c;
|
||||||
|
parts[part - 1]--;
|
||||||
|
continue;
|
||||||
|
} else if (part != 5) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore trailing whitespace */
|
return p != e ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
|
||||||
while ( ( p < e ) && ASCII_SPACE( *p ) ) {
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (p != e) {
|
|
||||||
return LDAP_INVALID_SYNTAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( tzoffset ) {
|
|
||||||
case -1: /* negativ offset to UTC, ie west of Greenwich */
|
|
||||||
parts[4] += parts[7];
|
|
||||||
parts[5] += parts[8];
|
|
||||||
for (part = 6; --part > 0; ) { /* offset is just hhmm, no seconds */
|
|
||||||
if (part != 3) {
|
|
||||||
c = ceiling[part];
|
|
||||||
} else {
|
|
||||||
c = mdays[leapyear][parts[2]];
|
|
||||||
}
|
|
||||||
if (parts[part] > c) {
|
|
||||||
parts[part] -= c + 1;
|
|
||||||
parts[part - 1]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: /* positive offset to UTC, ie east of Greenwich */
|
|
||||||
parts[4] -= parts[7];
|
|
||||||
parts[5] -= parts[8];
|
|
||||||
for (part = 6; --part > 0; ) {
|
|
||||||
if (part != 3) {
|
|
||||||
c = ceiling[part];
|
|
||||||
} else {
|
|
||||||
/* first arg to % needs to be non negativ */
|
|
||||||
c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
|
|
||||||
}
|
|
||||||
if (parts[part] < 0) {
|
|
||||||
parts[part] += c + 1;
|
|
||||||
parts[part - 1]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0: /* already UTC */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
|
#ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
|
||||||
|
|
||||||
|
#if 0
|
||||||
static int
|
static int
|
||||||
xutcTimeNormalize(
|
xutcTimeNormalize(
|
||||||
Syntax *syntax,
|
Syntax *syntax,
|
||||||
|
|
@ -2170,7 +2187,7 @@ xutcTimeNormalize(
|
||||||
{
|
{
|
||||||
int parts[9], rc;
|
int parts[9], rc;
|
||||||
|
|
||||||
rc = check_time_syntax(val, 1, parts);
|
rc = check_time_syntax(val, 1, parts, NULL);
|
||||||
if (rc != LDAP_SUCCESS) {
|
if (rc != LDAP_SUCCESS) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -2187,6 +2204,7 @@ xutcTimeNormalize(
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
utcTimeValidate(
|
utcTimeValidate(
|
||||||
|
|
@ -2194,9 +2212,10 @@ utcTimeValidate(
|
||||||
struct berval *in )
|
struct berval *in )
|
||||||
{
|
{
|
||||||
int parts[9];
|
int parts[9];
|
||||||
return check_time_syntax(in, 1, parts);
|
return check_time_syntax(in, 1, parts, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif /* SUPPORT_OBSOLETE_UTC_SYNTAX */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
generalizedTimeValidate(
|
generalizedTimeValidate(
|
||||||
|
|
@ -2204,7 +2223,8 @@ generalizedTimeValidate(
|
||||||
struct berval *in )
|
struct berval *in )
|
||||||
{
|
{
|
||||||
int parts[9];
|
int parts[9];
|
||||||
return check_time_syntax(in, 0, parts);
|
struct berval fraction;
|
||||||
|
return check_time_syntax(in, 0, parts, &fraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -2217,25 +2237,56 @@ generalizedTimeNormalize(
|
||||||
void *ctx )
|
void *ctx )
|
||||||
{
|
{
|
||||||
int parts[9], rc;
|
int parts[9], rc;
|
||||||
|
unsigned int len;
|
||||||
|
struct berval fraction;
|
||||||
|
|
||||||
rc = check_time_syntax(val, 0, parts);
|
rc = check_time_syntax(val, 0, parts, &fraction);
|
||||||
if (rc != LDAP_SUCCESS) {
|
if (rc != LDAP_SUCCESS) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
normalized->bv_val = sl_malloc( sizeof("YYYYmmddHHMMSSZ"), ctx );
|
len = sizeof("YYYYmmddHHMMSSZ")-1 + fraction.bv_len;
|
||||||
|
normalized->bv_val = sl_malloc( len + 1, ctx );
|
||||||
if ( normalized->bv_val == NULL ) {
|
if ( normalized->bv_val == NULL ) {
|
||||||
return LBER_ERROR_MEMORY;
|
return LBER_ERROR_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02dZ",
|
sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02d",
|
||||||
parts[0], parts[1], parts[2] + 1, parts[3] + 1,
|
parts[0], parts[1], parts[2] + 1, parts[3] + 1,
|
||||||
parts[4], parts[5], parts[6] );
|
parts[4], parts[5], parts[6] );
|
||||||
normalized->bv_len = 15;
|
if ( fraction.bv_len ) {
|
||||||
|
memcpy( normalized->bv_val + sizeof("YYYYmmddHHMMSSZ")-2,
|
||||||
|
fraction.bv_val, fraction.bv_len );
|
||||||
|
normalized->bv_val[sizeof("YYYYmmddHHMMSSZ")-2] = '.';
|
||||||
|
}
|
||||||
|
strcpy( normalized->bv_val + len-1, "Z" );
|
||||||
|
normalized->bv_len = len;
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
generalizedTimeOrderingMatch(
|
||||||
|
int *matchp,
|
||||||
|
slap_mask_t flags,
|
||||||
|
Syntax *syntax,
|
||||||
|
MatchingRule *mr,
|
||||||
|
struct berval *value,
|
||||||
|
void *assertedValue )
|
||||||
|
{
|
||||||
|
struct berval *asserted = (struct berval *) assertedValue;
|
||||||
|
ber_len_t v_len = value->bv_len;
|
||||||
|
ber_len_t av_len = asserted->bv_len;
|
||||||
|
|
||||||
|
/* ignore trailing 'Z' when comparing */
|
||||||
|
int match = memcmp( value->bv_val, asserted->bv_val,
|
||||||
|
(v_len < av_len ? v_len : av_len) - 1 );
|
||||||
|
if ( match == 0 ) match = v_len - av_len;
|
||||||
|
|
||||||
|
*matchp = match;
|
||||||
|
return LDAP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nisNetgroupTripleValidate(
|
nisNetgroupTripleValidate(
|
||||||
Syntax *syntax,
|
Syntax *syntax,
|
||||||
|
|
@ -2781,7 +2832,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
|
||||||
{"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
|
{"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
|
||||||
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
|
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
|
||||||
SLAP_MR_ORDERING, NULL,
|
SLAP_MR_ORDERING, NULL,
|
||||||
NULL, generalizedTimeNormalize, octetStringOrderingMatch,
|
NULL, generalizedTimeNormalize, generalizedTimeOrderingMatch,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
"generalizedTimeMatch" },
|
"generalizedTimeMatch" },
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue