Home | History | Annotate | Line # | Download | only in wind
      1 /*	$NetBSD: stringprep.c,v 1.2 2017/01/28 21:31:50 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2004, 2006, 2008 Kungliga Tekniska Hgskolan
      5  * (Royal Institute of Technology, Stockholm, Sweden).
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * 3. Neither the name of the Institute nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #ifdef HAVE_CONFIG_H
     37 #include <config.h>
     38 #endif
     39 #include "windlocl.h"
     40 #include <stdlib.h>
     41 #include <string.h>
     42 #include <errno.h>
     43 
     44 /**
     45  * Process a input UCS4 string according a string-prep profile.
     46  *
     47  * @param in input UCS4 string to process
     48  * @param in_len length of the input string
     49  * @param out output UCS4 string
     50  * @param out_len length of the output string.
     51  * @param flags stringprep profile.
     52  *
     53  * @return returns 0 on success, an wind error code otherwise
     54  * @ingroup wind
     55  */
     56 
     57 int
     58 wind_stringprep(const uint32_t *in, size_t in_len,
     59 		uint32_t *out, size_t *out_len,
     60 		wind_profile_flags flags)
     61 {
     62     size_t tmp_len = in_len * 3;
     63     uint32_t *tmp;
     64     int ret;
     65     size_t olen;
     66 
     67     if (in_len == 0) {
     68 	*out_len = 0;
     69 	return 0;
     70     }
     71 
     72     tmp = malloc(tmp_len * sizeof(uint32_t));
     73     if (tmp == NULL)
     74 	return ENOMEM;
     75 
     76     ret = _wind_stringprep_map(in, in_len, tmp, &tmp_len, flags);
     77     if (ret) {
     78 	free(tmp);
     79 	return ret;
     80     }
     81 
     82     olen = *out_len;
     83     ret = _wind_stringprep_normalize(tmp, tmp_len, tmp, &olen);
     84     if (ret) {
     85 	free(tmp);
     86 	return ret;
     87     }
     88     ret = _wind_stringprep_prohibited(tmp, olen, flags);
     89     if (ret) {
     90 	free(tmp);
     91 	return ret;
     92     }
     93     ret = _wind_stringprep_testbidi(tmp, olen, flags);
     94     if (ret) {
     95 	free(tmp);
     96 	return ret;
     97     }
     98 
     99     /* Insignificant Character Handling for ldap-prep */
    100     if (flags & WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE) {
    101 	ret = _wind_ldap_case_exact_attribute(tmp, olen, out, out_len);
    102 #if 0
    103     } else if (flags & WIND_PROFILE_LDAP_CASE_EXACT_ASSERTION) {
    104     } else if (flags & WIND_PROFILE_LDAP_NUMERIC) {
    105     } else if (flags & WIND_PROFILE_LDAP_TELEPHONE) {
    106 #endif
    107     } else {
    108 	memcpy(out, tmp, sizeof(out[0]) * olen);
    109 	*out_len = olen;
    110     }
    111     free(tmp);
    112 
    113     return ret;
    114 }
    115 
    116 static const struct {
    117     const char *name;
    118     wind_profile_flags flags;
    119 } profiles[] = {
    120     { "nameprep", WIND_PROFILE_NAME },
    121     { "saslprep", WIND_PROFILE_SASL },
    122     { "ldapprep", WIND_PROFILE_LDAP }
    123 };
    124 
    125 /**
    126  * Try to find the profile given a name.
    127  *
    128  * @param name name of the profile.
    129  * @param flags the resulting profile.
    130  *
    131  * @return returns 0 on success, an wind error code otherwise
    132  * @ingroup wind
    133  */
    134 
    135 int
    136 wind_profile(const char *name, wind_profile_flags *flags)
    137 {
    138     unsigned int i;
    139 
    140     for (i = 0; i < sizeof(profiles)/sizeof(profiles[0]); i++) {
    141 	if (strcasecmp(profiles[i].name, name) == 0) {
    142 	    *flags = profiles[i].flags;
    143 	    return 0;
    144 	}
    145     }
    146     return WIND_ERR_NO_PROFILE;
    147 }
    148