Esempio n. 1
1
// Handles a new http connection from the public internet
func httpHandler(tcpConn net.Conn, proto string) {
	// wrap up the connection for logging
	conn := conn.NewHttp(tcpConn, "pub")

	defer conn.Close()
	defer func() {
		// recover from failures
		if r := recover(); r != nil {
			conn.Warn("httpHandler failed with error %v", r)
		}
	}()

	// Make sure we detect dead connections while we decide how to multiplex
	conn.SetDeadline(time.Now().Add(connReadTimeout))

	// read out the http request
	req, err := conn.ReadRequest()
	if err != nil {
		conn.Warn("Failed to read valid %s request: %v", proto, err)
		conn.Write([]byte(BadRequest))
		return
	}

	// read out the Host header from the request
	host := strings.ToLower(req.Host)
	conn.Debug("Found hostname %s in request", host)

	// multiplex to find the right backend host
	tunnel := tunnelRegistry.Get(fmt.Sprintf("%s://%s", proto, host))
	if tunnel == nil {
		conn.Info("No tunnel found for hostname %s", host)
		conn.Write([]byte(fmt.Sprintf(NotFound, len(host)+18, host)))
		return
	}

	// If the client specified http auth and it doesn't match this request's auth
	// then fail the request with 401 Not Authorized and request the client reissue the
	// request with basic authdeny the request
	if tunnel.req.HttpAuth != "" && req.Header.Get("Authorization") != tunnel.req.HttpAuth {
		conn.Info("Authentication failed: %s", req.Header.Get("Authorization"))
		conn.Write([]byte(NotAuthorized))
		return
	}

	// dead connections will now be handled by tunnel heartbeating and the client
	conn.SetDeadline(time.Time{})

	// let the tunnel handle the connection now
	tunnel.HandlePublicConnection(conn)
}
Esempio n. 2
0
/**
 * Handles a new http connection from the public internet
 */
func httpHandler(tcpConn net.Conn) {
	// wrap up the connection for logging
	conn := conn.NewHttp(tcpConn, "pub")

	defer conn.Close()
	defer func() {
		// recover from failures
		if r := recover(); r != nil {
			conn.Warn("httpHandler failed with error %v", r)
		}
	}()

	// read out the http request
	req, err := conn.ReadRequest()
	if err != nil {
		conn.Warn("Failed to read valid http request: %v", err)
		conn.Write([]byte(BadRequest))
		return
	}

	// read out the Host header from the request
	host := strings.ToLower(req.Host)
	conn.Debug("Found hostname %s in request", host)

	// multiplex to find the right backend host
	tunnel := tunnels.Get("http://" + host)
	if tunnel == nil {
		conn.Info("No tunnel found for hostname %s", host)
		conn.Write([]byte(fmt.Sprintf(NotFound, len(host)+18, host)))
		return
	}

	// If the client specified http auth and it doesn't match this request's auth
	// then fail the request with 401 Not Authorized and request the client reissue the
	// request with basic authdeny the request
	if tunnel.regMsg.HttpAuth != "" && req.Header.Get("Authorization") != tunnel.regMsg.HttpAuth {
		conn.Info("Authentication failed: %s", req.Header.Get("Authorization"))
		conn.Write([]byte(NotAuthorized))
		return
	}

	tunnel.HandlePublicConnection(conn)
}
Esempio n. 3
0
/**
 * Handles a new http connection from the public internet
 */
func httpHandler(tcpConn net.Conn) {
	// wrap up the connection for logging
	conn := conn.NewHttp(tcpConn, "pub")

	defer conn.Close()
	defer func() {
		// recover from failures
		if r := recover(); r != nil {
			conn.Warn("httpHandler failed with error %v", r)
		}
	}()

	// read out the http request
	req, err := conn.ReadRequest()
	if err != nil {
		conn.Warn("Failed to read valid http request: %v", err)
		conn.Write([]byte(BadRequest))
		return
	}

	// multiplex to find the right backend host
	conn.Debug("Found hostname %s in request", req.Host)
	tunnel := tunnels.Get("http://" + req.Host)
	if tunnel == nil {
		conn.Info("No tunnel found for hostname %s", req.Host)
		conn.Write([]byte(fmt.Sprintf(NotFound, len(req.Host)+18, req.Host)))
		return
	}

	// satisfy auth, if necessary
	conn.Debug("From client: %s", req.Header.Get("Authorization"))
	conn.Debug("To match: %s", tunnel.regMsg.HttpAuth)
	if req.Header.Get("Authorization") != tunnel.regMsg.HttpAuth {
		conn.Info("Authentication failed")
		conn.Write([]byte(NotAuthorized))
		return
	}

	tunnel.HandlePublicConnection(conn)
}
Esempio n. 4
0
/**
 * Listens for new proxy connections from tunnel clients
 */
func proxyListener(addr *net.TCPAddr, domain string) {
	listener, err := conn.Listen(addr, "pxy", tls.Config)
	if err != nil {
		panic(err)
	}

	// set global proxy addr variable
	proxyAddr = fmt.Sprintf("%s:%d", domain, listener.Port)
	log.Info("Listening for proxy connection on %d", listener.Port)
	for proxyConn := range listener.Conns {
		go func(conn conn.Conn) {
			// fail gracefully if the proxy connection dies
			defer func() {
				if r := recover(); r != nil {
					conn.Warn("Failed with error: %v", r)
					conn.Close()
				}
			}()

			// read the proxy register message
			var regPxy msg.RegProxyMsg
			if err = msg.ReadMsgInto(conn, &regPxy); err != nil {
				panic(err)
			}

			// look up the tunnel for this proxy
			conn.Info("Registering new proxy for %s", regPxy.Url)
			tunnel := tunnels.Get(regPxy.Url)
			if tunnel == nil {
				panic("No tunnel found for: " + regPxy.Url)
			}

			// register the proxy connection with the tunnel
			tunnel.RegisterProxy(conn)
		}(proxyConn)
	}
}