Index: starbed_plugin/peer_setup.py
===================================================================
--- starbed_plugin/peer_setup.py	(revision 82126387b85122c8fe8dd6fe88eca30c33412209)
+++ starbed_plugin/peer_setup.py	(revision 82126387b85122c8fe8dd6fe88eca30c33412209)
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+import subprocess
+import re
+import os
+import sys, getopt
+
+class Peer:
+	@staticmethod
+	def getIP(interface):
+		proc = subprocess.Popen(['ifconfig',interface],stdout=subprocess.PIPE)
+		exit_code = os.waitpid(proc.pid, 0)
+		result = proc.communicate()[0]
+		m = re.search('inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',result)
+		if not m:
+			raise LookupError('Interface does not exist or IP is not assigned!')
+		else:
+			return m.group(1)
+	@staticmethod
+	def setIP(interface,ip):
+		proc = subprocess.Popen(['ifconfig',interface,ip,"up"],stdout=subprocess.PIPE)
+		exit_code = os.waitpid(proc.pid, 0)
+	@staticmethod
+	def setBridge(bridgename):
+		proc = subprocess.Popen(['brctl', 'addbr',bridgename],stdout=subprocess.PIPE)
+		exit_code = os.waitpid(proc.pid, 0)
+	@staticmethod
+	def addIfaceToBridge(iface,bridge):
+		proc = subprocess.Popen(['brctl','addif',bridge,iface],stdout=subprocess.PIPE)
+                exit_code = os.waitpid(proc.pid, 0)
+	@staticmethod
+	def delBridge(bridgename):
+                proc = subprocess.Popen(['brctl', 'delbr',bridgename],stdout=subprocess.PIPE)
+                exit_code = os.waitpid(proc.pid, 0)
+	@staticmethod
+	def ifUp(interface):
+		proc = subprocess.Popen(['ifconfig',interface,"up"],stdout=subprocess.PIPE)
+                exit_code = os.waitpid(proc.pid, 0)
+	#add the port and make sure you increase the tunnel number!
+	@staticmethod
+	def tunnelConnect(dest,key,bridge,iface):
+		print ['ssh','-o','Tunnel=ethernet','-f','-w','0:0','-p','22','-i',key,dest,'true']
+		proc = subprocess.call(['ssh','-o','Tunnel=ethernet','-f','-w','0:0','-p','22','-i',key,dest,'true'])
+		#Need to be fixed
+		Peer.addIfaceToBridge('tap0',bridge)
+		Peer.ifUp(iface)
+		Peer.ifUp('tap0')
+		Peer.ifUp(bridge)
+try:
+	opts, args = getopt.getopt(sys.argv[1:],"d:k:b:i:")
+	dest = None
+	key = None
+	bridge = None
+	interface = None
+	for opt, arg in opts:
+		if opt == '-d':
+			dest = arg
+		elif opt == '-k':
+			key = arg
+		elif opt == '-b':
+			bridge = arg
+		elif opt == '-i':
+			interface = arg
+	if not dest:
+		print "Missing Arguemnts! destionation"
+		sys.exit(2)
+	if not key:
+		print "Missing Arguemnts! key"
+		sys.exit(2)
+	if not bridge:
+		print "Missing Arguemnts! bridge"
+		sys.exit(2)
+	if not interface:
+		print "Missing Arguemnts! interface"
+		sys.exit(2)
+
+	Peer.tunnelConnect(dest,key,bridge,interface)
+except getopt.GetoptError:
+        #print "peer_setup.py -d=destination -k=key -b=bridge -i=interface"
+        #sys.exit(2)
+	pass
+
Index: starbed_plugin/starbed.py
===================================================================
--- starbed_plugin/starbed.py	(revision d070d9fec8fe3e2be03e9c3b009144a9e3e15d85)
+++ starbed_plugin/starbed.py	(revision 82126387b85122c8fe8dd6fe88eca30c33412209)
@@ -1,5 +1,9 @@
-#!/usr/local/bin/python
+#!/usr/bin/python
 
 import os,sys
+#temp
+import traceback 
+#
+import shutil
 import subprocess
 import signal
@@ -21,5 +25,5 @@
 from federation.proof import proof
 from topdltok import klanguage
-
+from peer_setup import Peer
 # Make log messages disappear if noone configures a fedd logger.  This is
 # something of an incantation, but basically it creates a logger object
@@ -61,7 +65,8 @@
         access_base.__init__(self, config, auth)
 
