Index: fedd/federation/desktop_access.py
===================================================================
--- fedd/federation/desktop_access.py	(revision 1819839108ac5632f486ff98fb7822ef3b2b57f1)
+++ fedd/federation/desktop_access.py	(revision 2dc99e350dfcc464b8c29c6b6b0981c27480f77a)
@@ -138,5 +138,61 @@
 	self.call_GetValue = service_caller('GetValue', log=self.log)
 
-    # RequestAccess and ReleaseAccess come from the base class
+    # ReleaseAccess come from the base class, this is a slightly modified
+    # RequestAccess from the base that includes a fedAttr to force this side to
+    # be active.
+    def RequestAccess(self, req, fid):
+        """
+	Handle an access request.  Success here maps the requester into the
+	local access control space and establishes state about that user keyed
+	to a fedid.  We also save a copy of the certificate underlying that
+	fedid so this allocation can access configuration information and
+	shared parameters on the experiment controller.
+        """
+
+	self.log.info("RequestAccess called by %s" % fid)
+        # The dance to get into the request body
+        if req.has_key('RequestAccessRequestBody'):
+            req = req['RequestAccessRequestBody']
+        else:
+            raise service_error(service_error.req, "No request!?")
+
+	# Base class lookup routine.  If this fails, it throws a service
+	# exception denying access that triggers a fault response back to the
+	# caller.
+	found,  owners, proof = self.lookup_access(req, fid)
+	self.log.info(
+		"[RequestAccess] Access granted local creds %s" % found)
+	# Make a fedid for this allocation
+	allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log)
+	aid = unicode(allocID)
+
+	# Store the data about this allocation: 
+	self.state_lock.acquire()
+	self.state[aid] = { }
+	self.state[aid]['user'] = found
+	self.state[aid]['owners'] = owners
+	self.state[aid]['auth'] = set()
+	# Authorize the creating fedid and the principal representing the
+	# allocation to manipulate it.
+	self.append_allocation_authorization(aid, 
+		((fid, allocID), (allocID, allocID)))
+	self.write_state()
+	self.state_lock.release()
+
+	# Create a directory to stash the certificate in, ans stash it.
+	try:
+	    f = open("%s/%s.pem" % (self.certdir, aid), "w")
+	    print >>f, alloc_cert
+	    f.close()
+	except EnvironmentError, e:
+	    raise service_error(service_error.internal, 
+		    "Can't open %s/%s : %s" % (self.certdir, aid, e))
+	self.log.debug('[RequestAccess] Returning allocation ID: %s' % allocID)
+	msg = { 
+		'allocID': { 'fedid': allocID }, 
+		'fedAttr': [{ 'attribute': 'nat_portals', 'value': 'True' }],
+		'proof': proof.to_dict()
+		}
+	return msg
 
     def validate_topology(self, top):
@@ -241,4 +297,34 @@
 	    print >>script, 'sudo ip route delete %s' % dest
 
+    def find_a_peer(self, addr): 
+	'''
+	Find another node in the experiment that's on our subnet.  This is a
+	hack to handle the problem that we really cannot require the desktop to
+	dynamically route.  Will be improved by distributing static routes.
+	'''
+
+	peer = None
+	hosts = os.path.join(self.localdir, 'hosts')
+	p = addr.rfind('.')
+	if p == -1:
+	    raise service_error(service_error.req, 'bad address in topology')
+	prefix = addr[0:p]
+	addr_re = re.compile('(%s.\\d+)' % prefix)
+	try:
+	    f = open(hosts, 'r')
+	    for line in f:
+		m = addr_re.search(line)
+		if m is not None and m.group(1) != addr:
+		    peer = m.group(1)
+		    break
+	    else:
+		raise service_error(service_error.req, 
+			'No other nodes in this subnet??')
+	except EnvironmentError, e:
+	    raise service_error(service_error.internal, 
+		    'Cannot open %s: %s' % (e.filename, e.strerror))
+	return peer
+
+
 
 
@@ -278,4 +364,6 @@
 		    'Cannot find all config parameters %s %s %s' % (peer, port, my_addr))
 
+	exp_peer = self.find_a_peer(my_addr)
+
 	cscript = os.path.join(self.localdir, 'connect')
 	dscript = os.path.join(self.localdir, 'disconnect')
@@ -289,9 +377,9 @@
 	    # a file this end can access into its local file system.  Try once
 	    # a minute.
-	    print >>f,'while !/usr/bin/scp -i "StrictHostKeyChecking no" -i %s %s:/usr/local/federation/etc/prep_done /dev/null; do' % (self.ssh_identity, peer)
+	    print >>f,'while ! /usr/bin/scp -o "StrictHostKeyChecking no" -i %s %s:/usr/local/federation/etc/prep_done /dev/null; do' % (self.ssh_identity, peer)
 	    print >>f, 'sleep 60; done'
 	    print >>f, ('sudo ssh -w 0:0 -p %s -o "Tunnel ethernet" ' + \
-		    '-o "StrictHostKeyChecking no" -i %s -N %s &') % \
-		    (port, self.ssh_identity, peer)
+		    '-o "StrictHostKeyChecking no" -i %s %s perl -I/usr/local/federation/lib /usr/local/federation/bin/setup_bridge.pl --tapno=0 --addr=%s &') % \
+		    (port, self.ssh_identity, peer, my_addr)
 	    # This should give the tap a a chance to come up
 	    print >>f,'sleep 10'
@@ -299,5 +387,5 @@
 	    print >>f, 'sudo ifconfig tap0 %s netmask 255.255.255.0 up' % \
 		    my_addr
-	    self.set_route('10.0.0.0/8', f, peer)
+	    self.set_route('10.0.0.0/8', f, exp_peer)
 	    f.close()
 	    os.chmod(cscript, 0755)
