Пример #1
0
// Caller MUST call Put or PutClose after this
func (cc *ConnectionCache) DialServer(cacheKey, addr string, port int, serverPK, pk, sk *[32]byte) (conn *transport.Conn, err error) {
	cc.Lock()
	ch, ok := cc.connections[cacheKey]
	if !ok {
		ch = make(chan *transport.Conn, 1)
		cc.connections[cacheKey] = ch
	}
	cc.Unlock()

	if ok {
		conn := <-ch
		if conn != nil {
			return conn, nil
		}
	}
	// ch is empty now

	plainconn, err := cc.dialer.Dial("tcp", net.JoinHostPort(addr, strconv.Itoa(port)))
	if err != nil {
		cc.PutClose(cacheKey)
		return nil, err
	}
	conn, _, err = transport.Handshake(plainconn, pk, sk, serverPK, proto.SERVER_MESSAGE_SIZE)
	if err != nil {
		conn.Close()
		cc.PutClose(cacheKey)
		return nil, err
	}

	return conn, nil
}
Пример #2
0
func CreateTestHomeServerConn(dename string, denameClient *client.Client, secretConfig *proto.LocalAccountConfig, t testing.TB) *transport.Conn {
	profile, err := denameClient.Lookup(dename)
	if err != nil {
		t.Fatal(err)
	}

	chatProfileBytes, err := client.GetProfileField(profile, PROFILE_FIELD_ID)
	if err != nil {
		t.Fatal(err)
	}

	chatProfile := new(proto.Profile)
	if err := chatProfile.Unmarshal(chatProfileBytes); err != nil {
		t.Fatal(err)
	}

	addr := chatProfile.ServerAddressTCP
	port := chatProfile.ServerPortTCP
	pkTransport := ([32]byte)(chatProfile.ServerTransportPK)
	pkp := (*[32]byte)(&chatProfile.UserIDAtServer)

	oldConn, err := net.Dial("tcp", net.JoinHostPort(addr, fmt.Sprint(port)))
	if err != nil {
		t.Fatal(err)
	}

	skp := (*[32]byte)(&secretConfig.TransportSecretKeyForServer)

	conn, _, err := transport.Handshake(oldConn, pkp, skp, &pkTransport, proto.SERVER_MESSAGE_SIZE)
	if err != nil {
		t.Fatal(err)
	}

	return conn
}
Пример #3
0
//Test message listing
func TestMessageListing(t *testing.T) {
	server, pks, _, teardown := CreateTestServer(t)

	oldConn, err := net.Dial("tcp", server.listener.Addr().String())
	if err != nil {
		t.Fatal(err)
	}
	defer oldConn.Close()

	pkp, skp, err := box.GenerateKey(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	conn, _, err := transport.Handshake(oldConn, pkp, skp, pks, proto.SERVER_MESSAGE_SIZE)
	if err != nil {
		t.Fatal(err)
	}

	inBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)
	outBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)

	envelope1 := []byte("Envelope1")
	envelope2 := []byte("Envelope2")

	createAccount(conn, inBuf, outBuf, t)
	uploadMessageToUser(conn, inBuf, outBuf, t, pkp, envelope1)
	uploadMessageToUser(conn, inBuf, outBuf, t, pkp, envelope2)

	messageList := listUserMessages(conn, inBuf, outBuf, t)

	expected := make([][32]byte, 0, 64)
	envelope1Hash := sha256.Sum256(envelope1)
	envelope2Hash := sha256.Sum256(envelope2)
	expected = append(expected, envelope1Hash)
	expected = append(expected, envelope2Hash)

