Description: framed-ipv6-address.patch
   * Add Framed-IPv6-Address support.
Author: Samuel Thibault <sthibault@debian.org>
X-Dgit-Generated: 2.1-6+IP6.3 0848b2e4241dc17c1461c2349649026d37b65300

---

--- openvpn-auth-radius-2.1.orig/AccountingProcess.cpp
+++ openvpn-auth-radius-2.1/AccountingProcess.cpp
@@ -97,6 +97,7 @@ void AccountingProcess::Accounting(Plugi
 					user->setPortnumber(context->acctsocketforegr.recvInt()); 
 					user->setCallingStationId(context->acctsocketforegr.recvStr()); 
 					user->setFramedIp(context->acctsocketforegr.recvStr()); 
+					user->setFramedIp6(context->acctsocketforegr.recvStr());
 					user->setCommonname(context->acctsocketforegr.recvStr());
 					user->setAcctInterimInterval(context->acctsocketforegr.recvInt());
 					user->setFramedRoutes(context->acctsocketforegr.recvStr());
@@ -106,7 +107,7 @@ void AccountingProcess::Accounting(Plugi
 					user->setUntrustedPort(context->acctsocketforegr.recvStr());
 					context->acctsocketforegr.recvBuf(user);
 					if (DEBUG (context->getVerbosity()))
-				    	cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: New user acct: username: " << user->getUsername() << ", interval: " << user->getAcctInterimInterval() << ", calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ", framed ip: " << user->getFramedIp() <<".\n";
+					cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: New user acct: username: " << user->getUsername() << ", interval: " << user->getAcctInterimInterval() << ", calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ", framed ip: " << user->getFramedIp() << ", framed ipv6: " << user->getFramedIp6() <<".\n";
 					
 					
 					//set the starttime
--- openvpn-auth-radius-2.1.orig/AuthenticationProcess.cpp
+++ openvpn-auth-radius-2.1/AuthenticationProcess.cpp
@@ -110,6 +110,9 @@ void AuthenticationProcess::Authenticati
 			     	//send the IPv6 routes to the parent process
 			     	context->authsocketforegr.send(user->getFramedRoutes6());
 					
+				//send the framed IPv6 to the parent process
+			     	context->authsocketforegr.send(user->getFramedIp6());
+										
 					//send the interval to the parent process
 			     	context->authsocketforegr.send(user->getAcctInterimInterval());
 			     	
--- openvpn-auth-radius-2.1.orig/Config.cpp
+++ openvpn-auth-radius-2.1/Config.cpp
@@ -39,6 +39,7 @@ Config::Config(void)
 	this->vsascript="";
 	memset(this->subnet,0,16);
 	memset(this->p2p,0,16);
+	memset(this->p2p6,0,40);
 }
 
 /** The constructor initializes all char arrays with 0. After the initialization
@@ -51,6 +52,7 @@ Config::Config(char * configfile)
 {
 	memset(this->subnet,0,16);
 	memset(this->p2p,0,16);
+	memset(this->p2p6,0,40);
 	this->ccdPath="";
 	this->openvpnconfig="";
 	this->vsanamedpipe="";
@@ -110,6 +112,14 @@ int Config::parseConfigFile(const char *
 					}
 					line.copy(this->p2p,line.size()-4,4);
 				}
+				if (strncmp(line.c_str(),"p2p6=",5)==0)
+				{
+					if((line.size()-5)>39)
+					{
+						return BAD_FILE;
+					}
+					line.copy(this->p2p6,line.size()-5,5);
+				}
 				if (strncmp(line.c_str(),"vsascript=",10)==0)
 				{
 					this->vsascript=line.substr(10,line.size()-10);
@@ -375,6 +385,23 @@ char * Config::getP2p(void)
 	return this->p2p;
 }
 
+/** The setter method for the p2p6 address.
+ * @param ip A string with p2p6 address.
+ */	
+void Config::setP2p6(char * ip)
+{
+	strncpy(this->p2p6,ip, 40);
+}
+
+
+/** The getter method for the p2p6 address.
+ * @return A pointer to the p2p6 address.
+ */
+char * Config::getP2p6(void)
+{
+	return this->p2p6;
+}
+
 /** The setter method for the vsascript.
  * @param script A path of the script.
  */	
--- openvpn-auth-radius-2.1.orig/Config.h
+++ openvpn-auth-radius-2.1/Config.h
@@ -43,6 +43,7 @@ private:
     string statusfile; 				/**< The path and filename of the status file, where openvpn writes the status information.*/ 
 	char subnet[16];				/**<The subnet which is assigned to the client in topology option.*/
 	char p2p[16];					/**<The OpenVPN server address which is assigned to the client in topology p2p.*/
+	char p2p6[40];					/**<The OpenVPN server IPv6 address which is assigned to the client in topology p2p.*/
 	string vsascript;				/**<A script whcih handles vendor specific attributes.*/
 	string vsanamedpipe;		/**<The named pipe to the vsascript.*/
 	bool usernameascommonname;		/**<Use the username as commonname in the plugin (for OpenVPN option username-as-common-name (no commonname in the enviroment!)).*/
@@ -76,6 +77,9 @@ public:
 	char * getP2p(void);
 	void setP2p(char * );
 	
+	char * getP2p6(void);
+	void setP2p6(char * );
+	
 	string getVsaScript(void);
 	void setVsaScript(string);
 	
--- openvpn-auth-radius-2.1.orig/RadiusClass/RadiusAttribute.cpp
+++ openvpn-auth-radius-2.1/RadiusClass/RadiusAttribute.cpp
@@ -568,3 +568,26 @@ string RadiusAttribute::ipFromBuf(void)
 	}
 	return string(ip3);			 
 }  
