[tor-commits] [flashproxy/master] New RTMFP relay started in Proxy.as, building relay system for Tor client and patsy proxy

dcf at torproject.org dcf at torproject.org
Sun Jun 12 08:56:27 UTC 2011


commit 3f5a036ef65d488d575c3ec8e3a8a3f7b7e69f6e
Author: Nate Hardison <nate at rescomp-09-154551.stanford.edu>
Date:   Wed May 4 16:28:34 2011 -0700

    New RTMFP relay started in Proxy.as, building relay system for Tor client and patsy proxy
---
 Connector.as  |   52 +++++++++++
 Makefile      |    2 +-
 Proxy.as      |  261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 RTMFPRelay.as |  272 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 586 insertions(+), 1 deletions(-)

diff --git a/Connector.as b/Connector.as
new file mode 100644
index 0000000..f362dd3
--- /dev/null
+++ b/Connector.as
@@ -0,0 +1,52 @@
+package
+{
+    import flash.display.Sprite;
+    import flash.text.TextField;
+    import flash.net.Socket;
+    import flash.events.Event;
+    import flash.events.EventDispatcher;
+    import flash.events.IOErrorEvent;
+    import flash.events.NetStatusEvent;
+    import flash.events.ProgressEvent;
+    import flash.events.SecurityErrorEvent;
+    import flash.net.NetConnection;
+    import flash.net.NetStream;
+    import flash.utils.ByteArray;
+    import flash.utils.clearInterval;
+    import flash.utils.setInterval;
+    import flash.utils.setTimeout;
+    
+    public class Connector extends RTMFPRelay {
+      
+      private var output_text:TextField;
+      
+      private var fac_addr:Object;
+      private var tor_addr:Object;
+      
+      public function Connector() {
+        output_text = new TextField();
+        output_text.width = 400;
+        output_text.height = 300;
+        output_text.background = true;
+        output_text.backgroundColor = 0x001f0f;
+        output_text.textColor = 0x44CC44;
+        addChild(output_text);
+
+        puts("Starting.");
+        // Wait until the query string parameters are loaded.
+        this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
+      }
+      
+      
+      private function loaderinfo_complete(e:Event):void
+      {
+        var fac_spec:String;
+        var tor_spec:String;
+
+        puts("Parameters loaded.");
+        
+        
+      }
+    
+}
+    
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 27ba9d8..6f03eb6 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ TARGETS = swfcat.swf
 all: $(TARGETS)
 
 %.swf: %.as
-	$(MXMLC) -output $@ $^
+	$(MXMLC) -output $@ -define=RTMFP::CIRRUS_KEY,\"$(CIRRUS_KEY)\" $^
 
 clean:
 	rm -f $(TARGETS)
diff --git a/Proxy.as b/Proxy.as
new file mode 100644
index 0000000..01b2fe3
--- /dev/null
+++ b/Proxy.as
@@ -0,0 +1,261 @@
+package
+{
+    import flash.display.Sprite;
+    import flash.text.TextField;
+    import flash.net.Socket;
+    import flash.events.Event;
+    import flash.events.EventDispatcher;
+    import flash.events.IOErrorEvent;
+    import flash.events.NetStatusEvent;
+    import flash.events.ProgressEvent;
+    import flash.events.SecurityErrorEvent;
+    import flash.net.NetConnection;
+    import flash.net.NetStream;
+    import flash.utils.ByteArray;
+    import flash.utils.clearInterval;
+    import flash.utils.setInterval;
+    import flash.utils.setTimeout;
+
+    public class Proxy extends Sprite
+    {
+        /* David's relay (nickname 3VXRyxz67OeRoqHn) that also serves a
+           crossdomain policy. */
+        private const DEFAULT_TOR_ADDR:Object = {
+            host: "173.255.221.44",
+            port: 9001
+        };
+
+		    /* Address of the Cirrus rendezvous service with Nate's
+		       developer key appended */
+		    private static const CIRRUS_ADDRESS:String = "rtmfp://p2p.rtmfp.net/" + RTMFP::CIRRUS_KEY + "/";
+		
+        // The name of our data stream
+        public static const DATA:String = "data";
+		
+        private var output_text:TextField;
+
+        // Socket to Tor relay.
+        private var s_t:Socket;
+        // Socket to facilitator.
+        private var s_f:Socket;
+
+        /* Connection to the Cirrus rendezvous service that will hook
+           us up with the Tor client */
+        public var cirrus:NetConnection;
+		
+		    // The Tor client's peerID (used when establishing the client_stream)
+		    private var client_id:String;
+		
+		    // The data streams to be established with the Tor client
+		    public var send_stream:NetStream;
+		    public var recv_stream:NetStream;
+
+        private var fac_addr:Object;
+        private var tor_addr:Object;
+
+        private function puts(s:String):void
+        {
+            output_text.appendText(s + "\n");
+            output_text.scrollV = output_text.maxScrollV;
+        }
+
+        public function Proxy()
+        {
+            output_text = new TextField();
+            output_text.width = 400;
+            output_text.height = 300;
+            output_text.background = true;
+            output_text.backgroundColor = 0x001f0f;
+            output_text.textColor = 0x44CC44;
+            addChild(output_text);
+
+            puts("Starting.");
+            // Wait until the query string parameters are loaded.
+            this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
+        }
+
+        private function loaderinfo_complete(e:Event):void
+        {
+            var fac_spec:String;
+            var tor_spec:String;
+
+            puts("Parameters loaded.");
+            fac_spec = this.loaderInfo.parameters["facilitator"];
+            if (!fac_spec) {
+                puts("Error: no \"facilitator\" specification provided.");
+                return;
+            }
+            puts("Facilitator spec: \"" + fac_spec + "\"");
+            fac_addr = parse_addr_spec(fac_spec);
+            if (!fac_addr) {
+                puts("Error: Facilitator spec must be in the form \"host:port\".");
+                return;
+            }
+
+            tor_addr = DEFAULT_TOR_ADDR;
+
+            go();
+        }
+
+        /* We connect first to the Tor relay; once that happens we connect to
+           the facilitator to get a client address; once we have the address
+           of a waiting client then we connect to the client and BAM! we're in business. */
+        private function go():void
+        {
+            s_t = new Socket();
+
+            s_t.addEventListener(Event.CONNECT, tor_connected);
+            s_t.addEventListener(Event.CLOSE, function (e:Event):void {
+                puts("Tor: closed.");
+            });
+            s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+                puts("Tor: I/O error: " + e.text + ".");
+            });
+            s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+                puts("Tor: security error: " + e.text + ".");
+
+            });
+
+            puts("Tor: connecting to " + tor_addr.host + ":" + tor_addr.port + ".");
+            s_t.connect(tor_addr.host, tor_addr.port);
+        }
+
+        private function tor_connected(e:Event):void
+        {
+            /* Got a connection to tor, now let's get served a client from the facilitator */
+            s_f = new Socket();
+
+            puts("Tor: connected.");
+            s_f.addEventListener(Event.CONNECT, fac_connected);
+            s_f.addEventListener(Event.CLOSE, function (e:Event):void {
+                puts("Facilitator: closed connection.");
+            });
+            s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+                puts("Facilitator: I/O error: " + e.text + ".");
+                if (s_t.connected)
+                    s_t.close();
+            });
+            s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+                puts("Facilitator: security error: " + e.text + ".");
+                if (s_t.connected)
+                    s_t.close();
+            });
+
+            puts("Facilitator: connecting to " + fac_addr.host + ":" + fac_addr.port + ".");
+            s_f.connect(fac_addr.host, fac_addr.port);
+        }
+
+        private function fac_connected(e:Event):void
+        {
+            puts("Facilitator: connected.");
+
+            s_f.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+              var client_spec:String;
+              var client_addr:Object;
+
+              client_spec = s_f.readMultiByte(e.bytesLoaded, "utf-8");
+              puts("Facilitator: got \"" + client_spec + "\"");
+
+              /*client_addr = parse_addr_spec(client_spec);
+              if (!client_addr) {
+                puts("Error: Client spec must be in the form \"host:port\".");
+                return;
+              }
+              if (client_addr.host == "0.0.0.0" && client_addr.port == 0) {
+                puts("Error: Facilitator has no clients.");
+                return;
+              }*/
+
+				      /* Now we have a client, so start up a connection to the Cirrus rendezvous point */
+				      cirrus = new NetConnection();
+				      cirrus.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+				      cirrus.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+					      if (s_t.connected) s_t.close();
+					      if (s_f.connected) s_f.close();
+				      });
+				
+				      cirrus.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityError):void {
+					      if (s_t.connected) s_t.close();
+					      if (s_f.connected) s_f.close();
+				      });
+				
+				      cirrus.connect(CIRRUS_ADDRESS);
+            });
+
+            s_f.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
+        }
+		
+		private function net_status_event_handler(e:NetStatusEvent):void
+		{
+			switch (e.info.code) {
+				case "NetConnection.Connect.Success" :
+					// Cirrus is now connected
+					cirrus_connected(e);
+			}
+			
+		}
+		
+		private function cirrus_connected(e:Event):void
+		{
+			if (client_id == null) {
+				puts("Error: Client ID doesn't exist.");
+				return;
+			} else if (client_id == cirrus.nearID) {
+				puts("Error: Client ID is our ID.");
+				return;
+			}
+					
+			send_stream = new NetStream(cirrus, NetStream.DIRECT_CONNECTIONS);
+			send_stream.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+			send_stream.publish(DATA);
+			
+			recv_stream = new NetStream(cirrus, client_id);
+			recv_stream.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+			recv_stream.play(DATA);
+		}
+
+        /*private function client_connected(e:Event):void
+        {
+            puts("Client: connected.");
+
+            s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+                var bytes:ByteArray = new ByteArray();
+                s_t.readBytes(bytes, 0, e.bytesLoaded);
+                puts("Tor: read " + bytes.length + ".");
+                s_c.writeBytes(bytes);
+            });
+            s_c.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+                var bytes:ByteArray = new ByteArray();
+                s_c.readBytes(bytes, 0, e.bytesLoaded);
+                puts("Client: read " + bytes.length + ".");
+                s_t.writeBytes(bytes);
+            });
+        }*/
+		
+		private function close_connections():void
+		{
+			if (s_t.connected) s_t.close();
+			if (s_f.connected) s_f.close();
+			if (cirrus.connected) cirrus.close();
+			if (send_stream != null) send_stream.close();
+			if (recv_stream != null) recv_stream.close();
+		}
+
+        /* Parse an address in the form "host:port". Returns an Object with
+           keys "host" (String) and "port" (int). Returns null on error. */
+        private static function parse_addr_spec(spec:String):Object
+        {
+            var parts:Array;
+            var addr:Object;
+
+            parts = spec.split(":", 2);
+            if (parts.length != 2 || !parseInt(parts[1]))
+                return null;
+            addr = {}
+            addr.host = parts[0];
+            addr.port = parseInt(parts[1]);
+
+            return addr;
+        }
+    }
+}
diff --git a/RTMFPRelay.as b/RTMFPRelay.as
new file mode 100644
index 0000000..27b3208
--- /dev/null
+++ b/RTMFPRelay.as
@@ -0,0 +1,272 @@
+package
+{
+    import flash.display.Sprite;
+    import flash.text.TextField;
+    import flash.net.Socket;
+    import flash.events.Event;
+    import flash.events.EventDispatcher;
+    import flash.events.IOErrorEvent;
+    import flash.events.NetStatusEvent;
+    import flash.events.ProgressEvent;
+    import flash.events.SecurityErrorEvent;
+    import flash.net.NetConnection;
+    import flash.net.NetStream;
+    import flash.utils.ByteArray;
+    import flash.utils.clearInterval;
+    import flash.utils.setInterval;
+    import flash.utils.setTimeout;
+    
+    import Utils;
+
+    public class RTMFPRelay extends Sprite
+    {
+		    private static const CIRRUS_ADDRESS:String = "rtmfp://p2p.rtmfp.net";
+		    private static const CIRRUS_DEV_KEY:String = RTMFP::CIRRUS_KEY;
+		
+        /* The name of the "media" to pass between peers */
+        public static const DATA:String = "data";
+		
+        protected var output_text:TextField;
+
+        // Socket to Tor relay.
+        private var s_t:Socket;
+        // Socket to facilitator.
+        private var s_f:Socket;
+
+        /* Connection to the Cirrus rendezvous service */
+        private var cirrus_conn:NetConnection;
+		
+		    /* ID of the peer to connect to */
+		    private var peer_id:String;
+		
+		    /* Data streams to be established with peer */
+		    private var send_stream:NetStream;
+		    private var recv_stream:NetStream;
+
+        private var fac_addr:Object;
+        private var tor_addr:Object;
+
+        private function puts(s:String):void
+        {
+            output_text.appendText(s + "\n");
+            output_text.scrollV = output_text.maxScrollV;
+        }
+
+        public function RTMFPRelay()
+        {
+            output_text = new TextField();
+            output_text.width = 400;
+            output_text.height = 300;
+            output_text.background = true;
+            output_text.backgroundColor = 0x001f0f;
+            output_text.textColor = 0x44CC44;
+            addChild(output_text);
+
+            puts("Starting.");
+            
+            cirrus_conn = new NetConnection();
+			      cirrus_conn.addEventListener(NetStatusEvent.NET_STATUS, function (e:NetStatusEvent):void {
+			        puts("Cirrus: connected.");
+			      });
+			      cirrus_conn.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+				      puts("Cirrus: I/O error: " + e.text + ".");
+			      });
+			
+			      cirrus_conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityError):void {
+				      puts("Cirrus: security error: " + e.text + ".");
+			      });
+			
+			      cirrus_conn.connect(CIRRUS_ADDRESS + "/" + CIRRUS_DEV_KEY);
+            
+            
+            // Wait until the query string parameters are loaded.
+            this.loaderInfo.addEventListener(Event.COMPLETE, loaderinfo_complete);
+        }
+
+        public function data_is(data:ByteArray):void
+        {
+          
+          
+        }
+        
+        public function facilitator_is(host:String, port:String):void
+        {
+          if (s_f != null && s_f.connected) {
+            
+            return;
+          }
+          
+          s_f = new Socket();
+          
+          s_f.addEventListener(Event.CONNECT, function (e:Event):void {
+            puts("Facilitator: connected.");
+          });
+          s_f.addEventListener(Event.CLOSE, function (e:Event):void {
+            puts("Facilitator: closed connection.");
+          });
+          s_f.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+            puts("Facilitator: I/O error: " + e.text + ".");
+          });
+          s_f.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+            puts("Facilitator: security error: " + e.text + ".");
+          });
+
+          puts("Facilitator: connecting to " + host + ":" + port + ".");
+          s_f.connect(host, port);
+        }
+        
+        public function peer(peer_id:String):String
+        {
+          return this.peer_id;
+        }
+
+        public function peer_is(peer_id:String):void
+        {
+          if (peer_id == null) {
+    				puts("Error: Client ID doesn't exist.");
+    				return;
+    			} else if (peer_id == cirrus_conn.nearID) {
+    				puts("Error: Client ID is our ID.");
+    				return;
+    			} else if (this.peer_id == peer_id) {
+    			  
+    			} else if (this.recv_stream != null) {
+            puts("Error: already set up with a peer!");
+            return;
+          }
+          
+          this.peer_id = peer_id;
+          
+          send_stream = new NetStream(cirrus_conn, NetStream.DIRECT_CONNECTIONS);
+    			send_stream.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+    			send_stream.publish(DATA);
+
+    			recv_stream = new NetStream(cirrus_conn, peer_id);
+    			recv_stream.addEventListener(NetStatusEvent.NET_STATUS, net_status_event_handler);
+    			recv_stream.play(DATA);
+        }
+        
+        public function tor_relay_is(host:String, port:String):void
+        {
+          if (s_t != null && s_t.connected) {
+            puts("Error: already connected to Tor relay!");
+            return;
+          }
+          
+          s_t = new Socket();
+
+          s_t.addEventListener(Event.CONNECT, function (e:Event):void {
+            puts("Tor: connected.");
+          });
+          s_t.addEventListener(Event.CLOSE, function (e:Event):void {
+            puts("Tor: closed.");
+          });
+          s_t.addEventListener(IOErrorEvent.IO_ERROR, function (e:IOErrorEvent):void {
+            puts("Tor: I/O error: " + e.text + ".");
+          });
+          s_t.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (e:SecurityErrorEvent):void {
+            puts("Tor: security error: " + e.text + ".");
+          });
+
+          puts("Tor: connecting to " + host + ":" + port + ".");
+          s_t.connect(host, port);
+        }
+
+        private function loaderinfo_complete(e:Event):void
+        {
+            var fac_spec:String;
+            var tor_spec:String;
+
+            puts("Parameters loaded.");
+            fac_spec = this.loaderInfo.parameters["facilitator"];
+            if (!fac_spec) {
+                puts("Error: no \"facilitator\" specification provided.");
+                return;
+            }
+            puts("Facilitator spec: \"" + fac_spec + "\"");
+            fac_addr = parse_addr_spec(fac_spec);
+            if (!fac_addr) {
+                puts("Error: Facilitator spec must be in the form \"host:port\".");
+                return;
+            }
+
+            tor_addr = DEFAULT_TOR_ADDR;
+
+            go();
+        }
+
+        private function fac_connected(e:Event):void
+        {
+            
+
+            s_f.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+              var client_spec:String;
+              var client_addr:Object;
+
+              client_spec = s_f.readMultiByte(e.bytesLoaded, "utf-8");
+              puts("Facilitator: got \"" + client_spec + "\"");
+
+              /*client_addr = parse_addr_spec(client_spec);
+              if (!client_addr) {
+                puts("Error: Client spec must be in the form \"host:port\".");
+                return;
+              }
+              if (client_addr.host == "0.0.0.0" && client_addr.port == 0) {
+                puts("Error: Facilitator has no clients.");
+                return;
+              }*/
+
+				      /* Now we have a client, so start up a connection to the Cirrus rendezvous point */
+				      
+            });
+
+            s_f.writeUTFBytes("GET / HTTP/1.0\r\n\r\n");
+        }
+		
+		private function net_status_event_handler(e:NetStatusEvent):void
+		{
+			switch (e.info.code) {
+				case "NetConnection.Connect.Success" :
+					// Cirrus is now connected
+					cirrus_connected(e);
+			}
+			
+		}
+		
+		private function cirrus_connected(e:Event):void
+		{
+			
+					
+			
+		}
+
+        /*private function client_connected(e:Event):void
+        {
+            puts("Client: connected.");
+
+            s_t.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+                var bytes:ByteArray = new ByteArray();
+                s_t.readBytes(bytes, 0, e.bytesLoaded);
+                puts("Tor: read " + bytes.length + ".");
+                s_c.writeBytes(bytes);
+            });
+            s_c.addEventListener(ProgressEvent.SOCKET_DATA, function (e:ProgressEvent):void {
+                var bytes:ByteArray = new ByteArray();
+                s_c.readBytes(bytes, 0, e.bytesLoaded);
+                puts("Client: read " + bytes.length + ".");
+                s_t.writeBytes(bytes);
+            });
+        }*/
+		
+		private function close_connections():void
+		{
+			if (s_t.connected) s_t.close();
+			if (s_f.connected) s_f.close();
+			if (cirrus.connected) cirrus.close();
+			if (send_stream != null) send_stream.close();
+			if (recv_stream != null) recv_stream.close();
+		}
+
+        
+    }
+}





More information about the tor-commits mailing list