1 /*
2  *  radiusplugin -- An OpenVPN plugin for do radius authentication
3  *					and accounting.
4  *
5  *  Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <ralfluebben@gmx.de>
6  *
7  *  This program 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  *  any later version.
11  *
12  *  This program 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.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 
23 #include "Config.h"
24 
25 
26 /** The constructor The constructor initializes all char arrays with 0.
27  */
28 
Config(void)29 Config::Config(void)
30 {
31 
32 	this->usernameascommonname=false;
33 	this->clientcertnotrequired=false;
34 	this->overwriteccfiles=true;
35         this->useauthcontrolfile=false;
36 	this->ccdPath="";
37 	this->openvpnconfig="";
38 	this->vsanamedpipe="";
39 	this->vsascript="";
40 	memset(this->subnet,0,16);
41 	memset(this->p2p,0,16);
42 }
43 
44 /** The constructor initializes all char arrays with 0. After the initialization
45  * the configfile is parsed and the information which are
46  * found are copied to the attributes.
47  * @param configfile The name of the configfile.
48  */
49 
Config(char * configfile)50 Config::Config(char * configfile)
51 {
52 	memset(this->subnet,0,16);
53 	memset(this->p2p,0,16);
54 	this->ccdPath="";
55 	this->openvpnconfig="";
56 	this->vsanamedpipe="";
57 	this->vsascript="";
58 	this->usernameascommonname=false;
59 	this->clientcertnotrequired=false;
60 	this->overwriteccfiles=true;
61         this->useauthcontrolfile=false;
62 	this->parseConfigFile(configfile);
63 
64 }
65 
66 
67 /** The destructur clears the serverlist. */
~Config(void)68 Config::~Config(void)
69 {
70 
71 
72 }
73 
74 
75 
76 /** The method parse the configfile for attributes and
77  * radius server, the attributes are copied to the
78  * member variables.
79  * @param configfile The name of the configfile.
80  * @return An integer, 0 if everything is ok
81  * or PARSING_ERROR or BAD_FILE if something is wrong.*/
parseConfigFile(const char * configfile)82 int Config::parseConfigFile(const char * configfile)
83 {
84 	string line;
85 
86 	ifstream file;
87 	file.open(configfile, ios::in);
88 	if (file.is_open())
89 	{
90 		while (file.eof()==false)
91 		{
92 			getline(file,line);
93 			this->deletechars(&line);
94 			if(line.empty()==false)
95 			{
96 				if (strncmp(line.c_str(),"subnet=",7)==0)
97 				{
98 					if((line.size()-7)>15)
99 					{
100 						return BAD_FILE;
101 					}
102 					line.copy(this->subnet,line.size()-7,7);
103 
104 				}
105 				if (strncmp(line.c_str(),"p2p=",4)==0)
106 				{
107 					if((line.size()-4)>15)
108 					{
109 						return BAD_FILE;
110 					}
111 					line.copy(this->p2p,line.size()-4,4);
112 				}
113 				if (strncmp(line.c_str(),"vsascript=",10)==0)
114 				{
115 					this->vsascript=line.substr(10,line.size()-10);
116 				}
117 				if (strncmp(line.c_str(),"vsanamedpipe=",13)==0)
118 				{
119 					this->vsanamedpipe=line.substr(13,line.size()-13);
120 				}
121 
122 				if (strncmp(line.c_str(),"OpenVPNConfig=",14)==0)
123 				{
124 					this->openvpnconfig=line.substr(14,line.size()-14);
125 				}
126 				if (strncmp(line.c_str(),"overwriteccfiles=",17)==0)
127 				{
128 
129 					string stmp=line.substr(17,line.size()-17);
130 					deletechars(&stmp);
131 					if(stmp == "true") this->overwriteccfiles=true;
132 					else if (stmp =="false") this->overwriteccfiles=false;
133 					else return BAD_FILE;
134 
135 				}
136                                 if (strncmp(line.c_str(),"useauthcontrolfile=",19)==0)
137 				{
138 
139 					string stmp=line.substr(19,line.size()-19);
140 					deletechars(&stmp);
141 					if(stmp == "true") this->useauthcontrolfile=true;
142 					else if (stmp =="false") this->useauthcontrolfile=false;
143 					else return BAD_FILE;
144 
145 				}
146 			}
147 
148 		}
149 		file.close();
150 		// if the main files contains references to other config files
151 		// we don't need to care about recursive includes, OpenVPN does it already
152 		list<string> configfiles;
153 		configfiles.push_back(this->openvpnconfig);
154 		//open OpenVPN config
155 		while(configfiles.size() > 0)
156 		{
157 		  ifstream file2;
158 		  string filename=configfiles.front();
159 		  file2.open(filename.c_str(), ios::in);
160 		  char const* delims = " \t\r\n\0";
161 		  if (file2.is_open())
162 		  {
163 			  while(file2.eof()==false)
164 			  {
165 				  getline(file2,line);
166 
167 				  if(line.empty()==false)
168 				  {
169 					  string param=line;
170 					  // trim leading whitespace
171 					  string::size_type  pos = param.find_first_not_of(delims);
172 					  if (pos != string::npos) param.erase(0,pos );
173 					  pos=param.find_first_of(delims);
174 					  if (pos != string::npos) param.erase(pos);
175 					  if (param == "client-cert-not-required")
176 					  {
177 						  this->deletechars(&line);
178 						  if (line == "client-cert-not-required")
179 						  {
180 							  this->clientcertnotrequired=true;
181 						  }
182 					  }
183 					  if (param == "username-as-common-name")
184 					  {
185 						  this->deletechars(&line);
186 						  if (line == "username-as-common-name")
187 						  {
188 							  this->usernameascommonname=true;
189 						  }
190 					  }
191 					  if (param == "client-config-dir")
192 					  {
193 						  this->deletechars(&line);
194 						  line.erase(0, 17);
195 						  this->setCcdPath(line);
196 					  }
197 					  if (param == "config")
198 					  {
199 						  this->deletechars(&line);
200 						  line.erase(0, 6);
201 						  configfiles.push_back(line);
202 					  }
203 					  if (param == "status")
204 					  {
205 						  //method deletechars don't work, entry has formet: status <file> [time]
206 						  pos  = line.find_first_of("#");
207 						  if (pos != string::npos)
208 						  {
209 							  line.erase(pos);
210 						  }
211 						  // trim leading whitespace
212 						  pos = line.find_first_not_of(delims);
213 						  if (pos != string::npos) line.erase(0,pos);
214 						  line.erase(0, 6);
215 						  // trim leading whitespace again
216 						  pos = line.find_first_not_of(" \t");
217 						  if (pos != string::npos) line.erase(0,pos);
218 						  //delete the trailing version of status if there
219 						  pos = line.find_first_of(delims);
220 						  if (pos != string::npos) line.erase(pos);
221 						  this->deletechars(&line);
222 						  if(!line.empty())
223 						  {
224 
225 						    this->statusfile=line;
226 						  }
227 					  }
228 				  }
229 			  }
230 			  file.close();
231 			  configfiles.remove(filename);
232 		  }
233 		  else
234 		  {
235 			  return BAD_FILE;
236 		  }
237 		}
238 	}
239 	else
240 	{
241 		return BAD_FILE;
242 	}
243 	return 0;
244 }
245 
246 
247 /** The method deletes chars from a string.
248  * This is used to delete tabs, spaces, # and '\0'
249  * from a string.
250  * @param text The string which should be cleaned.
251  */
deletechars(string * line)252 void Config::deletechars(string * line)
253 {
254 	char const* delims = " \t\r\n\0";
255 
256    // trim leading whitespace
257    string::size_type  pos = line->find_first_not_of(delims);
258    if (pos != string::npos) line->erase(0,pos );
259    // trim trailing whitespace
260    pos  = line->find_last_not_of(delims);
261    if (pos != string::npos)  line->erase(pos+1);
262 
263    //trim whitespaces in line
264    pos  = line->find_first_of(delims);
265    while (pos != string::npos)
266    {
267    	 line->erase(pos,1);
268    	 pos  = line->find_first_of(delims);
269    }
270 
271    // trim comments
272    pos  = line->find_first_of("#");
273    if (pos != string::npos)
274    {
275    	line->erase(pos);
276    }
277 
278 }
279 
280 
281 /**The method finds the part of the string after the
282  * '=' and puts it in the value.
283  * @param text The string with the value.
284  * @param value The value where to put the part of the string. */
getValue(const char * text,char * value)285 void Config::getValue(const char * text, char * value)
286 {
287 	int i=0,j=0;
288 	while (text[i]!='=' && text[i]!='\0')
289 	{
290 		i++;
291 	}
292 	i++;
293 	while (text[i]!='\0')
294 	{
295 		value[j]=text[i];
296 		i++;
297 		j++;
298 	}
299 	value[j]='\0';
300 }
301 
302 
303 
304 
305 
306 /** The getter methid for the client config dir (ccd).
307  * @return A string to the ccd.
308  */
getCcdPath(void)309 string Config::getCcdPath(void)
310 {
311 	return this->ccdPath;
312 }
313 
314 
315 /** The setter method for the client config dir (ccd).
316  * @param path A string to the ccd path.
317  */
setCcdPath(string path)318 void Config::setCcdPath(string path)
319 {
320 	if(path[path.length()]!= '/')
321 	{
322 		path +='/';
323 	}
324 	this->ccdPath=path;
325 }
326 
327 /** Returns the path to the status file.
328  * @param A string to path of the status file.
329  */
getStatusFile(void)330 string Config::getStatusFile(void)
331 {
332 	return this->statusfile;
333 }
334 
335 /** The setter method for thepath to the statusfile (path + filename).
336  * @param file A string of the filepath.
337  */
setStatusFile(string file)338 void Config::setStatusFile(string file)
339 {
340 
341 	this->statusfile=file;
342 }
343 
344 /** The setter method for the nas ip address.
345  * @param ip A string with ip address.
346  */
setSubnet(char * ip)347 void Config::setSubnet(char * ip)
348 {
349 	strncpy(this->subnet,ip, 16);
350 }
351 
352 
353 /** The getter method for the nas ip address.
354  * @return A pointer to the nas ipaddress.
355  */
getSubnet(void)356 char * Config::getSubnet(void)
357 {
358 	return this->subnet;
359 }
360 
361 /** The setter method for the p2p address.
362  * @param ip A string with p2p address.
363  */
setP2p(char * ip)364 void Config::setP2p(char * ip)
365 {
366 	strncpy(this->p2p,ip, 16);
367 }
368 
369 
370 /** The getter method for the p2p address.
371  * @return A pointer to the p2p address.
372  */
getP2p(void)373 char * Config::getP2p(void)
374 {
375 	return this->p2p;
376 }
377 
378 /** The setter method for the vsascript.
379  * @param script A path of the script.
380  */
setVsaScript(string script)381 void Config::setVsaScript(string script)
382 {
383 	this->vsascript=script;
384 }
385 
386 
387 /** The getter method for vsascript.
388  * @return A pointer to the path of the script.
389  */
getVsaScript(void)390 string Config::getVsaScript(void)
391 {
392 	return this->vsascript;
393 }
394 
395 /** The setter method for the usernameascommonname value.
396  * @param b A boolean for option usernameascommonname.
397  */
setUsernameAsCommonname(bool b)398 void Config::setUsernameAsCommonname(bool b)
399 {
400 	this->usernameascommonname=b;
401 }
402 
403 
404 /** The getter method for the usernameascommonname value.
405  * @return A boolean for option usernameascommonname.
406  */
getUsernameAsCommonname(void)407 bool Config::getUsernameAsCommonname(void)
408 {
409 	return this->usernameascommonname;
410 }
411 
412 /** The setter method for the vsanamedpipe.
413  * @param script A path of the pipe.
414  */
setVsaNamedPipe(string pipe)415 void Config::setVsaNamedPipe(string pipe)
416 {
417 	this->vsanamedpipe=pipe;
418 }
419 
420 
421 /** The getter method for vsanamedpipe.
422  * @return A pointer to the path of the pipe.
423  */
getVsaNamedPipe(void)424 string Config::getVsaNamedPipe(void)
425 {
426 	return this->vsanamedpipe;
427 }
428 
429 
430 /** The setter method for the clientcertnotrequired value.
431  * @param b A boolean for option clientcertnotrequired.
432  */
setClientCertNotRequired(bool b)433 void Config::setClientCertNotRequired(bool b)
434 {
435 	this->clientcertnotrequired=b;
436 }
437 
438 
439 /** The getter method for the clientcertnotrequired value.
440  * @return A boolean for option clientcertnotrequired.
441  */
getClientCertNotRequired(void)442 bool Config::getClientCertNotRequired(void)
443 {
444 	return this->clientcertnotrequired;
445 }
446 
447 /** The getter method for the path to the OpenVPN config
448  * @return A string to the path.
449  */
getOpenVPNConfig(void)450 string Config::getOpenVPNConfig(void)
451 {
452 	return this->openvpnconfig;
453 }
454 
455 /** The setter method for the path to the OpenVPN config
456  * @param conf Path to the config file.
457  */
setOpenVPNConfig(string conf)458 void Config::setOpenVPNConfig(string conf)
459 {
460 	this->openvpnconfig=conf;
461 }
462 
463 /** The getter method for the overwriteccfiles variable.
464  * @return A bool of overwriteccfiles.
465  */
getOverWriteCCFiles(void)466 bool Config::getOverWriteCCFiles(void)
467 {
468 	return this->overwriteccfiles;
469 }
470 
471 /** The setter method for the overwriteccfiles varibale
472  * @param overwrite Set to true if the plugin is allowed to overwrite the client config files.
473  */
setOverWriteCCFiles(bool overwrite)474 void Config::setOverWriteCCFiles(bool overwrite)
475 {
476 	this->overwriteccfiles=overwrite;
477 }
478 
479 /** Getter method for the authcontrolfile variable.
480  * @return A bool of authcontrolfile .
481  */
getUseAuthControlFile(void)482 bool Config::getUseAuthControlFile(void)
483 {
484 	return this->useauthcontrolfile;
485 }
486 
487 /** The setter method for the authcontrolfile  varibale
488  * @param overwrite Set to true if the plugin if auth control files should be if supported by the OpenVPN version.
489  */
setUseAuthControlFile(bool b)490 void Config::setUseAuthControlFile(bool b)
491 {
492 	this->useauthcontrolfile=b;
493 }
494