+
+/** The method converts the value into an IPv6.
+ * The attribute must have the right datatype IPADDRESS6.
+ * @return The ip address as a string.
+ */
+string RadiusAttribute::ip6FromBuf(void)
+{
+	int num,i,len;
+	char ip2[3],ip3[40];
+	memset(ip3,0,40);
+	len=(this->length-2);
+	if(len>16)
+		len=16;
+	for (i=0;i<len;i++)
+	{
+		num=(int)this->value[i];
+		sprintf(ip2,"%02x",num);
+		strcat(ip3,ip2);
+		if((i%2)==1 && i<len-1)
+			strcat(ip3,":");
+	}
+	return string(ip3);
+}  
--- openvpn-auth-radius-2.1.orig/RadiusClass/RadiusAttribute.h
+++ openvpn-auth-radius-2.1/RadiusClass/RadiusAttribute.h
@@ -68,6 +68,7 @@ public:
 	int				intFromBuf(void);
 	 
 	string			ipFromBuf(void); 
+	string			ip6FromBuf(void); 
 		
 	void			dumpRadiusAttrib(void);
 	
--- openvpn-auth-radius-2.1.orig/RadiusClass/utilities/dictionary
+++ openvpn-auth-radius-2.1/RadiusClass/utilities/dictionary
@@ -123,6 +123,8 @@ ATTRIBUTE	NAS-IPv6-Address		95	ipaddr6
 ATTRIBUTE	Login-IPv6-Host			98	ipaddr6	
 ATTRIBUTE	Framed-IPv6-Route		99	string	
 ATTRIBUTE	Framed-IPv6-Pool		100	string	
+ATTRIBUTE	Framed-IPv6-Address		168	ipaddr6
+
 ATTRIBUTE	X-Ascend-FCP-Parameter		119	string	
 ATTRIBUTE	Ascend-Modem-PortNo		120	integer	
 ATTRIBUTE	Ascend-Modem-SlotNo		121	integer	
--- openvpn-auth-radius-2.1.orig/RadiusClass/utilities/vsa.h
+++ openvpn-auth-radius-2.1/RadiusClass/utilities/vsa.h
@@ -161,6 +161,8 @@
   	//ATTRIBUTE	Login-IPv6-Host			98	ipaddr6	
   	//ATTRIBUTE	Framed-IPv6-Route		99	string	
   	//ATTRIBUTE	Framed-IPv6-Pool		100	string	
+  	//ATTRIBUTE	Framed-IPv6-Address		168	ipaddr6	
+  	//
   	//ATTRIBUTE	X-Ascend-FCP-Parameter		119	string	
   	//ATTRIBUTE	Ascend-Modem-PortNo		120	integer	
   	//ATTRIBUTE	Ascend-Modem-SlotNo		121	integer	
