2 * Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 /* Functions for operating in an PSK passwd file are included here */
27 #include <gnutls_int.h>
32 #include "gnutls_errors.h"
33 #include <auth_psk_passwd.h>
35 #include "gnutls_auth.h"
36 #include "gnutls_dh.h"
38 #include <gnutls_str.h>
39 #include <gnutls_datum.h>
40 #include <gnutls_num.h>
44 /* this function parses passwd.psk file. Format is:
45 * string(username):hex(passwd)
48 pwd_put_values (gnutls_datum_t
* psk
, char *str
)
54 p
= strchr (str
, ':');
58 return GNUTLS_E_SRP_PWD_PARSING_ERROR
;
70 if (p
[len
- 1] == '\n' || p
[len
- 1] == ' ')
73 size
= psk
->size
= len
/ 2;
74 psk
->data
= gnutls_malloc (size
);
75 if (psk
->data
== NULL
)
78 return GNUTLS_E_MEMORY_ERROR
;
81 ret
= _gnutls_hex2bin ((opaque
*) p
, len
, psk
->data
, &size
);
82 psk
->size
= (unsigned int) size
;
95 /* Randomizes the given password entry. It actually sets a random password.
96 * Returns 0 on success.
99 _randomize_psk (gnutls_datum_t
* psk
)
103 psk
->data
= gnutls_malloc (16);
104 if (psk
->data
== NULL
)
107 return GNUTLS_E_MEMORY_ERROR
;
112 ret
= _gnutls_rnd (GNUTLS_RND_NONCE
, (char *) psk
->data
, 16);
122 /* Returns the PSK key of the given user.
123 * If the user doesn't exist a random password is returned instead.
126 _gnutls_psk_pwd_find_entry (gnutls_session_t session
, char *username
,
127 gnutls_datum_t
* psk
)
129 gnutls_psk_server_credentials_t cred
;
135 cred
= (gnutls_psk_server_credentials_t
)
136 _gnutls_get_cred (session
->key
, GNUTLS_CRD_PSK
, NULL
);
140 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
143 /* if the callback which sends the parameters is
146 if (cred
->pwd_callback
!= NULL
)
148 ret
= cred
->pwd_callback (session
, username
, psk
);
151 { /* the user does not exist */
152 ret
= _randomize_psk (psk
);
164 return GNUTLS_E_SRP_PWD_ERROR
;
170 /* The callback was not set. Proceed.
172 if (cred
->password_file
== NULL
)
175 return GNUTLS_E_SRP_PWD_ERROR
;
178 /* Open the selected password file.
180 fd
= fopen (cred
->password_file
, "r");
184 return GNUTLS_E_SRP_PWD_ERROR
;
187 len
= strlen (username
);
188 while (fgets (line
, sizeof (line
), fd
) != NULL
)
190 /* move to first ':' */
192 while ((line
[i
] != ':') && (line
[i
] != '\0') && (i
< sizeof (line
)))
197 if (strncmp (username
, line
, MAX (i
, len
)) == 0)
199 ret
= pwd_put_values (psk
, line
);
204 return GNUTLS_E_SRP_PWD_ERROR
;
211 /* user was not found. Fake him.
212 * the last index found and randomize the entry.
214 ret
= _randomize_psk (psk
);
226 #endif /* ENABLE PSK */