예제 #1
0
파일: client.go 프로젝트: postfix/holepunch
func doAuth(conn transports.PacketClient) bool {
	// Authentication times out after 10 seconds.
	timeout_ch := time.After(10 * time.Second)
	send_ch := conn.SendChannel()
	recv_ch := conn.RecvChannel()

	// Receive the nonce from the server.
	var nonce []byte
	select {
	case nonce = <-recv_ch:
		// fallthrough
	case <-timeout_ch:
		log.Printf("Client authentication timed out: receiving nonce\n")
		return false
	}

	hm := hmac.New(sha256.New, []byte(password))
	_, err := hm.Write(nonce)
	if err != nil {
		log.Printf("Error computing HMAC: %s\n", err)
		return false
	}

	resp := make([]byte, 64)
	hex.Encode(resp, hm.Sum(nil))

	select {
	case send_ch <- resp:
		// fallthrough
	case <-timeout_ch:
		log.Printf("Client authentication timed out: sending respond\n")
		return false
	}

	// Wait for a response from the server.
	var serv_resp []byte
	select {
	case serv_resp = <-recv_ch:
		// fallthrough
	case <-timeout_ch:
		log.Printf("Client authentication timed out: waiting for confirmation\n")
		return false
	}

	// Check response.
	if bytes.Equal(serv_resp, []byte("success")) {
		log.Printf("Authentication success\n")
		return true
	} else {
		log.Printf("Authentication failure: %s\n", serv_resp)
		return false
	}
}
예제 #2
0
파일: client.go 프로젝트: postfix/holepunch
func startClient(tt tuntap.Device, hpserver string) {
	defer tt.Close()
	log.Printf("Holepunching with server %s...\n", hpserver)

	methods := strings.Split(method, ",")
	if len(methods) == 1 && methods[0] == "all" {
		methods = []string{"tcp", "udp", "icmp", "dns"}
	}

	var conn transports.PacketClient
	var err error

	for _, m := range methods {
		var curr_conn transports.PacketClient

		err = nil
		switch m {
		case "tcp":
			curr_conn, err = transports.NewTCPPacketClient(hpserver)

		case "udp":
			curr_conn, err = transports.NewUDPPacketClient(hpserver)

		default:
			log.Printf("Unknown method: %s\n", m)
			continue
		}

		if err != nil {
			log.Printf("Error creating transport '%s': %s\n", m, err)
			continue
		}

		// Set up encryption.
		enc_conn, err := transports.NewEncryptedPacketClient(curr_conn, "foobar")
		if err != nil {
			log.Printf("Could not initialize encryption: %s\n", err)
			curr_conn.Close()
			continue
		}

		// Encryption is valid, which means that we're authenticated.
		conn = enc_conn
	}

	if conn == nil {
		log.Printf("Could not create connection to server, exiting...\n")
		return
	}
	log.Printf("Connected to server (reliable = %t)\n", conn.IsReliable())

	recv_ch := conn.RecvChannel()
	send_ch := conn.SendChannel()

	defer conn.Close()

	for {
		// TODO: some way of stopping this
		select {
		case from_server := <-recv_ch:
			log.Printf("server --> tuntap (%d bytes)\n", len(from_server))
			tt.Write(from_server)

		case from_tuntap := <-tt.RecvChannel():
			log.Printf("tuntap --> server (%d bytes)\n", len(from_tuntap))
			send_ch <- from_tuntap

		case <-tt.EOFChannel():
			log.Println("EOF received from TUN/TAP device, exiting...")
			return
		}
	}
}