--- openvpn-auth-radius-2.1.orig/RadiusClass/vsa.h
+++ openvpn-auth-radius-2.1/RadiusClass/vsa.h
@@ -161,6 +161,8 @@
   	//ATTRIBUTE	Login-IPv6-Host			98	ipaddr6	
   	//ATTRIBUTE	Framed-IPv6-Route		99	string	
   	//ATTRIBUTE	Framed-IPv6-Pool		100	string	
+  	//ATTRIBUTE	Framed-IPv6-Address		168	ipaddr6	
+  	//
   	//ATTRIBUTE	X-Ascend-FCP-Parameter		119	string	
   	//ATTRIBUTE	Ascend-Modem-PortNo		120	integer	
   	//ATTRIBUTE	Ascend-Modem-SlotNo		121	integer	
--- openvpn-auth-radius-2.1.orig/User.cpp
+++ openvpn-auth-radius-2.1/User.cpp
@@ -27,6 +27,7 @@ User::User()
 	this->dev="";
 	this->framedip="";
 	this->framedroutes="";
+	this->framedip6="";
 	this->framedroutes6="";
 	this->key="";
         this->statusfilekey="";
@@ -46,6 +47,7 @@ User::User()
 	this->dev="";
 	this->framedip="";
 	this->framedroutes="";
+	this->framedip6="";
 	this->framedroutes6="";
 	this->key="";
 	this->untrustedport="";
@@ -73,8 +75,9 @@ User & User::operator=(const User & u)
 	this->username=u.username;
 	this->commonname=u.commonname;
 	this->dev=u.dev;
-	this->framedroutes=u.framedroutes;
 	this->framedip=u.framedip;
+	this->framedroutes=u.framedroutes;
+	this->framedip6=u.framedip6;
 	this->framedroutes6=u.framedroutes6;
 	this->key=u.key;
         this->statusfilekey=u.statusfilekey;
@@ -107,8 +110,9 @@ User::User(const User & u)
 	this->username=u.username;
 	this->commonname=u.commonname;
 	this->dev=u.dev;
-	this->framedroutes=u.framedroutes;
 	this->framedip=u.framedip;
+	this->framedroutes=u.framedroutes;
+	this->framedip6=u.framedip6;
 	this->framedroutes6=u.framedroutes6;
 	this->key=u.key;
         this->statusfilekey=u.statusfilekey;
@@ -211,6 +215,19 @@ void User::setFramedIp(string ip)
 	this->framedip=ip;
 }
 
+/** The getter method for the framed IPv6.
+ *  @return The framed IPv6 as a string.*/
+string User::getFramedIp6(void)
+{
+	return this->framedip6;
+}
+/** The setter method for the framedip6.
+ * @param ip The framedip.*/
+void User::setFramedIp6(string ip)
+{
+	this->framedip6=ip;
+}
+
 /** The getter method for the fkey.
  *  @return The unique key as a string.*/
 string User::getKey(void)
--- openvpn-auth-radius-2.1.orig/User.h
+++ openvpn-auth-radius-2.1/User.h
@@ -48,6 +48,7 @@ protected:
 	string framedroutes;		/**<The framedroutes, they are stored as a string. if there are more routes, they must be delimted by an ';'*/
 	string framedip;		/**<The framed ip.*/
 	string framedroutes6;		/**<The framed IPv6 routes, they are stored as a string. If there are more routes, they must be delimited by an ';'*/
+	string framedip6;		/**<The framed ipv6.*/
 	string callingstationid;	/**<The calling station id, in this case the real ip addres of the client.*/
 	string key;			/**<A unique key to find the user in a map. */
         string statusfilekey;	/**<Unique identifier in the status log file (version 1) "commonname,untrusted_ip:untrusted_port"*/
@@ -87,6 +88,9 @@ public:
 	string getFramedIp(void);
 	void setFramedIp(string);
 	
+	string getFramedIp6(void);
+	void setFramedIp6(string);
+	
 	string getKey(void);
 	void setKey(string);
 