+	self.ssh_port = config.get("access","ssh_port") or "22"
+	self.domain = config.get('globals','domain')
 	#Available ports for kuma!
 	ports = config.get('globals','freeports')
-	self.domain = config.get('globals','domain')
 	try:
 		if not ports or ports.count('-') != 1:
@@ -83,4 +88,22 @@
 		self.available_ports = set(range(3456,3458))
 		self.log.warning("Setting default freeports due to missing or malformed configuration. %s" % (e))
+	#Available internal and external interfaces for the commander!
+	internal_iface = config.get('globals','internal_interfaces')
+	external_iface = config.get('globals','external_interfaces')
+	if internal_iface:
+		try:
+			self.iiface = internal_iface.split(',')
+		except BaseException as e:
+			self.log.warning('Could not retrieve internal interfaces')
+	else:
+		self.log.warning("No internal interfaces specificed in the configration!")
+	if external_iface:
+		try:
+			self.eiface = external_iface.split(',')
+		except BaseException as e:
+			selflog.warning('Could not retrive external interfaces')
+        else:
+                self.log.warning("No external interfaces specificed in the configration!")
+
 	#Get reserved ports saved in state and remove them from the available set!
 	self.state_lock.acquire()
@@ -92,4 +115,9 @@
 		elif 'ESQP' in self.state[k]:
 			self.available_ports.discard(self.state[k]['ESQP'])
+		#Get reserved interfaces in state and remove them from the available set!
+		elif 'iiface' in self.state[k]:
+			self.iiface.remove(self.state[k]['iiface'] )
+		elif 'eiface' in self.state[k]:
+			self.eiface.remove(self.state[k]['eiface'] )
 	self.state_lock.release()
 	
@@ -135,4 +163,8 @@
             'TerminateSegment': soap_handler("TerminateSegment", 
 		self.TerminateSegment),
+            'InfoSegment': soap_handler("InfoSegment", self.InfoSegment),
+            'OperationSegment': soap_handler("OperationSegment",
+		self.OperationSegment),
+
             }
         self.xmlrpc_services =  {\
@@ -144,5 +176,12 @@
             'TerminateSegment': xmlrpc_handler('TerminateSegment',
                 self.TerminateSegment),
+	    'InfoSegment': xmlrpc_handler("InfoSegment", self.InfoSegment),
+            'OperationSegment': xmlrpc_handler("OperationSegment",
+		self.OperationSegment),
             }
+
+	self.call_SetValue = service_caller('SetValue', log=self.log)
+	self.call_GetValue = service_caller('GetValue', log=self.log)
+
 	self.log.debug("Starbed AC started!")
     def RequestAccess(self, req, fid):
@@ -230,5 +269,68 @@
 		self.state_lock.release()
 		raise service_error(service_error.req, "No such allocation")
-
+    def exportInfo(self,certfile,connInfo,peer_ip):
+
+	for c in connInfo:
+		 for p in [ p for p in c.get('parameter', []) if p.get('type', '') == 'output']:
+			if p.get('name', '') == 'peer':
+				 k = p.get('key', None)
+				 surl = p.get('store', None)
+				 if surl :
+					if k and k.index('/') != -1:
+						value = peer_ip
+						#value = "%s.%s.%s" % \
+						#	(k[k.index('/')+1:], "tcarch02" , self.domain)
+					else:
+						self.log.error("Bad export request: %s" % p)
+						continue
+					self.log.debug("Setting %s to %s on %s" % \
+						(k, value, surl))
+					req = { 'name': k, 'value': value }
+					self.call_SetValue(surl, req, certfile)
+				 else:
+					self.log.error("Bad export request: %s" % p)
+			elif p.get('name', '') == 'ssh_port':
+				k = p.get('key', None)
+				surl = p.get('store', None)
+				if surl and k:
+					req = { 'name': k, 'value': self.ssh_port }
+					self.log.debug("Setting %s to %s on %s" % \
+						(k, self.ssh_port, surl))
+					self.call_SetValue(surl, req, certfile )
+				else:
+					self.log.error("Bad export request: %s" % p)
+			else:
+				self.log.error("Unknown export parameter: %s" % \
+					p.get('name'))
+				continue
+    def fetchConfiguration(self,attrs,aid,certfile,tmpdir):
+	configs = ('hosts', 'ssh_pubkey', 'ssh_secretkey')
+	pubkey_base = None
+	secretkey_base = None
+	
+	for a in attrs:
+		if a['attribute'] in configs:
+			try:
+				self.log.debug("Retrieving %s from %s to %s" % (a['attribute'], a['value'],tmpdir))
+				get_url(a['value'], certfile, tmpdir, log=self.log)
+			except:
+				t, v, st = sys.exc_info()
+				raise service_error(service_error.internal,
+					"Error retrieving %s: %s" % (a.get('value', ""), v))
+		if a['attribute'] == 'ssh_pubkey':
+			pubkey_base = a['value'].rpartition('/')[2]
+		if a['attribute'] == 'ssh_secretkey':
+			secretkey_base = a['value'].rpartition('/')[2]
+	if not pubkey_base:
+		raise service_error(service_error.req, 
+			"No public key attribute")
+	if not secretkey_base:
+		raise service_error(service_error.req, 
+			"No secret key attribute")
+	return (pubkey_base,secretkey_base)
+    def getPortalInfo(self,connInfo):
+	peer = None
+	conn_type = None
+				
     def StartSegment(self, req, fid):
         #self.log.debug("data = %s" %(req));
