Branch data Line data Source code
1 : : /* password.c --- Get passwords from user.
2 : : * Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 Simon Josefsson
3 : : *
4 : : * This file is part of Shishi.
5 : : *
6 : : * Shishi is free software; you can redistribute it and/or modify it
7 : : * under the terms of the GNU General Public License as published by
8 : : * the Free Software Foundation; either version 3 of the License, or
9 : : * (at your option) any later version.
10 : : *
11 : : * Shishi is distributed in the hope that it will be useful, but
12 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 : : * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 : : * Floor, Boston, MA 02110-1301, USA
20 : : *
21 : : */
22 : :
23 : : /* XXX? zeroize password */
24 : :
25 : : #include "internal.h"
26 : :
27 : : #include "getpass.h"
28 : :
29 : : #ifdef HAVE_LIBIDN
30 : : # include <stringprep.h>
31 : : #endif
32 : :
33 : : /**
34 : : * shishi_prompt_password_callback_set:
35 : : * @handle: shishi handle as allocated by shishi_init().
36 : : * @cb: function pointer to application password callback, a
37 : : * #shishi_prompt_password_func type.
38 : : *
39 : : * Set a callback function that will be used by
40 : : * shishi_prompt_password() to query the user for a password. The
41 : : * function pointer can be retrieved using
42 : : * shishi_prompt_password_callback_get().
43 : : *
44 : : * The @cb function should follow the %shishi_prompt_password_func prototype:
45 : : *
46 : : * int prompt_password (Shishi * @handle, char **@s,
47 : : * const char *@format, va_list @ap);
48 : : *
49 : : * If the function returns 0, the @s variable should contain a newly
50 : : * allocated string with the password read from the user.
51 : : **/
52 : : void
53 : 1 : shishi_prompt_password_callback_set (Shishi * handle,
54 : : shishi_prompt_password_func cb)
55 : : {
56 : 1 : handle->prompt_passwd = cb;
57 : 1 : }
58 : :
59 : : /**
60 : : * shishi_prompt_password_callback_get:
61 : : * @handle: shishi handle as allocated by shishi_init().
62 : : *
63 : : * Get the application password prompt function callback as set by
64 : : * shishi_prompt_password_callback_set().
65 : : *
66 : : * Returns: Returns the callback, a #shishi_prompt_password_func type,
67 : : * or %NULL.
68 : : **/
69 : : shishi_prompt_password_func
70 : 2 : shishi_prompt_password_callback_get (Shishi * handle)
71 : : {
72 : 2 : return handle->prompt_passwd;
73 : : }
74 : :
75 : : /**
76 : : * shishi_prompt_password:
77 : : * @handle: shishi handle as allocated by shishi_init().
78 : : * @s: pointer to newly allocated output string with read password.
79 : : * @format: printf(3) style format string.
80 : : * @...: printf(3) style arguments.
81 : : *
82 : : * Format and print a prompt, and read a password from user. The
83 : : * password is possibly converted (e.g., converted from Latin-1 to
84 : : * UTF-8, or processed using Stringprep profile) following any
85 : : * "stringprocess" keywords in configuration files.
86 : : *
87 : : * Return value: Returns SHISHI_OK iff successful.
88 : : **/
89 : : int
90 : 2 : shishi_prompt_password (Shishi * handle, char **s, const char *format, ...)
91 : : {
92 : : char *p;
93 : : va_list ap;
94 : :
95 [ + - ]: 2 : if (handle->prompt_passwd)
96 : : {
97 : : int ret;
98 : 2 : va_start (ap, format);
99 : 2 : ret = handle->prompt_passwd (handle, s, format, ap);
100 : 2 : va_end (ap);
101 : :
102 : 2 : return ret;
103 : : }
104 : :
105 : : #ifdef HAVE_LIBIDN
106 [ # # ]: 0 : if (VERBOSE (handle))
107 : : {
108 : 0 : printf ("Libstringprep thinks your locale is `%s'.\n",
109 : : stringprep_locale_charset ());
110 : : }
111 : : #endif
112 : :
113 : 0 : va_start (ap, format);
114 : 0 : vprintf (format, ap);
115 : 0 : fflush (stdout);
116 : 0 : va_end (ap);
117 : :
118 : 0 : p = getpass ("");
119 : :
120 : 0 : *s = xstrdup (p);
121 : :
122 : 0 : printf ("\n");
123 : :
124 [ # # ]: 0 : if (VERBOSENOISE (handle))
125 : : {
126 : : size_t i;
127 : 0 : printf ("Read password (length %d): ", strlen (*s));
128 [ # # ]: 0 : for (i = 0; i < strlen (*s); i++)
129 : 0 : printf ("%02x ", (*s)[i] & 0xFF);
130 : 0 : printf ("\n");
131 : : }
132 : :
133 [ # # ][ # # ]: 0 : if (handle->stringprocess
134 : 0 : && strcasecmp (handle->stringprocess, "none") != 0)
135 : : #ifdef HAVE_LIBIDN
136 : : {
137 [ # # ]: 0 : if (strcasecmp (handle->stringprocess, "stringprep") == 0)
138 : 0 : p = stringprep_locale_to_utf8 (*s);
139 : : else
140 : 0 : p = stringprep_convert (*s, handle->stringprocess,
141 : : stringprep_locale_charset ());
142 : :
143 [ # # ]: 0 : if (p)
144 : : {
145 : 0 : free (*s);
146 : 0 : *s = p;
147 : : }
148 : : else
149 : 0 : shishi_warn (handle, "Charset conversion of password failed");
150 : :
151 [ # # ]: 0 : if (VERBOSENOISE (handle))
152 : : {
153 : : size_t i;
154 [ # # ]: 0 : printf ("Password converted to %s (length %d): ",
155 : 0 : strcasecmp (handle->stringprocess, "stringprep") == 0 ?
156 : 0 : "UTF-8" : handle->stringprocess, strlen (*s));
157 [ # # ]: 0 : for (i = 0; i < strlen (*s); i++)
158 : 0 : printf ("%02x ", (*s)[i] & 0xFF);
159 : 0 : printf ("\n");
160 : : }
161 : :
162 [ # # ]: 0 : if (strcasecmp (handle->stringprocess, "stringprep") == 0)
163 : : {
164 : : int rc;
165 : :
166 : 0 : rc = stringprep_profile (*s, &p, "SASLprep", 0);
167 [ # # ]: 0 : if (rc == SHISHI_OK)
168 : : {
169 : 0 : free (*s);
170 : 0 : *s = p;
171 : : }
172 : : else
173 : 0 : shishi_warn (handle, "Stringprep conversion of password failed");
174 : :
175 [ # # ]: 0 : if (VERBOSENOISE (handle))
176 : : {
177 : : size_t i;
178 : 0 : printf ("Stringprep'ed password (length %d): ", strlen (*s));
179 [ # # ]: 0 : for (i = 0; i < strlen (*s); i++)
180 : 0 : printf ("%02x ", (*s)[i] & 0xFF);
181 : 0 : printf ("\n");
182 : : }
183 : :
184 : : }
185 : : }
186 : : #else
187 : : shishi_warn (handle, "Password string processing (%s) disabled",
188 : : handle->stringprocess);
189 : : #endif
190 : :
191 : 2 : return SHISHI_OK;
192 : : }
|