--- openvpn-auth-radius-2.1.orig/UserAuth.cpp
+++ openvpn-auth-radius-2.1/UserAuth.cpp
@@ -268,6 +268,19 @@ void UserAuth::parseResponsePacket(Radiu
     	cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: framed ipv6 route: " << this->getFramedRoutes6() <<".\n";
 	
 	
+	range=packet->findAttributes(168);
+	iter1=range.first;
+	iter2=range.second;	
+	
+	
+	if (iter1!=iter2)
+	{
+		this->setFramedIp6(iter1->second.ip6FromBuf());
+	}
+	
+	if (DEBUG (context->getVerbosity()))
+    	cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: framed IPv6: " << this->getFramedIp6() <<".\n";
+	
 	
 	range=packet->findAttributes(85);
 	iter1=range.first;
@@ -1521,7 +1534,7 @@ int UserAuth::createCcdFile(PluginContex
 	int len=0;
 	
 	
-	if(context->conf.getOverWriteCCFiles()==true && (this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || this->getFramedRoutes6().length() > 0))
+	if(context->conf.getOverWriteCCFiles()==true && (this->getFramedIp().length() > 0 || this->getFramedRoutes().length() > 0 || this->getFramedIp6().length() > 0 || this->getFramedRoutes6().length() > 0))
 	{
 		memset(ipstring,0,100);
 		memset(framedip,0,16);
@@ -1733,6 +1746,32 @@ int UserAuth::createCcdFile(PluginContex
 				}
 			}
 
+			//set the IPv6 address in the file
+			if (this->framedip6[0]!='\0')
+			{
+				if (DEBUG (context->getVerbosity()))
+					cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Write framed IPv6 to ccd-file.\n";
+			
+				//build the ifconfig
+				ipstring[0] = 0;
+				strncat(ipstring, "ifconfig-ipv6-push ",19);
+				strncat(ipstring, this->getFramedIp6().c_str() , 39);
+				strncat(ipstring, " ", 1);
+				
+				if(context->conf.getP2p6()[0]!='\0')
+				{
+					strncat(ipstring, context->conf.getP2p6() , 39);
+					if (DEBUG (context->getVerbosity()))
+						cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Create ifconfig-ipv6-push for topology p2p.\n";
+				}
+				
+				if (DEBUG (context->getVerbosity()))
+					cerr << getTime() << "RADIUS-PLUGIN: Write " << ipstring << " ccd-file.\n";
+				
+				
+				ccdfile << ipstring <<"\n";
+			}
+			
 			//set the IPv6 framed routes in the file for the openvpn process
 			if (framedroutes6[0]!='\0')
 			{
--- openvpn-auth-radius-2.1.orig/radiusplugin.cnf
+++ openvpn-auth-radius-2.1/radiusplugin.cnf
@@ -30,6 +30,9 @@ subnet=255.255.255.0
 # If you use topology option "p2p", fill in the right network, e.g. from OpenVPN option "--server NETWORK NETMASK"
 # p2p=10.8.0.1
 
+# If using Framed-IPv6-Address, fill in the gateway, e.g. from OpenVPN option "--server-ipv6 ADDRESS"
+# p2p6=fc00::1
+
 
 # Allows the plugin to overwrite the client config in client config file directory,
 # default is true
--- openvpn-auth-radius-2.1.orig/radiusplugin.cpp
+++ openvpn-auth-radius-2.1/radiusplugin.cpp
@@ -577,6 +577,7 @@ extern "C"
 					context->acctsocketbackgr.send ( newuser->getPortnumber() );
 					context->acctsocketbackgr.send ( newuser->getCallingStationId() );
 					context->acctsocketbackgr.send ( newuser->getFramedIp() );
+					context->acctsocketbackgr.send ( newuser->getFramedIp6() );
 					context->acctsocketbackgr.send ( newuser->getCommonname() );
 					context->acctsocketbackgr.send ( newuser->getAcctInterimInterval() );
 					context->acctsocketbackgr.send ( newuser->getFramedRoutes() );
@@ -1085,6 +1086,10 @@ void  * auth_user_pass_verify(void * c)
                           newuser->setFramedRoutes6 ( context->authsocketbackgr.recvStr() );
                           if ( DEBUG ( context->getVerbosity() ) )
                                   cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Received IPv6 routes for user: "<< newuser->getFramedRoutes6() << ".\n";
+                          //get the framed IPv6
+                          newuser->setFramedIp6 ( context->authsocketbackgr.recvStr() );
+                          if ( DEBUG ( context->getVerbosity() ) )
+                              cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Received framed IPv6 for user: "<< newuser->getFramedIp6() << "." << endl;
   
   
                           // get the interval from the background process
