mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 04:07:07 +00:00
55 lines
1.7 KiB
Go
55 lines
1.7 KiB
Go
package libsignal
|
|
|
|
/*
|
|
#include <stdlib.h>
|
|
#include <signal_protocol.h>
|
|
*/
|
|
import "C"
|
|
|
|
import "unsafe"
|
|
|
|
// Address identifies a Signal Protocol session peer: a logical recipient
|
|
// name (for OMEMO, a bare JID) plus a numeric device ID.
|
|
type Address struct {
|
|
Name string
|
|
DeviceID uint32
|
|
}
|
|
|
|
// cAddress is a C-heap-allocated signal_protocol_address (struct and name
|
|
// string both), for the specific cases - session_builder_create and
|
|
// session_cipher_create - where the C library stores the *pointer* we pass
|
|
// it and keeps dereferencing it for the object's entire lifetime (a
|
|
// shallow assignment, e.g. `result_cipher->remote_address = remote_address;`
|
|
// in session_cipher.c, confirmed by reading the source - not a defensive
|
|
// copy). A transient, freed-after-the-call address (as a short-lived cgo
|
|
// helper would naturally produce) becomes a use-after-free the moment the
|
|
// constructor returns; this type's lifetime must instead match its owning
|
|
// SessionBuilder/SessionCipher, freed only in their Close methods.
|
|
type cAddress struct {
|
|
ptr *C.signal_protocol_address
|
|
}
|
|
|
|
func newCAddress(addr Address) *cAddress {
|
|
namePtr := C.CString(addr.Name)
|
|
c := (*C.signal_protocol_address)(C.malloc(C.size_t(unsafe.Sizeof(C.signal_protocol_address{}))))
|
|
c.name = namePtr
|
|
c.name_len = C.size_t(len(addr.Name))
|
|
c.device_id = C.int32_t(addr.DeviceID)
|
|
return &cAddress{ptr: c}
|
|
}
|
|
|
|
func (a *cAddress) free() {
|
|
if a.ptr != nil {
|
|
C.free(unsafe.Pointer(a.ptr.name))
|
|
C.free(unsafe.Pointer(a.ptr))
|
|
a.ptr = nil
|
|
}
|
|
}
|
|
|
|
// addressFromC copies a C signal_protocol_address into a Go Address.
|
|
func addressFromC(addr *C.signal_protocol_address) Address {
|
|
return Address{
|
|
Name: C.GoStringN(addr.name, C.int(addr.name_len)),
|
|
DeviceID: uint32(addr.device_id),
|
|
}
|
|
}
|