51ae95b1def3f82aa55dc252d1739e85c597c8b2
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_psk / userinfo.c
1 /* $Id$ */
2
3
4 /*
5  * userinfo.c
6  *
7  * Implementation of the user management
8  *
9  * 
10  * Copyright (C) France Télécom R&D (DR&D/MAPS/NSS)
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  */
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <ctype.h>
34
35 #include "userinfo.h"
36 #include "eap_psk_ssm.h"
37 #include "eap_psk.h"  //hex2Bin()
38
39
40
41 userinfo_t*   pskGetUserInfo(char* path, char* peerID)
42 {
43     FILE*       fp;
44     char        buff[1024]; //FIXME: give the buffer a proper size 
45                             //when we know more about ID length
46     userinfo_t* uinfo = NULL;
47     int         found = 0;
48     char*       AK = NULL;
49     char*       KDK = NULL;
50         int res;
51
52     fp = fopen(path, "r");
53     if (fp == NULL)
54         {
55             radlog(L_ERR, "pskGetUserInfo: failed to open PSK users file");
56             return NULL;
57         }
58     
59     while (!found && fgets(buff, sizeof(buff), fp)) 
60         {
61           unsigned int     i = 0;
62
63             // ignore comments
64             if (buff[0] == '#')
65                 continue;
66
67             // read this login name
68             while (! isspace(buff[i]))
69                 i++;
70             
71             // is it the one we looking for?
72             if ((i != strlen(peerID)) 
73                 || (strncmp(peerID, buff, i) != 0))
74                 continue;
75             else
76                 found = 1;
77             
78             // skip spaces 
79             while (isspace(buff[i]))
80                 i++;
81             
82             // prepare to store user info
83             uinfo = (userinfo_t*) malloc(sizeof(userinfo_t));
84             if (uinfo == NULL)
85                 {
86                     radlog(L_ERR, "pskGetUserInfo: out of memory");
87                     return NULL;
88                 }
89
90             //get AK  
91             AK = strndup(buff + i, PSK_AK_STRLEN);
92             if (AK == NULL) {
93                 radlog(L_ERR, "pskGetUserInfo: out of memory");
94                                 free(uinfo);
95                                 return NULL;
96             }
97             //FIXME: shouldnt we check the key size?
98             /*
99               else if (strlen(AK) != 32) {
100               log();
101               return NULL;
102               }
103             */
104             res=pskHex2Bin(AK, &(uinfo->AK),PSK_AK_SIZE);
105
106                 if(!res)
107                 {
108                         radlog(L_ERR, "pskGetUserInfo: the key isn't in hexadecimal format");
109                         free(uinfo);
110                         free(AK);
111                         return NULL;
112                 }
113                    
114             //get KDK
115             KDK = strndup(buff + i + PSK_AK_STRLEN, PSK_KDK_STRLEN);
116             if (KDK == NULL) {
117                         radlog(L_ERR, "psk_get_user_info: out of memory");
118                         free(uinfo);
119                         free(AK);
120                         return NULL;
121             }
122             //FIXME: shouldnt we check the key size?
123             /*
124               else if (strlen(KDK) != 32) { 
125               log();
126               return NULL;
127               }             
128             */
129             res=pskHex2Bin(KDK, &(uinfo->KDK),PSK_KDK_SIZE);
130
131                 if(!res)
132                 {
133                         radlog(L_ERR, "pskGetUserInfo: the key isn't in hexadecimal format");
134                         free(uinfo);
135                         free(AK);
136                         free(KDK);
137                         return NULL;
138                 }
139            
140             free(AK);
141             free(KDK);
142         }
143    
144     
145     // if user was not found, NULL is returned
146     fclose(fp);
147     return uinfo;
148 }
149