@@ -236,5 +338,4 @@
 	try:
 	    req = req['StartSegmentRequestBody']
-	    self.log.debug(req)
 	    # Get the request topology.  If not present, a KeyError is thrown.
 	    topref = req['segmentdescription']['topdldescription']
@@ -245,4 +346,6 @@
 	    raise service_error(server_error.req, "Badly formed request")
 
+	connInfo = req.get('connection', [])
+	attrs = req.get('fedAttr', [])
 	# String version of the allocation ID for keying
 	aid = "%s" % auth_attr
@@ -306,7 +409,52 @@
 	level, kname = tempfile.mkstemp()
 	k.to_file(kname)
-	#proc = subprocess.Popen(['/usr/local/springos/bin/kuma', '-p',self.state[aid]['passwd'],kname,'-P',str(ENCD),'-Q',str(ESQP)])
-	#pid = proc.pid
-	pid = 100000
+	
+	pubkey_base = None
+        secretkey_base = None
+        tmpdir = None
+        peer = None
+
+	if k.isPortal():
+		self.log.debug("Setting up a portal!")
+		try:	
+			#pick interface
+			self.state_lock.acquire()
+			if len(self.iiface) > 1:
+				IIFACE = random.choice([i for i in self.iiface] )
+				self.iiface.remove(IIFACE)
+				self.state[aid]['iiface'] = IIFACE
+				ip,substrate = k.getPortalInfo()
+				self.log.debug("IIFACE = %s, ip = %s" ,IIFACE,ip)
+				Peer.setIP(IIFACE,ip)
+				#set interface IP!
+                                #bridge name always have the following convention interfacenamebr
+                                Peer.setBridge("%sbr" % (IIFACE) )
+                                Peer.addIfaceToBridge(IIFACE,"%sbr" % (IIFACE) )
+
+			else: 
+				raise BaseException("No available internal interfaces!")
+			if len(self.eiface) > 1:
+				EIFACE = random.choice([i for i in self.eiface] )
+				self.eiface.remove(EIFACE)
+				self.state[aid]['eiface'] = EIFACE
+				peer_ip = Peer.getIP(EIFACE)
+			else:
+				raise BaseException("No available external interfaces!")
+			self.state_lock.release()
+                        tmpdir = tempfile.mkdtemp(prefix="access-")
+                        pubkey_base, secretkey_base = self.fetchConfiguration(attrs,aid,certfile,tmpdir)
+                        self.exportInfo(certfile,connInfo,peer_ip)
+                        self.import_store_info(certfile, connInfo)
+                        peer = connInfo[0].get('peer')
+                        con_type = connInfo[0].get('type')
+                        self.log.debug("peer = %s, type = %s, ", str(peer),con_type)
+		except BaseException as e:
+			self.state_lock.release()
+			self.log.error("Problem reteriving peer information")
+			traceback.print_exc(file=sys.stdout)	
+			raise service_error(service_error.internal, "Cannot handel peer information!")
+	proc = subprocess.Popen(['/usr/local/springos/bin/kuma', '-p',self.state[aid]['passwd'],kname,'-P',str(ENCD),'-Q',str(ESQP)])
+	pid = proc.pid
+	#pid = 100000
 	self.log.debug(['/usr/local/springos/bin/kuma', '-p',self.state[aid]['passwd'],kname,'-P',str(ENCD),'-Q',str(ESQP)])
 	#os.unlink(kname)
@@ -319,4 +467,10 @@
 	connInfo = req.get('connection', [])
 