outer:
	for _, hash := range expected {
		for _, msgid := range messageList {
			if bytes.Equal(msgid[8:], hash[:24]) {
				continue outer
			}
		}
		t.Error("Wrong message list returned")
	}
	teardown()
}
Пример #4
0
func dropMessage(t *testing.T, server *Server, uid *[32]byte, message []byte) {
	oldConn, err := net.Dial("tcp", server.listener.Addr().String())
	if err != nil {
		t.Fatal(err)
	}
	defer oldConn.Close()

	pkp, skp, err := box.GenerateKey(rand.Reader)
	handleError(err, t)

	conn, _, err := transport.Handshake(oldConn, pkp, skp, nil, proto.SERVER_MESSAGE_SIZE)
	handleError(err, t)

	inBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)
	outBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)

	uploadMessageToUser(conn, inBuf, outBuf, t, uid, message)
}
Пример #5
0
func setUpServerTest(db *leveldb.DB, t *testing.T) (*Server, *transport.Conn, []byte, []byte, *[32]byte) {
	shutdown := make(chan struct{})

	pks, sks, err := box.GenerateKey(rand.Reader)
	handleError(err, t)

	server, err := StartServer(db, shutdown, pks, sks, ":0")
	handleError(err, t)

	oldConn, err := net.Dial("tcp", server.listener.Addr().String())
	handleError(err, t)

	pkp, skp, err := box.GenerateKey(rand.Reader)
	handleError(err, t)

	conn, _, err := transport.Handshake(oldConn, pkp, skp, nil, proto.SERVER_MESSAGE_SIZE)
	handleError(err, t)

	inBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)
	outBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)

	return server, conn, inBuf, outBuf, pkp
}
Пример #6
0
//for each client, listen for commands
func (server *Server) handleClient(connection net.Conn) error {
	defer server.wg.Done()
	newConnection, uid, err := transport.Handshake(connection, server.pk, server.sk, nil, proto.SERVER_MESSAGE_SIZE) //TODO: Decide on this bound
	if err != nil {
		return err
	}

	commands := make(chan *proto.ClientToServer)
	disconnected := make(chan error)
	server.wg.Add(2)
	go server.readClientCommands(newConnection, commands, disconnected)
	go server.handleClientShutdown(newConnection)

	var notificationsUnbuffered, notifications chan *MessageWithId
	var notifyEnabled bool
	defer func() {
		if notifyEnabled {
			server.notifier.StopWaitingSync(uid, notificationsUnbuffered)
		}
	}()

	outBuf := make([]byte, proto.SERVER_MESSAGE_SIZE)
	response := new(proto.ServerToClient)
	for {
		select {
		case err := <-disconnected:
			return err
		case cmd := <-commands:
			if cmd.CreateAccount != nil && *cmd.CreateAccount {
				err = server.newUser(uid)
			} else if cmd.DeliverEnvelope != nil {
				msg_id, err := server.newMessage((*[32]byte)(cmd.DeliverEnvelope.User),
					cmd.DeliverEnvelope.Envelope)
				if err != nil {
					return err
				}
				response.MessageId = (*proto.Byte32)(msg_id)
			} else if cmd.ListMessages != nil && *cmd.ListMessages {
				var messageList []*[32]byte
				messageList, err = server.getMessageList(uid)
				response.MessageList = proto.ToProtoByte32List(messageList)
			} else if cmd.DownloadEnvelope != nil {
				response.Envelope, err = server.getEnvelope(uid, (*[32]byte)(cmd.DownloadEnvelope))
				response.MessageId = cmd.DownloadEnvelope
			} else if cmd.DeleteMessages != nil {
				messageList := cmd.DeleteMessages
				err = server.deleteMessages(uid, proto.To32ByteList(messageList))
			} else if cmd.UploadSignedKeys != nil {
				err = server.newKeys(uid, cmd.UploadSignedKeys)
			} else if cmd.GetSignedKey != nil {
				response.SignedKey, err = server.getKey((*[32]byte)(cmd.GetSignedKey))
			} else if cmd.GetNumKeys != nil {
				response.NumKeys, err = server.getNumKeys(uid)
			} else if cmd.ReceiveEnvelopes != nil {
				if *cmd.ReceiveEnvelopes && !notifyEnabled {
					notifyEnabled = true
					notificationsUnbuffered = server.notifier.StartWaiting(uid)
					notifications = make(chan *MessageWithId)
					server.wg.Add(1)
					go server.readClientNotifications(notificationsUnbuffered, notifications)
				} else if !*cmd.ReceiveEnvelopes && notifyEnabled {
					server.notifier.StopWaitingSync(uid, notificationsUnbuffered)
					notifyEnabled = false
				}
			}
			if err != nil {
				fmt.Printf("Server error: %v\n", err)
				response.Status = proto.ServerToClient_PARSE_ERROR.Enum()
			} else {
				response.Status = proto.ServerToClient_OK.Enum()
			}
			if err = server.writeProtobuf(newConnection, outBuf, response); err != nil {
				return err
			}
			commands <- cmd
		case notification, ok := <-notifications:
			if !notifyEnabled {
				continue
			}
			if !ok {
				notifyEnabled = false
				go server.notifier.StopWaitingSync(uid, notificationsUnbuffered)
				continue
			}
			response.Envelope = notification.Envelope
			response.MessageId = (*proto.Byte32)(notification.Id)
			response.Status = proto.ServerToClient_OK.Enum()
			if err = server.writeProtobuf(newConnection, outBuf, response); err != nil {
				return err
			}
		}
		response.Reset()
	}
}