2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of libpwmd.
7 Libpwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Libpwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Libpwmd. If not, see <http://www.gnu.org/licenses/>.
45 #ifdef HAVE_GETPWUID_R
47 _expand_homedir (char *str
, struct passwd
*pw
)
57 if (*p
!= '~' || *(p
+ 1) != '/')
58 return pwmd_strdup (p
);
62 pwbuf
= _getpwuid (&t
);
70 result
= pwmd_strdup_printf ("%s/%s", pw
->pw_dir
, p
);
76 _getpwuid (struct passwd
*pwd
)
78 size_t size
= sysconf (_SC_GETPW_R_SIZE_MAX
);
79 struct passwd
*result
;
86 buf
= pwmd_malloc (size
);
90 n
= getpwuid_r (getuid (), pwd
, buf
, size
, &result
);
109 _expand_homedir (char *str
, struct passwd
*pw
)
116 if (*p
!= '~' || *(p
+ 1) != '/')
117 return pwmd_strdup (p
);
121 pw
= getpwuid (getuid ());
127 return pwmd_strdup_printf ("%s/%s", pw
->pw_dir
, p
);
131 _getpwuid (struct passwd
*pwd
)
133 struct passwd
*pw
= getpwuid (getuid ());
139 return pwmd_strdup ("");
144 * Borrowed from libassuan.
147 _percent_escape (const char *atext
)
149 const unsigned char *s
;
156 len
= strlen (atext
) * 3 + 1;
157 buf
= (char *) pwmd_malloc (len
);
164 for (s
= (const unsigned char *) atext
; *s
; s
++)
168 sprintf (p
, "%%%02X", *s
);
180 update_pinentry_settings (pwm_t
* pwm
)
186 char *pwbuf
= _getpwuid (&pw
);
191 snprintf (buf
, sizeof (buf
), "%s/.pwmd/pinentry.conf", pw
.pw_dir
);
193 if ((fp
= fopen (buf
, "r")) == NULL
)
199 while ((p
= fgets (buf
, sizeof (buf
), fp
)) != NULL
)
201 char name
[32] = {0}, val
[256] = {0};
203 if (sscanf (p
, " %31[a-zA-Z] = %255s", name
, val
) != 2)
206 if (strcasecmp (name
, "TTYNAME") == 0)
208 pwmd_free (pwm
->pinentry_tty
);
209 pwm
->pinentry_tty
= pwmd_strdup (val
);
210 if (!pwm
->pinentry_tty
)
213 else if (strcasecmp (name
, "TTYTYPE") == 0)
215 pwmd_free (pwm
->pinentry_term
);
216 pwm
->pinentry_term
= pwmd_strdup (val
);
217 if (!pwm
->pinentry_term
)
220 else if (strcasecmp (name
, "DISPLAY") == 0)
222 pwmd_free (pwm
->pinentry_display
);
223 pwm
->pinentry_display
= pwmd_strdup (val
);
224 if (!pwm
->pinentry_display
)
227 else if (strcasecmp (name
, "PATH") == 0)
229 pwmd_free (pwm
->pinentry_path
);
230 pwm
->pinentry_path
= _expand_homedir (val
, &pw
);
231 if (!pwm
->pinentry_path
)
234 else if (strcasecmp (name
, "LC_MESSAGES") == 0)
236 pwmd_free (pwm
->pinentry_lcmessages
);
237 pwm
->pinentry_lcmessages
= pwmd_strdup (val
);
238 if (!pwm
->pinentry_lcmessages
)
241 else if (strcasecmp (name
, "LC_CTYPE") == 0)
243 pwmd_free (pwm
->pinentry_lcctype
);
244 pwm
->pinentry_lcctype
= pwmd_strdup (val
);
245 if (!pwm
->pinentry_lcctype
)
255 /* Common hostname parsing for urls. Handles both IPv4 and IPv6 hostname and
256 * port specification.
259 parse_hostname_common (const char *str
, char **host
, int *port
)
264 /* IPv6 with optional port. */
275 /* Handle IPv6 without proper braces around the IP. */
288 size_t len
= strlen (p
) - strlen (t
) + 1;
290 *host
= pwmd_malloc (len
);
292 return gpg_error_from_errno (ENOMEM
);
294 snprintf (*host
, len
, "%s", p
);
301 *port
= strtol (t
, NULL
, 10);
306 while (*t
&& isdigit (*t
))
313 *host
= pwmd_strdup (str
);
315 return gpg_error_from_errno (ENOMEM
);
322 bin2hex (const unsigned char *data
, size_t len
)
324 size_t size
= len
* 2 + 1;
325 char buf
[size
]; // C99
330 for (n
= 0; n
< len
; n
++)
334 sprintf (c
, "%02X", data
[n
]);
338 return pwmd_strdup (buf
);