1/* saslprep.c --- Internationalized SASL string processing.
2 * Copyright (C) 2002-2012 Simon Josefsson
3 *
4 * This file is part of GNU SASL Library.
5 *
6 * GNU SASL Library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * GNU SASL Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License License along with GNU SASL Library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "internal.h"
24
25#if HAVE_LIBIDN
26#include <stringprep.h>
27#if defined HAVE_PR29_H && defined HAVE_PR29_8Z
28#include <pr29.h>
29#endif
30#endif
31
32/**
33 * gsasl_saslprep:
34 * @in: a UTF-8 encoded string.
35 * @flags: any SASLprep flag, e.g., %GSASL_ALLOW_UNASSIGNED.
36 * @out: on exit, contains newly allocated output string.
37 * @stringpreprc: if non-NULL, will hold precise stringprep return code.
38 *
39 * Prepare string using SASLprep. On success, the @out variable must
40 * be deallocated by the caller.
41 *
42 * Return value: Returns %GSASL_OK on success, or
43 * %GSASL_SASLPREP_ERROR on error.
44 *
45 * Since: 0.2.3
46 **/
47int
48gsasl_saslprep (const char *in, Gsasl_saslprep_flags flags,
49 char **out, int *stringpreprc)
50{
51#if HAVE_LIBIDN
52 int rc;
53
54 rc = stringprep_profile (in, out, "SASLprep",
55 (flags & GSASL_ALLOW_UNASSIGNED)
56 ? STRINGPREP_NO_UNASSIGNED : 0);
57
58 if (stringpreprc)
59 *stringpreprc = rc;
60
61 if (rc != STRINGPREP_OK)
62 {
63 *out = NULL;
64 return GSASL_SASLPREP_ERROR;
65 }
66
67#if defined HAVE_PR29_8Z && defined HAVE_PR29_H
68 if (pr29_8z (*out) != PR29_SUCCESS)
69 {
70 free (*out);
71 *out = NULL;
72 if (stringpreprc)
73 *stringpreprc = STRINGPREP_NFKC_FAILED;
74
75 return GSASL_SASLPREP_ERROR;
76 }
77#endif
78
79#else
80 size_t i, inlen = strlen (in);
81
82 for (i = 0; i < inlen; i++)
83 if (in[i] & 0x80)
84 {
85 *out = NULL;
86 return GSASL_SASLPREP_ERROR;
87 }
88
89 *out = malloc (inlen + 1);
90 if (!*out)
91 return GSASL_MALLOC_ERROR;
92 strcpy (*out, in);
93#endif
94
95 return GSASL_OK;
96}
97