+	proce1 = None
+	if k.isPortal():
+		try:
+			proce1 = subprocess.Popen(['./peer_setup.py','-d',peer,'-k','%s/%s'% (tmpdir,pubkey_base),'-b',"%sbr" % (IIFACE),'-i', IIFACE])
+		except:
+			self.log.warning("Could not start connection with peer!") 
 	self.state_lock.acquire()
 	# It's possible that the StartSegment call gets retried (!). 
@@ -324,4 +478,14 @@
 	# than redo the setup.  The integer allocation was saved when we made
 	# it.
+	if pubkey_base:
+		self.state[aid]['pubkey_base'] = pubkey_base
+	if secretkey_base:
+		self.state[aid]['secretkey_base'] = secretkey_base
+	if tmpdir:
+		self.state[aid]['tmpdir'] = tmpdir
+	if peer:
+		self.state[aid]['peer'] = peer
+	if proce1:
+		self.state[aid]['ssh_pid'] = proce1.pid
 	self.state[aid]['pid'] = pid
 	self.state[aid]['descfile'] = kname
@@ -376,7 +540,13 @@
 		except OSError as ex:
 			self.log.warning("Cannot kill process %s " % (pid))
+	    if 'ssh_pid' in self.state[aid]:
+		try:
+			os.kill(int(self.state[aid]['ssh_pid'] ) )
+			os.wait()
+		except OSError as ex:
+			self.log.warning("Cannot kill process") 
 	    descfile = self.state[aid].get('descfile',None)
 	    if descfile:
-	    	#os.unlink(descfile)
+	    	os.unlink(descfile)
 		del self.state[aid]['descfile']
 	    if 'ENCD' in self.state[aid]:
@@ -385,4 +555,25 @@
                 del self.state[aid]['ESQP']
 	    del self.state[aid]['started']
+
+	    if 'eiface' in self.state[aid]:
+		del self.state[aid]['eiface']
+	    if 'iiface' in self.state[aid]:
+		try:
+			Peer.delBridge("%sbr" % self.state[aid]['iiface'] )
+		except:
+			self.log.warning("Problem removing bridge %sbr" % self.state[aid]['eiface'] )
+		del self.state[aid]['iiface']
+            if 'pubkey_base' in self.state[aid]:
+		del self.state[aid]['pubkey_base']
+            if 'secretkey_base' in self.state[aid]:
+		del self.state[aid]['secretkey_base']
+            if 'tmpdir' in self.state[aid]:
+		try:	
+			shutil.rmtree(self.state[aid]['tmpdir'])
+		except  OSError as e:
+			self.log.warning("Problem removing directory %s" % (self.state[aid]['tmpdir'] ))
+		del self.state[aid]['tmpdir']
+	    if 'peer' in self.state[aid]:
+		del self.state[aid]['peer']
 	    self.write_state()
 	self.state_lock.release()
@@ -392,2 +583,5 @@
 	self.log.info("InfoSegment called by %s" % fid)
 
+    def OperationSegment(self, req, fid):
+	self.log.info("OperationSegment called by %s" % (fid) ) 
+	self.log.debug("req = %s " % req )
Index: starbed_plugin/topdltok.py
===================================================================
--- starbed_plugin/topdltok.py	(revision d070d9fec8fe3e2be03e9c3b009144a9e3e15d85)
+++ starbed_plugin/topdltok.py	(revision 82126387b85122c8fe8dd6fe88eca30c33412209)
@@ -44,4 +44,14 @@
 		self.sparenoderatio = sparenoderatio
 		self.gut = ""
+		#WE handle portal configuration manually since we do it in the commander!
+		self.portal_iip = None
+		self.portal_substrate = None
+	def isPortal(self):
+		if self.portal_iip and self.portal_substrate:
+			return True
+		else:
+			return False
+	def getPortalInfo(self):
+		return (self.portal_iip,self.portal_substrate)
 	def to_file(self,name):
 		f = open(name, 'w+')
@@ -99,5 +109,10 @@
 				nodedef = nodedef + "}\n"
 				nodeinst = nodeinst + "nodeset %s class %sclass num 1\n" % (name,name)
-
+			elif isinstance(elt, topdl.Computer) and elt.get_attribute('portal') == 'true':
+				for iface in elt.interface:
+					#We need a portal! we handle outside kuma!
+					if not iface.get_attribute('portal'):
+						self.portal_iip = str(iface.get_attribute('ip4_address'))
+						self.portal_substrate = str(iface.substrate[0])
 		#This should be replaced to specificlly define each LAN when required!
 		lanclass = "ethernet"
