Example #1
0
func Main() {
	// parse options
	opts := parseArgs()

	// set up logging
	log.LogTo(opts.logto)

	// set up auth token
	if opts.authtoken == "" {
		opts.authtoken = LoadAuthToken()
	}

	// init client state
	s := &State{
		status: "connecting",

		// unique client id
		id: util.RandIdOrPanic(8),

		// command-line options
		opts: opts,

		// metrics
		metrics: NewClientMetrics(),
	}

	switch opts.protocol {
	case "http":
		s.protocol = proto.NewHttp()
	case "tcp":
		s.protocol = proto.NewTcp()
	}

	// init ui
	ctl := ui.NewController()
	if opts.webport != -1 {
		web.NewWebView(ctl, s, opts.webport)
	}

	if opts.logto != "stdout" {
		term.New(ctl, s)
	}

	go reconnectingControl(s, ctl)
	go autoUpdate(s, ctl, opts.authtoken)

	quitMessage := ""
	ctl.Wait.Add(1)
	go func() {
		defer ctl.Wait.Done()
		for {
			select {
			case obj := <-ctl.Cmds:
				switch cmd := obj.(type) {
				case ui.CmdQuit:
					quitMessage = cmd.Message
					ctl.DoShutdown()
					return
				case ui.CmdRequest:
					go func() {
						var localConn conn.Conn
						localConn, err := conn.Dial(s.opts.localaddr, "prv", nil)
						if err != nil {
							log.Warn("Failed to open private leg %s: %v", s.opts.localaddr, err)
							return
						}
						//defer localConn.Close()
						localConn = s.protocol.WrapConn(localConn)
						localConn.Write(cmd.Payload)
						ioutil.ReadAll(localConn)
					}()
				}
			}
		}
	}()

	ctl.Wait.Wait()
	fmt.Println(quitMessage)
}
Example #2
0
func newClientModel(config *Configuration, ctl mvc.Controller) *ClientModel {
	protoMap := make(map[string]proto.Protocol)
	protoMap["http"] = proto.NewHttp()
	protoMap["https"] = protoMap["http"]
	protoMap["tcp"] = proto.NewTcp()
	protocols := []proto.Protocol{protoMap["http"], protoMap["tcp"]}

	// configure TLS
	var tlsConfig *tls.Config
	if config.TrustHostRootCerts {
		tlsConfig = &tls.Config{}
	} else {
		var err error
		if tlsConfig, err = LoadTLSConfig(rootCrtPaths); err != nil {
			panic(err)
		}
	}

	return &ClientModel{
		Logger: log.NewPrefixLogger("client"),

		// server address
		serverAddr: config.ServerAddr,

		// proxy address
		proxyUrl: config.HttpProxy,

		// auth token
		authToken: config.AuthToken,

		// connection status
		connStatus: mvc.ConnConnecting,

		// update status
		updateStatus: mvc.UpdateNone,

		// metrics
		metrics: NewClientMetrics(),

		// protocols
		protoMap: protoMap,

		// protocol list
		protocols: protocols,

		// open tunnels
		tunnels: make(map[string]mvc.Tunnel),

		// controller
		ctl: ctl,

		// tls configuration
		tlsConfig: tlsConfig,

		// tunnel configuration
		tunnelConfig: config.Tunnels,

		// config path
		configPath: config.Path,
	}
}
Example #3
0
func newClientModel(config *Configuration, ctl mvc.Controller) *ClientModel {
	protoMap := make(map[string]proto.Protocol)
	protoMap["http"] = proto.NewHttp()
	protoMap["https"] = protoMap["http"]
	protoMap["tcp"] = proto.NewTcp()
	protocols := []proto.Protocol{protoMap["http"], protoMap["tcp"]}

	m := &ClientModel{
		Logger: log.NewPrefixLogger("client"),

		// server address
		serverAddr: config.ServerAddr,

		// proxy address
		proxyUrl: config.HttpProxy,

		// auth token
		authToken: config.AuthToken,

		password: config.Password,

		// connection status
		connStatus: mvc.ConnConnecting,

		// update status
		updateStatus: mvc.UpdateNone,

		// metrics
		metrics: NewClientMetrics(),

		// protocols
		protoMap: protoMap,

		// protocol list
		protocols: protocols,

		// open tunnels
		tunnels: make(map[string]mvc.Tunnel),

		// controller
		ctl: ctl,

		// tunnel configuration
		tunnelConfig: config.Tunnels,

		// config path
		configPath: config.Path,
	}

	// configure TLS
	if config.TrustHostRootCerts {
		m.Info("Trusting host's root certificates")
		m.tlsConfig = &tls.Config{}
	} else {
		m.Info("Trusting root CAs: %v", rootCrtPaths)
		var err error
		if m.tlsConfig, err = LoadTLSConfig(rootCrtPaths); err != nil {
			panic(err)
		}
	}

	// configure TLS SNI
	m.tlsConfig.ServerName = serverName(m.serverAddr)

	return m
}