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 Högskolan
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
wind_stringprep(const uint32_t * in,size_t in_len,uint32_t * out,size_t * out_len,wind_profile_flags flags)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
wind_profile(const char * name,wind_profile_flags * flags)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