internal/pipewire: implement SecurityContext::Create
All checks were successful
Test / Create distribution (push) Successful in 37s
Test / Sandbox (push) Successful in 2m18s
Test / Hakurei (push) Successful in 3m18s
Test / Hpkg (push) Successful in 4m12s
Test / Sandbox (race detector) (push) Successful in 4m19s
Test / Hakurei (race detector) (push) Successful in 2m58s
Test / Flake checks (push) Successful in 1m36s
All checks were successful
Test / Create distribution (push) Successful in 37s
Test / Sandbox (push) Successful in 2m18s
Test / Hakurei (push) Successful in 3m18s
Test / Hpkg (push) Successful in 4m12s
Test / Sandbox (race detector) (push) Successful in 4m19s
Test / Hakurei (race detector) (push) Successful in 2m58s
Test / Flake checks (push) Successful in 1m36s
This is finally the thing we are after. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -314,19 +314,13 @@ func TestHeader(t *testing.T) {
|
|||||||
Size: 0x68, Sequence: 43, FileCount: 0,
|
Size: 0x68, Sequence: 43, FileCount: 0,
|
||||||
}, nil},
|
}, nil},
|
||||||
|
|
||||||
{"PW_SECURITY_CONTEXT_METHOD_CREATE", []byte{
|
/* sendmsg 2 */
|
||||||
// Id
|
|
||||||
3, 0, 0, 0,
|
{"PW_SECURITY_CONTEXT_METHOD_CREATE", samplePWContainer[6][0][0], pipewire.Header{
|
||||||
// size
|
ID: 3,
|
||||||
0xd8, 0, 0,
|
Opcode: pipewire.PW_SECURITY_CONTEXT_METHOD_CREATE,
|
||||||
// opcode
|
Size: 0xd8, Sequence: 5, FileCount: 2,
|
||||||
1,
|
}, nil},
|
||||||
// seq
|
|
||||||
5, 0, 0, 0,
|
|
||||||
// n_fds
|
|
||||||
2, 0, 0, 0,
|
|
||||||
}, pipewire.Header{ID: 3, Opcode: pipewire.PW_SECURITY_CONTEXT_METHOD_CREATE,
|
|
||||||
Size: 0xd8, Sequence: 5, FileCount: 2}, nil},
|
|
||||||
|
|
||||||
{"PW_SECURITY_CONTEXT_METHOD_NUM", []byte{
|
{"PW_SECURITY_CONTEXT_METHOD_NUM", []byte{
|
||||||
// Id
|
// Id
|
||||||
|
|||||||
@@ -356,30 +356,6 @@ const (
|
|||||||
PW_KEY_PROFILER_NAME = "profiler.name"
|
PW_KEY_PROFILER_NAME = "profiler.name"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* pipewire/extensions/security-context.h */
|
|
||||||
|
|
||||||
const (
|
|
||||||
PW_TYPE_INTERFACE_SecurityContext = PW_TYPE_INFO_INTERFACE_BASE + "SecurityContext"
|
|
||||||
PW_SECURITY_CONTEXT_PERM_MASK = PW_PERM_RWX
|
|
||||||
PW_VERSION_SECURITY_CONTEXT = 3
|
|
||||||
|
|
||||||
PW_EXTENSION_MODULE_SECURITY_CONTEXT = PIPEWIRE_MODULE_PREFIX + "module-security-context"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
PW_SECURITY_CONTEXT_EVENT_NUM = iota
|
|
||||||
|
|
||||||
PW_VERSION_SECURITY_CONTEXT_EVENTS = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
PW_SECURITY_CONTEXT_METHOD_ADD_LISTENER = iota
|
|
||||||
PW_SECURITY_CONTEXT_METHOD_CREATE
|
|
||||||
PW_SECURITY_CONTEXT_METHOD_NUM
|
|
||||||
|
|
||||||
PW_VERSION_SECURITY_CONTEXT_METHODS = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
/* pipewire/type.h */
|
/* pipewire/type.h */
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ type (
|
|||||||
String = string
|
String = string
|
||||||
// Bytes is a byte slice representing SPA_TYPE_Bytes.
|
// Bytes is a byte slice representing SPA_TYPE_Bytes.
|
||||||
Bytes = []byte
|
Bytes = []byte
|
||||||
|
|
||||||
|
// A Fd is a signed integer value representing SPA_TYPE_Fd.
|
||||||
|
Fd Long
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -49,6 +52,9 @@ const (
|
|||||||
SizeInt Word = 4
|
SizeInt Word = 4
|
||||||
// SizeLong is the fixed, unpadded size of a [SPA_TYPE_Long] value.
|
// SizeLong is the fixed, unpadded size of a [SPA_TYPE_Long] value.
|
||||||
SizeLong Word = 8
|
SizeLong Word = 8
|
||||||
|
|
||||||
|
// SizeFd is the fixed, unpadded size of a [SPA_TYPE_Fd] value.
|
||||||
|
SizeFd = SizeLong
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Basic types */
|
/* Basic types */
|
||||||
@@ -176,6 +182,15 @@ func marshalValueAppend(data []byte, v reflect.Value) ([]byte, error) {
|
|||||||
|
|
||||||
// marshalValueAppendRaw implements [MarshalAppend] on [reflect.Value] without the size prefix.
|
// marshalValueAppendRaw implements [MarshalAppend] on [reflect.Value] without the size prefix.
|
||||||
func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
func marshalValueAppendRaw(data []byte, v reflect.Value) ([]byte, error) {
|
||||||
|
if v.CanInterface() {
|
||||||
|
switch c := v.Interface().(type) {
|
||||||
|
case Fd:
|
||||||
|
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Fd)
|
||||||
|
data = binary.NativeEndian.AppendUint64(data, uint64(c))
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
case reflect.Uint32:
|
case reflect.Uint32:
|
||||||
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Id)
|
data = binary.NativeEndian.AppendUint32(data, SPA_TYPE_Id)
|
||||||
@@ -312,6 +327,16 @@ func unmarshalValue(data []byte, v reflect.Value, wireSizeP *Word) error {
|
|||||||
*wireSizeP, err = u.UnmarshalPOD(data)
|
*wireSizeP, err = u.UnmarshalPOD(data)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch v.Interface().(type) {
|
||||||
|
case Fd:
|
||||||
|
*wireSizeP = SizeFd
|
||||||
|
if err := unmarshalCheckTypeBounds(&data, SPA_TYPE_Fd, wireSizeP); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.SetInt(int64(binary.NativeEndian.Uint64(data)))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
|||||||
69
internal/pipewire/securitycontext.go
Normal file
69
internal/pipewire/securitycontext.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package pipewire
|
||||||
|
|
||||||
|
/* pipewire/extensions/security-context.h */
|
||||||
|
|
||||||
|
const (
|
||||||
|
PW_TYPE_INTERFACE_SecurityContext = PW_TYPE_INFO_INTERFACE_BASE + "SecurityContext"
|
||||||
|
PW_SECURITY_CONTEXT_PERM_MASK = PW_PERM_RWX
|
||||||
|
PW_VERSION_SECURITY_CONTEXT = 3
|
||||||
|
|
||||||
|
PW_EXTENSION_MODULE_SECURITY_CONTEXT = PIPEWIRE_MODULE_PREFIX + "module-security-context"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PW_SECURITY_CONTEXT_EVENT_NUM = iota
|
||||||
|
|
||||||
|
PW_VERSION_SECURITY_CONTEXT_EVENTS = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PW_SECURITY_CONTEXT_METHOD_ADD_LISTENER = iota
|
||||||
|
PW_SECURITY_CONTEXT_METHOD_CREATE
|
||||||
|
PW_SECURITY_CONTEXT_METHOD_NUM
|
||||||
|
|
||||||
|
PW_VERSION_SECURITY_CONTEXT_METHODS = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// SecurityContextCreate is sent to create a new security context.
|
||||||
|
//
|
||||||
|
// Creates a new security context with a socket listening FD.
|
||||||
|
// PipeWire will accept new client connections on listen_fd.
|
||||||
|
//
|
||||||
|
// listen_fd must be ready to accept new connections when this
|
||||||
|
// request is sent by the client. In other words, the client must
|
||||||
|
// call bind(2) and listen(2) before sending the FD.
|
||||||
|
//
|
||||||
|
// close_fd is a FD closed by the client when PipeWire should stop
|
||||||
|
// accepting new connections on listen_fd.
|
||||||
|
//
|
||||||
|
// PipeWire must continue to accept connections on listen_fd when
|
||||||
|
// the client which created the security context disconnects.
|
||||||
|
//
|
||||||
|
// After sending this request, closing listen_fd and close_fd
|
||||||
|
// remains the only valid operation on them.
|
||||||
|
type SecurityContextCreate struct {
|
||||||
|
// The offset in the SCM_RIGHTS msg_control message to
|
||||||
|
// the fd to listen on for new connections.
|
||||||
|
ListenFd Fd
|
||||||
|
// The offset in the SCM_RIGHTS msg_control message to
|
||||||
|
// the fd used to stop listening.
|
||||||
|
CloseFd Fd
|
||||||
|
|
||||||
|
// Extra properties. These will be copied on the client
|
||||||
|
// that connects through this context.
|
||||||
|
Properties *SPADict `json:"props"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size satisfies [KnownSize] with a value computed at runtime.
|
||||||
|
func (c *SecurityContextCreate) Size() Word {
|
||||||
|
return SizePrefix +
|
||||||
|
Size(SizeFd) +
|
||||||
|
Size(SizeFd) +
|
||||||
|
c.Properties.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary satisfies [encoding.BinaryMarshaler] via [Marshal].
|
||||||
|
func (c *SecurityContextCreate) MarshalBinary() ([]byte, error) { return Marshal(c) }
|
||||||
|
|
||||||
|
// UnmarshalBinary satisfies [encoding.BinaryUnmarshaler] via [Unmarshal].
|
||||||
|
func (c *SecurityContextCreate) UnmarshalBinary(data []byte) error { return Unmarshal(data, c) }
|
||||||
21
internal/pipewire/securitycontext_test.go
Normal file
21
internal/pipewire/securitycontext_test.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package pipewire_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"hakurei.app/internal/pipewire"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSecurityContextCreate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
encodingTestCases[pipewire.SecurityContextCreate, *pipewire.SecurityContextCreate]{
|
||||||
|
{"sample", samplePWContainer[6][0][1], pipewire.SecurityContextCreate{
|
||||||
|
ListenFd: 1 /* 21: duplicated from listen_fd */, CloseFd: 0, /* 20: duplicated from close_fd */
|
||||||
|
Properties: &pipewire.SPADict{
|
||||||
|
{Key: "pipewire.sec.engine", Value: "org.flatpak"},
|
||||||
|
{Key: "pipewire.access", Value: "restricted"},
|
||||||
|
},
|
||||||
|
}, nil},
|
||||||
|
}.run(t)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user