Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Merge pull request #36 from signal-golang/groups_v2
Browse files Browse the repository at this point in the history
Initial groups v2 support
  • Loading branch information
nanu-c authored May 28, 2021
2 parents 0d52bfd + fb85dbd commit 9a87085
Show file tree
Hide file tree
Showing 28 changed files with 1,361 additions and 325 deletions.
13 changes: 9 additions & 4 deletions cmd/textsecure/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"github.com/go-redis/redis"
"github.com/signal-golang/textsecure"
"github.com/signal-golang/textsecure/axolotl"
"github.com/signal-golang/textsecure/config"
"github.com/signal-golang/textsecure/contacts"
"golang.org/x/crypto/ssh/terminal"

log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -126,12 +128,14 @@ func getStoragePassword() string {
return string(password)
}

func getConfig() (*textsecure.Config, error) {
func getConfig() (*config.Config, error) {
return textsecure.ReadConfig(configDir + "/config.yml")
}

func getLocalContacts() ([]textsecure.Contact, error) {
return textsecure.ReadContacts(configDir + "/contacts.yml")
func getUsername() string {
return readLine("A username is missing please enter one>")
}
func getLocalContacts() ([]contacts.Contact, error) {
return contacts.ReadContacts(configDir + "/contacts.yml")
}

func sendMessageToRedis(rmsg RedisMessage) {
Expand Down Expand Up @@ -498,6 +502,7 @@ func main() {
MessageHandler: messageHandler,
ReceiptMessageHandler: receiptMessageHandler,
RegistrationDone: registrationDone,
GetUsername: getUsername,
}
err := textsecure.Setup(client)
if err != nil {
Expand Down
58 changes: 20 additions & 38 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,42 @@ import (
"io/ioutil"

"github.com/go-yaml/yaml"
"github.com/signal-golang/textsecure/config"
log "github.com/sirupsen/logrus"
)

// Config holds application configuration settings
type Config struct {
Tel string `yaml:"tel"` // Our telephone number
UUID string `yaml:"uuid" default:"notset"`
Server string `yaml:"server"` // The TextSecure server URL
RootCA string `yaml:"rootCA"` // The TLS signing certificate of the server we connect to
ProxyServer string `yaml:"proxy"` // HTTP Proxy URL if one is being used
VerificationType string `yaml:"verificationType"` // Code verification method during registration (SMS/VOICE/DEV)
StorageDir string `yaml:"storageDir"` // Directory for the persistent storage
UnencryptedStorage bool `yaml:"unencryptedStorage"` // Whether to store plaintext keys and session state (only for development)
StoragePassword string `yaml:"storagePassword"` // Password to the storage
LogLevel string `yaml:"loglevel"` // Verbosity of the logging messages
UserAgent string `yaml:"userAgent"` // Override for the default HTTP User Agent header field
AlwaysTrustPeerID bool `yaml:"alwaysTrustPeerID"` // Workaround until proper handling of peer reregistering with new ID.
AccountCapabilities AccountCapabilities `yaml:"accountCapabilities"` // Account Attrributes are used in order to track the support of different function for signal
DiscoverableByPhoneNumber bool `yaml:"discoverableByPhoneNumber"` // If the user should be found by his phone number
ProfileKey []byte `yaml:"profileKey"` // The profile key is used in many places to encrypt the avatar, name etc and also in groupsv2 context
Name string `yaml:"name"`
}

var configFile string

// TODO: some race conditions to be solved
func checkUUID(cfg *Config) *Config {
defer func(cfg *Config) *Config {
log.Debugln("[textsecure] missing my uuid defer")
recover()
UUID, err := GetMyUUID()
if err != nil {
log.Debugln("[textsecure] missing my uuid", err)
func checkUUID(cfg *config.Config) *config.Config {
if len(cfg.UUID) != 36 {
log.Debugln(cfg.UUID)
defer func(cfg *config.Config) *config.Config {
recover()
UUID, err := GetMyUUID()
if err != nil {
log.Debugln("[textsecure] missing my uuid", err)
return cfg
}
cfg.UUID = UUID
return cfg
}(cfg)
if cfg.UUID == "notset" {
log.Debugln("[textsecure] missing my uuid notset")
}
cfg.UUID = UUID
return cfg
}(cfg)
if cfg.UUID == "notset" {
log.Debugln("[textsecure] missing my uuid notset")
}
return cfg

}

// ReadConfig reads a YAML config file
func ReadConfig(fileName string) (*Config, error) {
func ReadConfig(fileName string) (*config.Config, error) {
b, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, err
}
configFile = fileName

cfg := &Config{}
cfg := &config.Config{}
err = yaml.Unmarshal(b, cfg)
if err != nil {
return nil, err
Expand All @@ -69,21 +51,21 @@ func ReadConfig(fileName string) (*Config, error) {
}

// WriteConfig saves a config to a file
func WriteConfig(filename string, cfg *Config) error {
func WriteConfig(filename string, cfg *config.Config) error {
b, err := yaml.Marshal(cfg)
if err != nil {
return err
}
return ioutil.WriteFile(filename, b, 0600)
}

func saveConfig(cfg *Config) {
func saveConfig(cfg *config.Config) {
WriteConfig(configFile, cfg)
}

// loadConfig gets the config via the client and makes sure
// that for unset values sane defaults are used
func loadConfig() (*Config, error) {
func loadConfig() (*config.Config, error) {
cfg, err := client.GetConfig()

if err != nil {
Expand Down
33 changes: 33 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package config

// Config holds application configuration settings
type Config struct {
Tel string `yaml:"tel"` // Our telephone number
UUID string `yaml:"uuid" default:"notset"`
Server string `yaml:"server"` // The TextSecure server URL
RootCA string `yaml:"rootCA"` // The TLS signing certificate of the server we connect to
ProxyServer string `yaml:"proxy"` // HTTP Proxy URL if one is being used
VerificationType string `yaml:"verificationType"` // Code verification method during registration (SMS/VOICE/DEV)
StorageDir string `yaml:"storageDir"` // Directory for the persistent storage
UnencryptedStorage bool `yaml:"unencryptedStorage"` // Whether to store plaintext keys and session state (only for development)
StoragePassword string `yaml:"storagePassword"` // Password to the storage
LogLevel string `yaml:"loglevel"` // Verbosity of the logging messages
UserAgent string `yaml:"userAgent"` // Override for the default HTTP User Agent header field
AlwaysTrustPeerID bool `yaml:"alwaysTrustPeerID"` // Workaround until proper handling of peer reregistering with new ID.
AccountCapabilities AccountCapabilities `yaml:"accountCapabilities"` // Account Attrributes are used in order to track the support of different function for signal
DiscoverableByPhoneNumber bool `yaml:"discoverableByPhoneNumber"` // If the user should be found by his phone number
ProfileKey []byte `yaml:"profileKey"` // The profile key is used in many places to encrypt the avatar, name etc and also in groupsv2 context
Name string `yaml:"name"`
}

// AccountCapabilities describes what functions axolotl supports
type AccountCapabilities struct {
UUID bool `json:"uuid" yaml:"uuid"`
Gv2 bool `json:"gv2-3" yaml:"gv2"`
Storage bool `json:"storage" yaml:"storage"`
Gv1Migration bool `json:"gv1-migration" yaml:"gv1-migration"`
}

var (
ConfigFile *Config
)
12 changes: 6 additions & 6 deletions contactDiscoveryCrypto/contactDiscoveryCrypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type QueryEnvelope struct {
Mac []byte `json:"mac"`
RequestId []byte `json:"requestId"`
}

type DiscoveryRequest struct {
AddressCount int `json:"addressCount"`
Commitment []byte `json:"commitment"`
Expand All @@ -29,7 +30,6 @@ type DiscoveryRequest struct {
Mac []byte `json:"mac"`
}

//copied from nanu_c
type RemoteAttestation struct {
RequestId []byte
Keys RemoteAttestationKeys
Expand Down Expand Up @@ -91,11 +91,11 @@ func buildQueryData(addressBook []string) ([]byte, error) {
func buildQueryDataWithNonce(addressBook []string, nonce []byte) ([]byte, error) {
var addressData []byte
for _, address := range addressBook {
addressId, err := parse(address)
addressID, err := parse(address)
if err != nil {
return nil, err
}
addressData = append(addressData, toByteArray(addressId)...)
addressData = append(addressData, toByteArray(addressID)...)
}
return append(nonce, addressData...), nil
}
Expand All @@ -118,16 +118,16 @@ func buildQueryEnvelopeFromAttestation(attestation *contactsDiscovery.RemoteAtte
return buildQueryEnvelope(attestation.RequestId, attestation.Keys.ClientKey, queryDataKey)
}

func buildQueryEnvelope(requestId, clientKey, queryDataKey []byte) (*QueryEnvelope, error) {
result, err := aesEncrypt(clientKey, requestId, queryDataKey)
func buildQueryEnvelope(requestID, clientKey, queryDataKey []byte) (*QueryEnvelope, error) {
result, err := aesEncrypt(clientKey, requestID, queryDataKey)
if err != nil {
return nil, err
}
return &QueryEnvelope{
Data: result.data,
Mac: result.mac,
Iv: result.iv,
RequestId: requestId,
RequestId: requestID,
}, nil
}

Expand Down
76 changes: 29 additions & 47 deletions contacts.go → contacts/contacts.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// Copyright (c) 2014 Canonical Ltd.
// Licensed under the GPLv3, see the COPYING file for details.

package textsecure
package contacts

import (
"bytes"
"io"
"io/ioutil"

signalservice "github.com/signal-golang/textsecure/protobuf"
Expand Down Expand Up @@ -37,17 +35,17 @@ type yamlContacts struct {

var (
contactsFile string
contacts = map[string]Contact{}
Contacts = map[string]Contact{}
)

// ReadContacts reads a YAML contacts file
func loadContacts(contactsYaml *yamlContacts) {
// LoadContacts reads a YAML contacts file
func LoadContacts(contactsYaml *yamlContacts) {
for _, c := range contactsYaml.Contacts {
if c.UUID != "" && c.UUID != "0" && (c.UUID[0] != 0 || c.UUID[len(c.UUID)-1] != 0) {
contacts[c.UUID] = c
Contacts[c.UUID] = c

} else {
contacts[c.Tel] = c
Contacts[c.Tel] = c
}
}
}
Expand All @@ -66,7 +64,7 @@ func ReadContacts(fileName string) ([]Contact, error) {
if err != nil {
return nil, err
}
loadContacts(contactsYaml)
LoadContacts(contactsYaml)
return contactsYaml.Contacts, nil
}

Expand All @@ -91,7 +89,7 @@ func WriteContactsToPath() error {
}
func contactsToYaml() *yamlContacts {
c := &yamlContacts{}
for _, co := range contacts {
for _, co := range Contacts {
c.Contacts = append(c.Contacts, co)
}
return c
Expand All @@ -100,24 +98,25 @@ func contactsToYaml() *yamlContacts {
func updateContact(c *signalservice.ContactDetails) error {
log.Debugln("[textsecure] updateContact ", c.GetUuid())

var r io.Reader
av := c.GetAvatar()
buf := new(bytes.Buffer)
if av != nil {
att, err := handleProfileAvatar(av, c.GetProfileKey())
if err != nil {
return err
}
r = att.R
buf.ReadFrom(r)
}
avatar, _ := ioutil.ReadAll(buf)

contacts[c.GetUuid()] = Contact{
Tel: c.GetNumber(),
UUID: c.GetUuid(),
Name: c.GetName(),
Avatar: avatar,
// var r io.Reader
// av := c.GetAvatar()
// buf := new(bytes.Buffer)
// if av != nil {
// att, err := handleProfileAvatar(av, c.GetProfileKey())
// if err != nil {
// return err
// }
// r = att.R
// buf.ReadFrom(r)
// }
// avatar, _ := ioutil.ReadAll(buf)

Contacts[c.GetUuid()] = Contact{
Tel: c.GetNumber(),
UUID: c.GetUuid(),
Name: c.GetName(),
// Avatar: avatar,
Avatar: nil,
Color: c.GetColor(),
Verified: c.GetVerified(),
ProfileKey: c.GetProfileKey(),
Expand All @@ -126,11 +125,11 @@ func updateContact(c *signalservice.ContactDetails) error {
InboxPosition: c.GetInboxPosition(),
Archived: c.GetArchived(),
}
log.Debugln("[textsecure] avatar", c.GetAvatar(), buf)
log.Debugln("[textsecure] avatar", c.GetAvatar())
return WriteContactsToPath()
}

func handleContacts(src string, dm *signalservice.DataMessage) ([]*signalservice.DataMessage_Contact, error) {
func HandleContacts(src string, dm *signalservice.DataMessage) ([]*signalservice.DataMessage_Contact, error) {
cs := dm.GetContact()
if cs == nil {
return nil, nil
Expand All @@ -142,20 +141,3 @@ func handleContacts(src string, dm *signalservice.DataMessage) ([]*signalservice
}
return nil, nil
}

// SyncContacts syncs the contacts
func SyncContacts() error {
var t signalservice.SyncMessage_Request_Type
t = signalservice.SyncMessage_Request_CONTACTS
omsg := &signalservice.SyncMessage{
Request: &signalservice.SyncMessage_Request{
Type: &t,
},
}
_, err := sendSyncMessage(omsg, nil)
if err != nil {
return err
}

return nil
}
Loading

0 comments on commit 9a87085

Please sign in to comment.