edd2282d0a1acf14d338d21e021458654f0e271e
[exim.git] / src / src / auths / xtextdecode.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2022 */
6 /* Copyright (c) University of Cambridge 1995 - 2009 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 #include "../exim.h"
11
12
13 /*************************************************
14 *          Decode byte-string in xtext           *
15 *************************************************/
16
17 /* This function decodes a string in xtextformat as defined in RFC 1891 and
18 required by the SMTP AUTH extension (RFC 2554). We put the result in a piece of
19 store of equal length - it cannot be longer than this. Although in general the
20 result of decoding an xtext may be binary, in the context in which it is used
21 by Exim (for decoding the value of AUTH on a MAIL command), the result is
22 expected to be an addr-spec. We therefore add on a terminating zero, for
23 convenience.
24
25 Arguments:
26   code        points to the coded string, zero-terminated
27   ptr         where to put the pointer to the result, which is in
28               dynamic store
29
30 Returns:      the number of bytes in the result, excluding the final zero;
31               -1 if the input is malformed
32 */
33
34 int
35 auth_xtextdecode(uschar * code, uschar ** ptr)
36 {
37 int x;
38 uschar * result = store_get(Ustrlen(code) + 1, code);
39 *ptr = result;
40
41 while ((x = (*code++)) != 0)
42   {
43   if (x < 33 || x > 127 || x == '=') return -1;
44   if (x == '+')
45     {
46     register int y;
47     if (!isxdigit((x = (*code++)))) return -1;
48     y = ((isdigit(x))? x - '0' : (tolower(x) - 'a' + 10)) << 4;
49     if (!isxdigit((x = (*code++)))) return -1;
50     *result++ = y | ((isdigit(x))? x - '0' : (tolower(x) - 'a' + 10));
51     }
52   else *result++ = x;
53   }
54
55 *result = 0;
56 return result - *ptr;
57 }
58
59 /* End of xtextdecode.c */