1/* md5pwd.c --- Find passwords in UoW imapd MD5 type password files.
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/**
26 * gsasl_simple_getpass:
27 * @filename: filename of file containing passwords.
28 * @username: username string.
29 * @key: newly allocated output character array.
30 *
31 * Retrieve password for user from specified file. The buffer @key
32 * contain the password if this function is successful. The caller is
33 * responsible for deallocating it.
34 *
35 * The file should be on the UoW "MD5 Based Authentication" format,
36 * which means it is in text format with comments denoted by # first
37 * on the line, with user entries looking as "usernameTABpassword".
38 * This function removes CR and LF at the end of lines before
39 * processing. TAB, CR, and LF denote ASCII values 9, 13, and 10,
40 * respectively.
41 *
42 * Return value: Return %GSASL_OK if output buffer contains the
43 * password, %GSASL_AUTHENTICATION_ERROR if the user could not be
44 * found, or other error code.
45 **/
46int
47gsasl_simple_getpass (const char *filename, const char *username, char **key)
48{
49 size_t userlen = strlen (username);
50 char *line = NULL;
51 size_t n = 0;
52 FILE *fh;
53
54 fh = fopen (filename, "r");
55 if (fh)
56 {
57 while (!feof (fh))
58 {
59 if (getline (&line, &n, fh) < 0)
60 break;
61
62 if (line[0] == '#')
63 continue;
64
65 if (line[strlen (line) - 1] == '\r')
66 line[strlen (line) - 1] = '\0';
67 if (line[strlen (line) - 1] == '\n')
68 line[strlen (line) - 1] = '\0';
69
70 if (strncmp (line, username, userlen) == 0 && line[userlen] == '\t')
71 {
72 *key = malloc (strlen (line) - userlen);
73 if (!*key)
74 {
75 free (line);
76 return GSASL_MALLOC_ERROR;
77 }
78
79 strcpy (*key, line + userlen + 1);
80
81 free (line);
82
83 fclose (fh);
84
85 return GSASL_OK;
86 }
87 }
88
89 fclose (fh);
90 }
91
92 free (line);
93
94 return GSASL_AUTHENTICATION_ERROR;
95}
96