automatically ignore known forwarded addresses, fixes #64

This commit is contained in:
Aine
2023-09-18 12:35:37 +03:00
parent e90925eceb
commit 60b4386dd8
187 changed files with 4070 additions and 2667 deletions

View File

@@ -14,13 +14,13 @@ import (
"time"
"github.com/rs/zerolog"
"go.mau.fi/util/dbutil"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/crypto"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/sqlstatestore"
"maunium.net/go/mautrix/util/dbutil"
)
type CryptoHelper struct {

View File

@@ -339,6 +339,9 @@ func (mach *OlmMachine) handleBeeperRoomKeyAck(ctx context.Context, sender id.Us
log.Err(err).Msg("Failed to get group session to check if it should be redacted")
}
return
} else if sess == nil {
log.Warn().Msg("Got key backup ack for unknown session")
return
}
log = log.With().
Str("sender_key", sess.SenderKey.String()).

View File

@@ -622,8 +622,8 @@ func (mach *OlmMachine) ShareKeys(ctx context.Context, currentOTKCount int) erro
start := time.Now()
mach.otkUploadLock.Lock()
defer mach.otkUploadLock.Unlock()
if mach.lastOTKUpload.Add(1 * time.Minute).After(start) {
log.Debug().Msg("Checking OTK count from server due to suspiciously close share keys requests")
if mach.lastOTKUpload.Add(1*time.Minute).After(start) || currentOTKCount < 0 {
log.Debug().Msg("Checking OTK count from server due to suspiciously close share keys requests or negative OTK count")
resp, err := mach.Client.UploadKeys(&mautrix.ReqUploadKeys{})
if err != nil {
return fmt.Errorf("failed to check current OTK counts: %w", err)

View File

@@ -109,3 +109,62 @@ func (p *PkSigning) SignJSON(obj interface{}) (string, error) {
func (p *PkSigning) lastError() error {
return convertError(C.GoString(C.olm_pk_signing_last_error((*C.OlmPkSigning)(p.int))))
}
type PkDecryption struct {
int *C.OlmPkDecryption
mem []byte
PublicKey []byte
}
func pkDecryptionSize() uint {
return uint(C.olm_pk_decryption_size())
}
func pkDecryptionPublicKeySize() uint {
return uint(C.olm_pk_key_length())
}
func NewPkDecryption(privateKey []byte) (*PkDecryption, error) {
memory := make([]byte, pkDecryptionSize())
p := &PkDecryption{
int: C.olm_pk_decryption(unsafe.Pointer(&memory[0])),
mem: memory,
}
p.Clear()
pubKey := make([]byte, pkDecryptionPublicKeySize())
if C.olm_pk_key_from_private((*C.OlmPkDecryption)(p.int),
unsafe.Pointer(&pubKey[0]), C.size_t(len(pubKey)),
unsafe.Pointer(&privateKey[0]), C.size_t(len(privateKey))) == errorVal() {
return nil, p.lastError()
}
p.PublicKey = pubKey
return p, nil
}
func (p *PkDecryption) Decrypt(ephemeralKey []byte, mac []byte, ciphertext []byte) ([]byte, error) {
maxPlaintextLength := uint(C.olm_pk_max_plaintext_length((*C.OlmPkDecryption)(p.int), C.size_t(len(ciphertext))))
plaintext := make([]byte, maxPlaintextLength)
size := C.olm_pk_decrypt((*C.OlmPkDecryption)(p.int),
unsafe.Pointer(&ephemeralKey[0]), C.size_t(len(ephemeralKey)),
unsafe.Pointer(&mac[0]), C.size_t(len(mac)),
unsafe.Pointer(&ciphertext[0]), C.size_t(len(ciphertext)),
unsafe.Pointer(&plaintext[0]), C.size_t(len(plaintext)))
if size == errorVal() {
return nil, p.lastError()
}
return plaintext[:size], nil
}
// Clear clears the underlying memory of a PkDecryption object.
func (p *PkDecryption) Clear() {
C.olm_clear_pk_decryption((*C.OlmPkDecryption)(p.int))
}
// lastError returns the last error that happened in relation to this PkDecryption object.
func (p *PkDecryption) lastError() error {
return convertError(C.GoString(C.olm_pk_decryption_last_error((*C.OlmPkDecryption)(p.int))))
}

View File

@@ -11,10 +11,10 @@ import (
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"go.mau.fi/util/exgjson"
"maunium.net/go/mautrix/crypto/canonicaljson"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/util"
)
// Utility stores the necessary state to perform hash and signature
@@ -115,7 +115,7 @@ func (u *Utility) VerifySignatureJSON(obj interface{}, userID id.UserID, keyName
return false, err
}
}
sig := gjson.GetBytes(objJSON, util.GJSONPath("signatures", string(userID), fmt.Sprintf("ed25519:%s", keyName)))
sig := gjson.GetBytes(objJSON, exgjson.Path("signatures", string(userID), fmt.Sprintf("ed25519:%s", keyName)))
if !sig.Exists() || sig.Type != gjson.String {
return false, SignatureNotFound
}

View File

@@ -18,13 +18,13 @@ import (
"time"
"github.com/rs/zerolog"
"go.mau.fi/util/dbutil"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/crypto/olm"
"maunium.net/go/mautrix/crypto/sql_store_upgrade"
"maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/id"
"maunium.net/go/mautrix/util/dbutil"
)
var PostgresArrayWrapper func(interface{}) interface {
@@ -418,6 +418,22 @@ func (store *SQLCryptoStore) RedactExpiredGroupSessions() ([]id.SessionID, error
return sessionIDs, err
}
func (store *SQLCryptoStore) RedactOutdatedGroupSessions() ([]id.SessionID, error) {
res, err := store.DB.Query(`
UPDATE crypto_megolm_inbound_session
SET withheld_code=$1, withheld_reason=$2, session=NULL, forwarding_chains=NULL
WHERE account_id=$3 AND session IS NOT NULL AND received_at IS NULL
RETURNING session_id
`, event.RoomKeyWithheldBeeperRedacted, "Session redacted: outdated", store.AccountID)
var sessionIDs []id.SessionID
for res.Next() {
var sessionID id.SessionID
_ = res.Scan(&sessionID)
sessionIDs = append(sessionIDs, sessionID)
}
return sessionIDs, err
}
func (store *SQLCryptoStore) PutWithheldGroupSession(content event.RoomKeyWithheldEventContent) error {
_, err := store.DB.Exec("INSERT INTO crypto_megolm_inbound_session (session_id, sender_key, room_id, withheld_code, withheld_reason, received_at, account_id) VALUES ($1, $2, $3, $4, $5, $6, $7)",
content.SessionID, content.SenderKey, content.RoomID, content.Code, content.Reason, time.Now().UTC(), store.AccountID)

View File

@@ -10,7 +10,7 @@ import (
"embed"
"fmt"
"maunium.net/go/mautrix/util/dbutil"
"go.mau.fi/util/dbutil"
)
var Table dbutil.UpgradeTable

View File

@@ -59,6 +59,8 @@ type Store interface {
RedactGroupSessions(id.RoomID, id.SenderKey, string) ([]id.SessionID, error)
// RedactExpiredGroupSessions removes the session data for all inbound Megolm sessions that have expired.
RedactExpiredGroupSessions() ([]id.SessionID, error)
// RedactOutdatedGroupSessions removes the session data for all inbound Megolm sessions that are lacking the expiration metadata.
RedactOutdatedGroupSessions() ([]id.SessionID, error)
// PutWithheldGroupSession tells the store that a specific Megolm session was withheld.
PutWithheldGroupSession(event.RoomKeyWithheldEventContent) error
// GetWithheldGroupSession gets the event content that was previously inserted with PutWithheldGroupSession.
@@ -317,6 +319,10 @@ func (gs *MemoryStore) RedactExpiredGroupSessions() ([]id.SessionID, error) {
return nil, fmt.Errorf("not implemented")
}
func (gs *MemoryStore) RedactOutdatedGroupSessions() ([]id.SessionID, error) {
return nil, fmt.Errorf("not implemented")
}
func (gs *MemoryStore) getWithheldGroupSessions(roomID id.RoomID, senderKey id.SenderKey) map[id.SessionID]*event.RoomKeyWithheldEventContent {
room, ok := gs.WithheldGroupSessions[roomID]
if !ok {

View File

@@ -16,10 +16,9 @@ import (
"math/rand"
"strings"
"go.mau.fi/util/base58"
"golang.org/x/crypto/hkdf"
"golang.org/x/crypto/pbkdf2"
"maunium.net/go/mautrix/util/base58"
)
const (