Example #1
0
func (selector *serverSelector) OnSelected(method uint8, conn net.Conn) (net.Conn, error) {
	glog.V(LDEBUG).Infof("%d %d", gosocks5.Ver5, method)

	switch method {
	case MethodTLS:
		conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{selector.arg.Cert}})

	case gosocks5.MethodUserPass, MethodTLSAuth:
		if method == MethodTLSAuth {
			conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{selector.arg.Cert}})
		}

		req, err := gosocks5.ReadUserPassRequest(conn)
		if err != nil {
			glog.V(LWARNING).Infoln("socks5 auth:", err)
			return nil, err
		}
		glog.V(LDEBUG).Infoln(req.String())

		var username, password string
		if selector.arg.User != nil {
			username = selector.arg.User.Username()
			password, _ = selector.arg.User.Password()
		}

		if (username != "" && req.Username != username) || (password != "" && req.Password != password) {
			resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Failure)
			if err := resp.Write(conn); err != nil {
				glog.V(LWARNING).Infoln("socks5 auth:", err)
				return nil, err
			}
			glog.V(LDEBUG).Infoln(resp)
			glog.V(LWARNING).Infoln("socks5: proxy authentication required")

			return nil, gosocks5.ErrAuthFailure
		}

		resp := gosocks5.NewUserPassResponse(gosocks5.UserPassVer, gosocks5.Succeeded)
		if err := resp.Write(conn); err != nil {
			glog.V(LWARNING).Infoln("socks5 auth:", err)
			return nil, err
		}
		glog.V(LDEBUG).Infoln(resp)

	case gosocks5.MethodNoAcceptable:
		return nil, gosocks5.ErrBadMethod
	}

	return conn, nil
}
Example #2
0
func (s *Server) proxyConnection(c net.Conn, front *Frontend) (err error) {
	// unwrap if tls cert/key was specified
	if front.TlsConfig != nil {
		c = tls.Server(c, front.TlsConfig)
	}

	// pick the backend
	backend := front.strategy.NextBackend()

	if s.Interceptor != nil {
		backend = *s.Interceptor(c, front, &backend)
	}

	// dial the backend
	upConn, err := net.DialTimeout("tcp", backend.Addr+":"+s.ListenerConfig.BindPort, time.Duration(backend.ConnectTimeout)*time.Millisecond)
	if err != nil {
		s.Printf("Failed to dial backend connection %v: %v", backend.Addr, err)
		c.Close()
		return
	}
	s.Printf("Initiated new connection to backend: %v %v", upConn.LocalAddr(), upConn.RemoteAddr())

	// join the connections
	totalBytes := s.joinConnections(c, upConn)
	s.TrafCounter.Count(backend.Addr, c.RemoteAddr(), totalBytes)
	return
}
Example #3
0
func (y *yamuxer) listen(ctx context.Context) {
	defer y.listener.Close()
OUTER:
	for {

		// Accepts will only block for 1s
		y.listener.SetDeadline(time.Now().Add(y.deadline))

		select {

		// Stop server on channel receive
		case <-ctx.Done():
			break OUTER
		default:

			// Accept new connection
			tcpConn, err := y.listener.Accept()
			if err != nil {
				if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
					y.logger.Trace("Connection timeout...")
				} else {
					y.logger.Warn("Connection failed", "error", err)
				}
				continue
			}

			// Handle connection
			y.logger.Info("Successful TCP connection:", tcpConn.RemoteAddr().String())
			y.handleConn(y.grim.New(), tls.Server(tcpConn, y.tlsConfig))
		}
	}
	return
}
Example #4
0
func (d *relayDialer) Dial(id protocol.DeviceID, uri *url.URL) (IntermediateConnection, error) {
	inv, err := client.GetInvitationFromRelay(uri, id, d.tlsCfg.Certificates, 10*time.Second)
	if err != nil {
		return IntermediateConnection{}, err
	}

	conn, err := client.JoinSession(inv)
	if err != nil {
		return IntermediateConnection{}, err
	}

	err = dialer.SetTCPOptions(conn)
	if err != nil {
		conn.Close()
		return IntermediateConnection{}, err
	}

	var tc *tls.Conn
	if inv.ServerSocket {
		tc = tls.Server(conn, d.tlsCfg)
	} else {
		tc = tls.Client(conn, d.tlsCfg)
	}

	err = tc.Handshake()
	if err != nil {
		tc.Close()
		return IntermediateConnection{}, err
	}

	return IntermediateConnection{tc, "Relay (Client)", relayPriority}, nil
}
Example #5
0
func (l TLSListener) Accept() (net.Conn, error) {
	c, err := l.AcceptTCP()
	if err != nil {
		return nil, err
	}
	c.SetKeepAlive(true)
	c.SetKeepAlivePeriod(3 * time.Minute)

	b := make([]byte, 1)
	_, err = c.Read(b)
	if err != nil {
		c.Close()
		if err != io.EOF {
			return nil, err
		}
	}

	con := &conn{
		Conn: c,
		b:    b[0],
		e:    err,
		f:    true,
	}

	if b[0] == 22 {
		return tls.Server(con, l.TLSConfig), nil
	}

	return con, nil
}
Example #6
0
func (l *DowngradingListener) Accept() (net.Conn, error) {
	conn, err := l.Listener.Accept()
	if err != nil {
		return nil, err
	}

	br := bufio.NewReader(conn)
	conn.SetReadDeadline(time.Now().Add(1 * time.Second))
	bs, err := br.Peek(1)
	conn.SetReadDeadline(time.Time{})
	if err != nil {
		// We hit a read error here, but the Accept() call succeeded so we must not return an error.
		// We return the connection as is and let whoever tries to use it deal with the error.
		return conn, nil
	}

	wrapper := &WrappedConnection{br, conn}

	// 0x16 is the first byte of a TLS handshake
	if bs[0] == 0x16 {
		return tls.Server(wrapper, l.TLSConfig), nil
	}

	return wrapper, nil
}
Example #7
0
func (c *tlsCreds) ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error) {
	conn := tls.Server(rawConn, c.config)
	if err := conn.Handshake(); err != nil {
		return nil, nil, err
	}
	return conn, TLSInfo{conn.ConnectionState()}, nil
}
Example #8
0
func (this *TCPListener) KeepAccepting() {
	for this.acccepting {
		conn, err := this.listener.Accept()
		this.Lock()
		if !this.acccepting {
			this.Unlock()
			break
		}
		if this.tlsConfig != nil {
			conn = tls.Server(conn, this.tlsConfig)
		}
		if this.authConfig != nil {
			conn = this.authConfig.Server(conn)
		}
		select {
		case this.awaitingConns <- &ConnectionWithError{
			conn: conn,
			err:  err,
		}:
		default:
			if conn != nil {
				conn.Close()
			}
		}

		this.Unlock()
	}
}
Example #9
0
// TODO this code is ugly
// TODO test coverage for error cases
func TestNewClientNotEd(t *testing.T) {
	confSrv := mustGenerateTLSConfig(t, nil, nil)
	client, server := net.Pipe()
	defer client.Close()
	defer server.Close()

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		c := tls.Server(server, confSrv)
		defer c.Close()
		_, _ = io.Copy(ioutil.Discard, c)
	}()

	confClient := mustGenerateTLSConfig(t, nil, nil)
	confClient.InsecureSkipVerify = true
	c, err := edtls.NewClient(client, confClient, testKeyPub)
	if err == nil {
		c.Close()
		t.Fatal("expected an error")
	}
	if err != edtls.ErrNotEdTLS {
		t.Fatalf("expected ErrNotEdTLS, got %T: %v", err, err)
	}

	wg.Wait()
}
Example #10
0
// handle inbound STARTTLS command
func upgradeTLS(c *v1Conn, line string, hooks EventHooks) (err error) {
	if c.tlsConfig == nil {
		err = c.printfLine("%s TLS not supported", RPL_TLSRejected)
	} else {
		err = c.printfLine("%s Continue with TLS Negotiation", RPL_TLSContinue)
		if err == nil {
			tconn := tls.Server(c.conn, c.tlsConfig)
			err = tconn.Handshake()
			if err == nil {
				// successful tls handshake
				c.tlsConn = tconn
				c.C = textproto.NewConn(c.tlsConn)
			} else {
				// tls failed
				log.WithFields(log.Fields{
					"pkg":   "nntp-conn",
					"addr":  c.conn.RemoteAddr(),
					"state": c.state,
				}).Warn("TLS Handshake failed ", err)
				// fall back to plaintext
				err = nil
			}
		}
	}
	return
}
Example #11
0
func (s *Server) configure(c *net.TCPConn) net.Conn {
	c.SetNoDelay(true)
	if s.cfg == nil {
		return c
	}
	return tls.Server(c, s.cfg)
}
Example #12
0
func startTLSServer(config *Config) (net.Conn, chan error) {
	errc := make(chan error, 1)

	tlsConfigServer, err := config.IncomingTLSConfig()
	if err != nil {
		errc <- err
		return nil, errc
	}

	client, server := net.Pipe()

	// Use yamux to buffer the reads, otherwise it's easy to deadlock
	muxConf := yamux.DefaultConfig()
	serverSession, _ := yamux.Server(server, muxConf)
	clientSession, _ := yamux.Client(client, muxConf)
	clientConn, _ := clientSession.Open()
	serverConn, _ := serverSession.Accept()

	go func() {
		tlsServer := tls.Server(serverConn, tlsConfigServer)
		if err := tlsServer.Handshake(); err != nil {
			errc <- err
		}
		close(errc)
		// Because net.Pipe() is unbuffered, if both sides
		// Close() simultaneously, we will deadlock as they
		// both send an alert and then block. So we make the
		// server read any data from the client until error or
		// EOF, which will allow the client to Close(), and
		// *then* we Close() the server.
		io.Copy(ioutil.Discard, tlsServer)
		tlsServer.Close()
	}()
	return clientConn, errc
}
Example #13
0
func (c *conn) SwitchToTLS() error {
	log.WithFields(log.Fields{"c": c}).Debug("securableConn::conn::SwitchToTLS called")

	sslConfig := tls.Config{Certificates: []tls.Certificate{*c.cert}}

	log.WithFields(log.Fields{"c": c, "sslConfig": sslConfig}).Debug("securableConn::conn::SwitchToTLS sslConfig created")

	srv := tls.Server(c.plain, &sslConfig)
	log.WithFields(log.Fields{"c": c, "sslConfig": sslConfig, "srv": srv}).Debug("securableConn::conn::SwitchToTLS tls.Server created")

	//	err := srv.Handshake()
	//	if err != nil {
	//		return err
	//	}

	log.WithFields(log.Fields{"c": c, "sslConfig": sslConfig}).Debug("securableConn::conn::SwitchToTLS done")

	c.secure = srv

	c.bufr = bufio.NewReader(c.secure)
	c.bufw = bufio.NewWriter(c.secure)

	log.WithFields(log.Fields{"c": c, "sslConfig": sslConfig}).Debug("securableConn::conn::SwitchToTLS ending")
	return nil
}
Example #14
0
func (t *TCP) startTLS() (el element.Element, err error) {
	var tlsConn *tls.Conn
	if t.mode == stream.Initiating {
		err = t.WriteElement(element.StartTLS)
		if err != nil {
			return
		}
		el, err = t.Next()
		if err != nil || el.Tag != element.TLSProceed.Tag {
			return
		}
		tlsConn = tls.Client(t.Conn, t.conf)
	} else {
		err = t.WriteElement(element.TLSProceed)
		if err != nil {
			return
		}
		tlsConn = tls.Server(t.Conn, t.conf)
	}

	err = tlsConn.Handshake()
	if err != nil {
		return
	}
	conn := net.Conn(tlsConn)
	t.Conn = conn
	t.Decoder = xml.NewDecoder(conn)
	el = element.Element{}
	err = stream.ErrRequireRestart
	t.secure = true
	log.Println("Done upgrading connection")
	return
}
Example #15
0
// HandleStartTLS is the companion to StartTLS, and will do the connection upgrade.  It assumes
// that the TLS command byte has already been read.  Like StartTLS it returns the peer name, or
// an error
func (p *Protocol) HandleStartTLS(identity *security.Identity, caCertificate *security.Certificate) (string, error) {
	var (
		err     error
		tlsConn *tls.Conn
	)

	// Build the config
	config := new(tls.Config)
	config.ClientAuth = tls.RequireAndVerifyClientCert

	// Setup the tls connection
	if err := p.tlsSetup(config, identity, caCertificate); err != nil {
		return "", err
	}

	// Upgrade the connection to TLS
	// TODO: Add a deadline here?
	tlsConn = tls.Server(p.conn, config)
	if err = tlsConn.Handshake(); err != nil {
		return "", err
	}

	// Capture the connection state
	cs := tlsConn.ConnectionState()

	// And replace the original connection
	p.conn = net.Conn(tlsConn)
	p.setupBuffers()

	// Send an Ack
	p.Ack()

	return cs.PeerCertificates[0].Subject.CommonName, nil
}
Example #16
0
// smtp server, finely tailored to deal with our own client only!
func serverHandle(c net.Conn, t *testing.T) error {
	send := smtpSender{c}.send
	send("220 127.0.0.1 ESMTP service ready")
	s := bufio.NewScanner(c)
	for s.Scan() {
		switch s.Text() {
		case "EHLO localhost":
			send("250-127.0.0.1 ESMTP offers a warm hug of welcome")
			send("250-STARTTLS")
			send("250 Ok")
		case "STARTTLS":
			send("220 Go ahead")
			keypair, err := tls.X509KeyPair(localhostCert, localhostKey)
			if err != nil {
				return err
			}
			config := &tls.Config{Certificates: []tls.Certificate{keypair}}
			c = tls.Server(c, config)
			defer c.Close()
			return serverHandleTLS(c, t)
		default:
			t.Fatalf("unrecognized command: %q", s.Text())
		}
	}
	return s.Err()
}
Example #17
0
// Hijack takes a net.Conn and the host name to create the SSL
// certificate for and returns a tls.Conn that can read and write
// to the given host over TLS.
func (mitm *MITM) Hijack(conn net.Conn, host string) (*tls.Conn, *bufio.ReadWriter, error) {
	// Ensure the certificate we create is valid within a window of time to allow
	// for clock skew.
	start := time.Now().Add(-mitm.Validity)
	end := time.Now().Add(mitm.Validity)

	tpl, err := NewTemplate(mitm.Organization, host, start, end, mitm.PublicKey)
	if err != nil {
		return nil, nil, err
	}

	cb, err := x509.CreateCertificate(rand.Reader, tpl, mitm.Authority, mitm.PublicKey, mitm.PrivateKey)
	if err != nil {
		return nil, nil, err
	}

	config := &tls.Config{
		Certificates: []tls.Certificate{
			{
				PrivateKey:  mitm.PrivateKey,
				Certificate: [][]byte{cb},
			},
		},
	}

	tlsConn := tls.Server(conn, config)
	r := bufio.NewReader(tlsConn)
	w := bufio.NewWriter(tlsConn)

	return tlsConn, bufio.NewReadWriter(r, w), nil
}
Example #18
0
func (cach *connectionAwaitClientHandshake) start() (bool, error) {
	config := cach.commonTLSConfig()
	config.ClientAuth = tls.RequireAnyClientCert
	socket := tls.Server(cach.socket, config)
	cach.socket = socket
	if err := socket.Handshake(); err != nil {
		return false, err
	}

	if cach.topology.Root.VarUUId == nil {
		return false, errors.New("Root not yet known")
	}

	peerCerts := socket.ConnectionState().PeerCertificates
	if authenticated, hashsum := cach.verifyPeerCerts(cach.topology, peerCerts); authenticated {
		cach.peerCerts = peerCerts
		log.Printf("User '%s' authenticated", hex.EncodeToString(hashsum[:]))
	} else {
		return false, errors.New("Client connection rejected: No client certificate known")
	}

	helloFromServer := cach.makeHelloClientFromServer(cach.topology)
	if err := cach.send(server.SegToBytes(helloFromServer)); err != nil {
		return false, err
	}
	cach.remoteHost = cach.socket.RemoteAddr().String()
	cach.nextState(nil)
	return false, nil
}
Example #19
0
func (v *TCPListener) KeepAccepting() {
	for v.acccepting {
		conn, err := v.listener.Accept()
		v.Lock()
		if !v.acccepting {
			v.Unlock()
			break
		}
		if v.tlsConfig != nil {
			conn = tls.Server(conn, v.tlsConfig)
		}
		if v.authConfig != nil {
			conn = v.authConfig.Server(conn)
		}
		select {
		case v.awaitingConns <- &ConnectionWithError{
			conn: conn,
			err:  err,
		}:
		default:
			if conn != nil {
				conn.Close()
			}
		}

		v.Unlock()
	}
}
Example #20
0
// FIXME: This ought to be refactored with the node
func (ic *incomingConnection) sslHandshake() error {
	ic.Trace("Listener for %d in sslHandshake", ic.server.ID)
	// FIXME: Demeter is yelling at me here.
	if ic.nodeListener.failOnSSLHandshake {
		ic.Trace("But I've been told to fail the handshake hard")
		ic.terminate()
		return errors.New("ssl handshake simulating failure")
	}
	tlsConfig := ic.nodeListener.connectionServer.Cluster.tlsConfig(ic.server.ID)
	tls := tls.Server(ic.conn, tlsConfig)
	ic.Trace("Listener for %d made the tlsConn, handshaking", ic.server.ID)

	err := tls.Handshake()
	ic.Trace("Listener for %d handshook err: %s", ic.server.ID, myString(err))
	if err != nil {
		return err
	}

	ic.tls = tls
	ic.conn = tls
	ic.output = gob.NewEncoder(ic.conn)
	ic.input = gob.NewDecoder(ic.conn)

	return nil
}
Example #21
0
func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) {
	switch method {
	case MethodTLS:
		var cert tls.Certificate
		var err error

		if len(CertFile) == 0 || len(KeyFile) == 0 {
			cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey))
		} else {
			cert, err = tls.LoadX509KeyPair(CertFile, KeyFile)
		}

		if err != nil {
			return nil, err
		}
		conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}})
		if err := svrTLSAuth(conn); err != nil {
			return nil, err
		}
	case MethodAES128, MethodAES192, MethodAES256,
		MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable:
		cipher, err := shadowsocks.NewCipher(Methods[method], Password)
		if err != nil {
			return nil, err
		}
		conn = shadowsocks.NewConn(conn, cipher)
	case gosocks5.MethodNoAcceptable:
		return nil, gosocks5.ErrBadMethod
	}

	return conn, nil
}
Example #22
0
// Accept waits for and returns the next connection to the listener.
func (cl *changeCertListener) Accept() (net.Conn, error) {
	conn, err := cl.Listener.Accept()
	if err != nil {
		return nil, err
	}
	return tls.Server(conn, cl.tlsConfig()), nil
}
Example #23
0
func (t testXMPPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method != "CONNECT" {
		t.Fatal("want: proxy CONNECT but:", r.Method)
	}

	if auth := r.Header.Get("Proxy-Authorization"); auth != t.wantProxyAuth {
		t.Fatal("want: ", t.wantProxyAuth, " but: ", auth)
	}
	w.WriteHeader(http.StatusOK)

	hj, ok := w.(http.Hijacker)
	if !ok {
		t.Fatal("webserver doesn't support hijacking")
	}

	conn, bufrw, err := hj.Hijack()
	if err != nil {
		t.Fatal("failed to hijack", err)
	}
	defer conn.Close()

	if err := bufrw.Flush(); err != nil {
		t.Fatal("failed to flush", err)
	}

	cloneTLSConfig := *t.cfg
	tlsConn := tls.Server(conn, &cloneTLSConfig)

	if err := tlsConn.Handshake(); err != nil {
		t.Fatal("failed to handshake TLS", err)
	}

	t.serveXMPP(tlsConn)
}
Example #24
0
func Listen(addr, typ string, tlsCfg *tls.Config) (l *Listener, err error) {
	// listen for incoming connections
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return
	}

	l = &Listener{
		Addr:  listener.Addr(),
		Conns: make(chan Conn),
	}

	go func() {
		for {
			rawConn, err := listener.Accept()
			if err != nil {
				log.Error("Failed to accept new TCP connection of type %s: %v", typ, err)
				continue
			}

			c := wrapConn(rawConn, typ)
			if tlsCfg != nil {
				c.Conn = tls.Server(c.Conn, tlsCfg)
			}
			c.Info("New connection from %v", c.RemoteAddr())
			l.Conns <- c
		}
	}()
	return
}
Example #25
0
// newListenerMux listens and wraps accepted connections with tls after protocol peeking
func newListenerMux(listener net.Listener, config *tls.Config) *ListenerMux {
	l := ListenerMux{
		Listener:    listener,
		config:      config,
		cond:        sync.NewCond(&sync.Mutex{}),
		acceptResCh: make(chan ListenerMuxAcceptRes),
	}
	// Start listening, wrap connections with tls when needed
	go func() {
		// Loop for accepting new connections
		for {
			conn, err := l.Listener.Accept()
			if err != nil {
				l.acceptResCh <- ListenerMuxAcceptRes{err: err}
				return
			}
			// Wrap the connection with ConnMux to be able to peek the data in the incoming connection
			// and decide if we need to wrap the connection itself with a TLS or not
			go func(conn net.Conn) {
				connMux := NewConnMux(conn)
				if connMux.PeekProtocol() == "tls" {
					l.acceptResCh <- ListenerMuxAcceptRes{conn: tls.Server(connMux, l.config)}
				} else {
					l.acceptResCh <- ListenerMuxAcceptRes{conn: connMux}
				}
			}(conn)
		}
	}()
	return &l
}
Example #26
0
func serve(listener net.Listener) {
	certificate, err := tls.LoadX509KeyPair("server.crt", "server.key")
	if err != nil {
		panic(err)
	}

	for {
		c, err := listener.Accept()
		if err != nil {
			log.Printf("accept: %s", err)
		}

		tlsConn := tls.Server(c, &tls.Config{
			Certificates: []tls.Certificate{certificate},
		})
		if err := tlsConn.Handshake(); err != nil {
			log.Printf("tls: %s", err)
		}

		go func() {
			io.Copy(os.Stdout, tlsConn)
			c.Close()
		}()

		go func() {
			io.Copy(tlsConn, os.Stdin)
			c.Close()
		}()
	}
}
Example #27
0
func (r *invitationReceiver) Serve() {
	for {
		select {
		case inv := <-r.invitations:
			l.Debugln("Received relay invitation", inv)
			conn, err := client.JoinSession(inv)
			if err != nil {
				l.Debugf("Failed to join relay session %s: %v", inv, err)
				continue
			}

			var tc *tls.Conn

			if inv.ServerSocket {
				tc = tls.Server(conn, r.tlsCfg)
			} else {
				tc = tls.Client(conn, r.tlsCfg)
			}
			err = tc.Handshake()
			if err != nil {
				l.Infof("TLS handshake (BEP/relay %s): %v", inv, err)
				tc.Close()
				continue
			}
			r.conns <- tc

		case <-r.stop:
			return
		}
	}
}
Example #28
0
// 处理 tls 请求
func (s *TlsServer) HandlerTls(conn net.Conn) {
	c, err := vhost.TLS(conn)

	if err != nil || c.Host() != s.httpsDomain {
		// 不匹配,直接转发
		defer c.Close()
		c.Free()

		remoteConn, err := net.Dial("tcp", s.forwardAddr)
		if err != nil {
			log.Printf("[ERR] dial(\"tcp\",%v):%v", s.forwardAddr, err)
			return
		}
		defer remoteConn.Close()

		go io.Copy(c, remoteConn)
		io.Copy(remoteConn, c)
	} else {
		c.Free()
		tlsConn := tls.Server(c, s.tlsConfig)

		err := tlsConn.Handshake()
		if err != nil {
			log.Println(err)
			return
		}

		s.http.HandlerHttp(tlsConn)
	}
}
Example #29
0
func startTLSServer(config *Config) (net.Conn, chan error) {
	errc := make(chan error, 1)

	tlsConfigServer, err := config.IncomingTLSConfig()
	if err != nil {
		errc <- err
		return nil, errc
	}

	client, server := net.Pipe()
	go func() {
		tlsServer := tls.Server(server, tlsConfigServer)
		if err := tlsServer.Handshake(); err != nil {
			errc <- err
		}
		close(errc)
		// Because net.Pipe() is unbuffered, if both sides
		// Close() simultaneously, we will deadlock as they
		// both send an alert and then block. So we make the
		// server read any data from the client until error or
		// EOF, which will allow the client to Close(), and
		// *then* we Close() the server.
		io.Copy(ioutil.Discard, tlsServer)
		tlsServer.Close()
	}()
	return client, errc
}
Example #30
0
func (f *Filter) Request(ctx *filters.Context, req *http.Request) (*filters.Context, *http.Request, error) {
	if req.Method != "CONNECT" || !f.Match(req.Host) {
		return ctx, req, nil
	}

	hijacker, ok := ctx.GetResponseWriter().(http.Hijacker)
	if !ok {
		return ctx, nil, fmt.Errorf("%#v does not implments Hijacker", ctx.GetResponseWriter())
	}

	conn, _, err := hijacker.Hijack()
	if err != nil {
		defer conn.Close()
		return ctx, nil, fmt.Errorf("http.ResponseWriter Hijack failed: %s", err)
	}

	_, err = io.WriteString(conn, "HTTP/1.1 200 OK\r\n\r\n")
	if err != nil {
		defer conn.Close()
		return ctx, nil, err
	}

	glog.Infof("%s \"STRIP %s %s %s\" - -", req.RemoteAddr, req.Method, req.Host, req.Proto)

	cert, err := f.issue(req.Host)
	if err != nil {
		defer conn.Close()
		return ctx, nil, fmt.Errorf("tls.LoadX509KeyPair failed: %s", err)
	}

	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{*cert},
		ClientAuth:   tls.VerifyClientCertIfGiven,
	}
	tlsConn := tls.Server(conn, tlsConfig)

	if err := tlsConn.Handshake(); err != nil {
		defer tlsConn.Close()
		return ctx, nil, fmt.Errorf("tlsConn.Handshake error: %v", err)
	}

	if ln1, ok := ctx.GetListener().(httpproxy.Listener); ok {
		ln1.Add(tlsConn)
		ctx.SetHijacked(true)
		return ctx, nil, nil
	}

	loConn, err := net.Dial("tcp", ctx.GetListener().Addr().String())
	if err != nil {
		defer tlsConn.Close()
		return ctx, nil, fmt.Errorf("net.Dial failed: %v", err)
	}

	go httpproxy.IoCopy(loConn, tlsConn)
	go httpproxy.IoCopy(tlsConn, loConn)

	ctx.SetHijacked(true)
	return ctx, nil, nil
}