enhanced automatic banning for invalid auth requests; update deps
This commit is contained in:
parent
bf89b8fe1b
commit
a6f52fe1ee
152 changed files with 326416 additions and 43159 deletions
26
go.mod
26
go.mod
|
|
@ -7,10 +7,10 @@ toolchain go1.22.0
|
|||
// replace gitlab.com/etke.cc/linkpearl => ../linkpearl
|
||||
|
||||
require (
|
||||
github.com/archdx/zerolog-sentry v1.8.3
|
||||
github.com/archdx/zerolog-sentry v1.8.4
|
||||
github.com/emersion/go-msgauth v0.6.8
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43
|
||||
github.com/emersion/go-smtp v0.21.2
|
||||
github.com/emersion/go-smtp v0.21.3
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/gabriel-vasile/mimetype v1.4.4
|
||||
github.com/getsentry/sentry-go v0.28.1
|
||||
|
|
@ -28,10 +28,10 @@ require (
|
|||
gitlab.com/etke.cc/go/psd v1.1.2
|
||||
gitlab.com/etke.cc/go/secgen v1.2.0
|
||||
gitlab.com/etke.cc/go/validator v1.0.7
|
||||
gitlab.com/etke.cc/linkpearl v0.0.0-20240425105001-435ae2720365
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
|
||||
maunium.net/go/mautrix v0.18.1
|
||||
modernc.org/sqlite v1.30.1
|
||||
gitlab.com/etke.cc/linkpearl v0.0.0-20240716084747-f2a547f02d54
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
maunium.net/go/mautrix v0.19.0
|
||||
modernc.org/sqlite v1.31.1
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
@ -45,7 +45,7 @@ require (
|
|||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
|
|
@ -59,13 +59,13 @@ require (
|
|||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/yuin/goldmark v1.7.4 // indirect
|
||||
gitlab.com/etke.cc/go/trysmtp v1.1.3 // indirect
|
||||
go.mau.fi/util v0.5.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
go.mau.fi/util v0.6.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect
|
||||
modernc.org/libc v1.54.1 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e // indirect
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
|
|
|
|||
68
go.sum
68
go.sum
|
|
@ -2,8 +2,8 @@ blitiri.com.ar/go/spf v1.5.1 h1:CWUEasc44OrANJD8CzceRnRn1Jv0LttY68cYym2/pbE=
|
|||
blitiri.com.ar/go/spf v1.5.1/go.mod h1:E71N92TfL4+Yyd5lpKuE9CAF2pd4JrUq1xQfkTxoNdk=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/archdx/zerolog-sentry v1.8.3 h1:d3MiV+2406pHnUodv6O00sqafIohjtsYGb8cuFAf2KQ=
|
||||
github.com/archdx/zerolog-sentry v1.8.3/go.mod h1:XrFHGe1CH5DQk/XSySu/IJSi5C9XR6+zpc97zVf/c4c=
|
||||
github.com/archdx/zerolog-sentry v1.8.4 h1:Thxb8Crm+JaV1kcAF2KEcpKwkMtQaj+GazhktFgGTUc=
|
||||
github.com/archdx/zerolog-sentry v1.8.4/go.mod h1:XrFHGe1CH5DQk/XSySu/IJSi5C9XR6+zpc97zVf/c4c=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
|
||||
|
|
@ -18,8 +18,8 @@ github.com/emersion/go-msgauth v0.6.8/go.mod h1:YDwuyTCUHu9xxmAeVj0eW4INnwB6NNZo
|
|||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpzYfLAAfl63E8Le6F2+EL/cdhlkyRJY=
|
||||
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-smtp v0.21.2 h1:OLDgvZKuofk4em9fT5tFG5j4jE1/hXnX75UMvcrL4AA=
|
||||
github.com/emersion/go-smtp v0.21.2/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||
github.com/emersion/go-smtp v0.21.3 h1:7uVwagE8iPYE48WhNsng3RRpCUpFvNl39JGNSIyGVMY=
|
||||
github.com/emersion/go-smtp v0.21.3/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
|
||||
|
|
@ -56,8 +56,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
|||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mcnijman/go-emailaddress v1.1.1 h1:AGhgVDG3tCDaL0/Vc6erlPQjDuDN3dAT7rRdgFtetr0=
|
||||
|
|
@ -118,49 +118,49 @@ gitlab.com/etke.cc/go/trysmtp v1.1.3 h1:e2EHond77onMaecqCg6mWumffTSEf+ycgj88nbee
|
|||
gitlab.com/etke.cc/go/trysmtp v1.1.3/go.mod h1:lOO7tTdAE0a3ETV3wN3GJ7I1Tqewu7YTpPWaOmTteV0=
|
||||
gitlab.com/etke.cc/go/validator v1.0.7 h1:4BGDTa9x68vJhbyn7m8W2yX+2Nb5im9+JLRrgoLUlF4=
|
||||
gitlab.com/etke.cc/go/validator v1.0.7/go.mod h1:Id0SxRj0J3IPhiKlj0w1plxVLZfHlkwipn7HfRZsDts=
|
||||
gitlab.com/etke.cc/linkpearl v0.0.0-20240425105001-435ae2720365 h1:MZnAxKJ5Bwv6ZHfC+HUEQyTDC0HPXVB8Q63ISkZ1lHo=
|
||||
gitlab.com/etke.cc/linkpearl v0.0.0-20240425105001-435ae2720365/go.mod h1:onM3Tge1SUII+oda91/ThDvVvMhkPiSRJ7EOsC2g0yc=
|
||||
go.mau.fi/util v0.5.0 h1:8yELAl+1CDRrwGe9NUmREgVclSs26Z68pTWePHVxuDo=
|
||||
go.mau.fi/util v0.5.0/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
gitlab.com/etke.cc/linkpearl v0.0.0-20240716084747-f2a547f02d54 h1:+ihVGkVBBWlRyugJ3dvmA1rwqC9jFXrUZSslkYFN0Gw=
|
||||
gitlab.com/etke.cc/linkpearl v0.0.0-20240716084747-f2a547f02d54/go.mod h1:R/uxbOoajQVxm0qCbWYfox6B9uqnM5R0/KMJcLSr6zM=
|
||||
go.mau.fi/util v0.6.0 h1:W6SyB3Bm/GjenQ5iq8Z8WWdN85Gy2xS6L0wmnR7SVjg=
|
||||
go.mau.fi/util v0.6.0/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/mautrix v0.18.1 h1:a6mUsJixegBNTXUoqC5RQ9gsumIPzKvCubKwF+zmCt4=
|
||||
maunium.net/go/mautrix v0.18.1/go.mod h1:2oHaq792cSXFGvxLvYw3Gf1L4WVVP4KZcYys5HVk/h8=
|
||||
maunium.net/go/mautrix v0.19.0 h1:67eSJWam93mw44Q0/1SiOG7zQzXMUknUv5UaWkrODDU=
|
||||
maunium.net/go/mautrix v0.19.0/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8=
|
||||
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
|
||||
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.19.0 h1:f9K5VdC0nVhHKTFMvhjtZ8TbRgFQbASvE5yO1zs8eC0=
|
||||
modernc.org/ccgo/v4 v4.19.0/go.mod h1:CfpAl+673iXNwMG/aqcQn+vDcu4Es/YLya7+9RHjTa4=
|
||||
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
|
||||
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8=
|
||||
modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.54.1 h1:5vzs86ANQehsFZXqjxUam20JwgK2eODTOcGMIWcCdg4=
|
||||
modernc.org/libc v1.54.1/go.mod h1:B0D6klDmSmnq26T1iocn9kzyX6NtbzjuI3+oX/xfvng=
|
||||
modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e h1:WPC4v0rNIFb2PY+nBBEEKyugPPRHPzUgyN3xZPpGK58=
|
||||
modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
|
|
@ -169,8 +169,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
|||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk=
|
||||
modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU=
|
||||
modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs=
|
||||
modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
|
|
|||
70
smtp/authserver.go
Normal file
70
smtp/authserver.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package smtp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/emersion/go-sasl"
|
||||
"github.com/emersion/go-smtp"
|
||||
)
|
||||
|
||||
// ensure that PlainAuthServer implements sasl.Server
|
||||
var _ sasl.Server = (*PlainAuthServer)(nil)
|
||||
|
||||
// PlainAuthServer is a server implementation of the PLAIN authentication mechanism.
|
||||
// It's a modified version of the original plainServer from https://github.com/emersion/go-sasl package (MIT License)
|
||||
// ref: https://github.com/emersion/go-sasl/blob/e73c9f7bad438a9bf3f5b28e661b74d752ecafdd/plain.go
|
||||
// The reason for modification is to extend automatic banning mechanism of Postmoogle, as the original implementation
|
||||
// doesn't provide a way to return an error to the caller before the actual authentication process.
|
||||
type PlainAuthServer struct {
|
||||
done bool
|
||||
ctx context.Context //nolint:containedctx // that's per-request structure
|
||||
bot matrixbot
|
||||
conn *smtp.Conn
|
||||
authenticate sasl.PlainAuthenticator
|
||||
}
|
||||
|
||||
// NewPlainAuthServer creates a new PLAIN authentication server.
|
||||
func NewPlainAuthServer(ctx context.Context, bot matrixbot, conn *smtp.Conn, auth sasl.PlainAuthenticator) *PlainAuthServer {
|
||||
return &PlainAuthServer{
|
||||
ctx: ctx,
|
||||
bot: bot,
|
||||
conn: conn,
|
||||
authenticate: auth,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *PlainAuthServer) Next(response []byte) (challenge []byte, done bool, err error) {
|
||||
if a.done {
|
||||
err = sasl.ErrUnexpectedClientResponse
|
||||
return
|
||||
}
|
||||
addr := a.conn.Conn().RemoteAddr()
|
||||
if a.bot.IsBanned(a.ctx, addr) {
|
||||
err = ErrBanned
|
||||
return
|
||||
}
|
||||
|
||||
// No initial response, send an empty challenge
|
||||
if response == nil {
|
||||
return []byte{}, false, nil
|
||||
}
|
||||
|
||||
a.done = true
|
||||
|
||||
parts := bytes.Split(response, []byte("\x00"))
|
||||
if len(parts) != 3 {
|
||||
a.bot.BanAuth(a.ctx, addr)
|
||||
err = errors.New("sasl: invalid response. Don't bother me anymore, kupo")
|
||||
return
|
||||
}
|
||||
|
||||
identity := string(parts[0])
|
||||
username := string(parts[1])
|
||||
password := string(parts[2])
|
||||
|
||||
err = a.authenticate(identity, username, password)
|
||||
done = true
|
||||
return
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/emersion/go-msgauth/dkim"
|
||||
|
|
@ -34,6 +35,8 @@ var (
|
|||
ErrInvalidEmail = errors.New("please, provide valid email address")
|
||||
// GraylistEnhancedCode is GraylistCode in enhanced code notation
|
||||
GraylistEnhancedCode = smtp.EnhancedCode{4, 5, 1}
|
||||
// ensure that session implements smtp.AuthSession
|
||||
_ smtp.AuthSession = (*session)(nil)
|
||||
)
|
||||
|
||||
type session struct {
|
||||
|
|
@ -52,13 +55,20 @@ type session struct {
|
|||
fromRoom id.RoomID
|
||||
}
|
||||
|
||||
// AuthMechanisms returns the list of supported authentication mechanisms
|
||||
func (s *session) AuthMechanisms() []string {
|
||||
return []string{sasl.Plain}
|
||||
}
|
||||
|
||||
//nolint:unparam // it's a part of the interface
|
||||
func (s *session) Auth(_ string) (sasl.Server, error) {
|
||||
return sasl.NewPlainServer(func(identity, username, password string) error {
|
||||
func (s *session) Auth(mech string) (sasl.Server, error) {
|
||||
if !slices.Contains(s.AuthMechanisms(), mech) {
|
||||
addr := s.conn.Conn().RemoteAddr()
|
||||
s.log.Info().Str("addr", addr.String()).Msg("banning due to invalid auth mechanism")
|
||||
s.bot.BanAuth(s.ctx, addr)
|
||||
return nil, ErrBanned
|
||||
}
|
||||
|
||||
return NewPlainAuthServer(s.ctx, s.bot, s.conn, func(identity, username, password string) error {
|
||||
return s.authPlain(identity, username, password)
|
||||
}), nil
|
||||
}
|
||||
|
|
|
|||
13
vendor/github.com/archdx/zerolog-sentry/writer.go
generated
vendored
13
vendor/github.com/archdx/zerolog-sentry/writer.go
generated
vendored
|
|
@ -6,7 +6,6 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/buger/jsonparser"
|
||||
"github.com/getsentry/sentry-go"
|
||||
|
|
@ -147,17 +146,17 @@ func (w *Writer) parseLogEvent(data []byte) (*sentry.Event, bool) {
|
|||
}
|
||||
|
||||
err := jsonparser.ObjectEach(data, func(key, value []byte, vt jsonparser.ValueType, offset int) error {
|
||||
switch string(key) {
|
||||
switch strKey := string(key); strKey {
|
||||
case zerolog.MessageFieldName:
|
||||
event.Message = bytesToStrUnsafe(value)
|
||||
event.Message = string(value)
|
||||
case zerolog.ErrorFieldName:
|
||||
event.Exception = append(event.Exception, sentry.Exception{
|
||||
Value: bytesToStrUnsafe(value),
|
||||
Value: string(value),
|
||||
Stacktrace: newStacktrace(),
|
||||
})
|
||||
case zerolog.LevelFieldName, zerolog.TimestampFieldName:
|
||||
default:
|
||||
event.Extra[string(key)] = bytesToStrUnsafe(value)
|
||||
event.Extra[strKey] = string(value)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -202,10 +201,6 @@ outer:
|
|||
return st
|
||||
}
|
||||
|
||||
func bytesToStrUnsafe(data []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&data))
|
||||
}
|
||||
|
||||
// WriterOption configures sentry events writer.
|
||||
type WriterOption interface {
|
||||
apply(*config)
|
||||
|
|
|
|||
19
vendor/github.com/emersion/go-smtp/client.go
generated
vendored
19
vendor/github.com/emersion/go-smtp/client.go
generated
vendored
|
|
@ -29,6 +29,8 @@ type Client struct {
|
|||
lmtp bool
|
||||
ext map[string]string // supported extensions
|
||||
localName string // the name to use in HELO/EHLO/LHLO
|
||||
didGreet bool // whether we've received greeting from server
|
||||
greetError error // the error from the greeting
|
||||
didHello bool // whether we've said HELO/EHLO/LHLO
|
||||
helloError error // the error from the hello
|
||||
rcpts []string // recipients accumulated for the current session
|
||||
|
|
@ -179,17 +181,22 @@ func (c *Client) Close() error {
|
|||
}
|
||||
|
||||
func (c *Client) greet() error {
|
||||
if c.didGreet {
|
||||
return c.greetError
|
||||
}
|
||||
|
||||
// Initial greeting timeout. RFC 5321 recommends 5 minutes.
|
||||
c.conn.SetDeadline(time.Now().Add(c.CommandTimeout))
|
||||
defer c.conn.SetDeadline(time.Time{})
|
||||
|
||||
c.didGreet = true
|
||||
_, _, err := c.readResponse(220)
|
||||
if err != nil {
|
||||
c.greetError = err
|
||||
c.text.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return c.greetError
|
||||
}
|
||||
|
||||
// hello runs a hello exchange if needed.
|
||||
|
|
@ -198,12 +205,11 @@ func (c *Client) hello() error {
|
|||
return c.helloError
|
||||
}
|
||||
|
||||
c.didHello = true
|
||||
if err := c.greet(); err != nil {
|
||||
c.helloError = err
|
||||
return c.helloError
|
||||
return err
|
||||
}
|
||||
|
||||
c.didHello = true
|
||||
if err := c.ehlo(); err != nil {
|
||||
var smtpError *SMTPError
|
||||
if errors.As(err, &smtpError) && (smtpError.Code == 500 || smtpError.Code == 502) {
|
||||
|
|
@ -321,7 +327,8 @@ func (c *Client) startTLS(config *tls.Config) error {
|
|||
testHookStartTLS(config)
|
||||
}
|
||||
c.setConn(tls.Client(c.conn, config))
|
||||
return c.ehlo()
|
||||
c.didHello = false
|
||||
return nil
|
||||
}
|
||||
|
||||
// TLSConnectionState returns the client's TLS connection state.
|
||||
|
|
|
|||
323
vendor/github.com/mattn/go-runewidth/runewidth_table.go
generated
vendored
323
vendor/github.com/mattn/go-runewidth/runewidth_table.go
generated
vendored
|
|
@ -4,20 +4,21 @@ package runewidth
|
|||
|
||||
var combining = table{
|
||||
{0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3},
|
||||
{0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0D00, 0x0D01},
|
||||
{0x135D, 0x135F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1AC0},
|
||||
{0x1B6B, 0x1B73}, {0x1DC0, 0x1DF9}, {0x1DFB, 0x1DFF},
|
||||
{0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0CF3, 0x0CF3},
|
||||
{0x0D00, 0x0D01}, {0x135D, 0x135F}, {0x1A7F, 0x1A7F},
|
||||
{0x1AB0, 0x1ACE}, {0x1B6B, 0x1B73}, {0x1DC0, 0x1DFF},
|
||||
{0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF},
|
||||
{0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D},
|
||||
{0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1},
|
||||
{0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A},
|
||||
{0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x11300, 0x11301},
|
||||
{0x1133B, 0x1133C}, {0x11366, 0x1136C}, {0x11370, 0x11374},
|
||||
{0x16AF0, 0x16AF4}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},
|
||||
{0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85},
|
||||
{0x11300, 0x11301}, {0x1133B, 0x1133C}, {0x11366, 0x1136C},
|
||||
{0x11370, 0x11374}, {0x16AF0, 0x16AF4}, {0x1CF00, 0x1CF2D},
|
||||
{0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},
|
||||
{0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
|
||||
{0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},
|
||||
{0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},
|
||||
{0x1E8D0, 0x1E8D6},
|
||||
{0x1E08F, 0x1E08F}, {0x1E8D0, 0x1E8D6},
|
||||
}
|
||||
|
||||
var doublewidth = table{
|
||||
|
|
@ -33,33 +34,34 @@ var doublewidth = table{
|
|||
{0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
|
||||
{0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
|
||||
{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
|
||||
{0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},
|
||||
{0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF},
|
||||
{0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3},
|
||||
{0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x4DBF},
|
||||
{0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
|
||||
{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19},
|
||||
{0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B},
|
||||
{0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4},
|
||||
{0x16FF0, 0x16FF1}, {0x17000, 0x187F7}, {0x18800, 0x18CD5},
|
||||
{0x18D00, 0x18D08}, {0x1B000, 0x1B11E}, {0x1B150, 0x1B152},
|
||||
{0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1F004, 0x1F004},
|
||||
{0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
|
||||
{0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
|
||||
{0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F320},
|
||||
{0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393},
|
||||
{0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0},
|
||||
{0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440},
|
||||
{0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E},
|
||||
{0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596},
|
||||
{0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5},
|
||||
{0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D7},
|
||||
{0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB},
|
||||
{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F978},
|
||||
{0x1F97A, 0x1F9CB}, {0x1F9CD, 0x1F9FF}, {0x1FA70, 0x1FA74},
|
||||
{0x1FA78, 0x1FA7A}, {0x1FA80, 0x1FA86}, {0x1FA90, 0x1FAA8},
|
||||
{0x1FAB0, 0x1FAB6}, {0x1FAC0, 0x1FAC2}, {0x1FAD0, 0x1FAD6},
|
||||
{0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
|
||||
{0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x303E},
|
||||
{0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312F},
|
||||
{0x3131, 0x318E}, {0x3190, 0x31E3}, {0x31EF, 0x321E},
|
||||
{0x3220, 0x3247}, {0x3250, 0x4DBF}, {0x4E00, 0xA48C},
|
||||
{0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3},
|
||||
{0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
|
||||
{0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60},
|
||||
{0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF1},
|
||||
{0x17000, 0x187F7}, {0x18800, 0x18CD5}, {0x18D00, 0x18D08},
|
||||
{0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE},
|
||||
{0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152},
|
||||
{0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB},
|
||||
{0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E},
|
||||
{0x1F191, 0x1F19A}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23B},
|
||||
{0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265},
|
||||
{0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C},
|
||||
{0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3},
|
||||
{0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E},
|
||||
{0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D},
|
||||
{0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A},
|
||||
{0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F},
|
||||
{0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2},
|
||||
{0x1F6D5, 0x1F6D7}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC},
|
||||
{0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0},
|
||||
{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF},
|
||||
{0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA88}, {0x1FA90, 0x1FABD},
|
||||
{0x1FABF, 0x1FAC5}, {0x1FACE, 0x1FADB}, {0x1FAE0, 0x1FAE8},
|
||||
{0x1FAF0, 0x1FAF8}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
|
||||
}
|
||||
|
||||
var ambiguous = table{
|
||||
|
|
@ -154,43 +156,43 @@ var neutral = table{
|
|||
{0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},
|
||||
{0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F},
|
||||
{0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4},
|
||||
{0x0600, 0x061C}, {0x061E, 0x070D}, {0x070F, 0x074A},
|
||||
{0x074D, 0x07B1}, {0x07C0, 0x07FA}, {0x07FD, 0x082D},
|
||||
{0x0830, 0x083E}, {0x0840, 0x085B}, {0x085E, 0x085E},
|
||||
{0x0860, 0x086A}, {0x08A0, 0x08B4}, {0x08B6, 0x08C7},
|
||||
{0x08D3, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990},
|
||||
{0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2},
|
||||
{0x09B6, 0x09B9}, {0x09BC, 0x09C4}, {0x09C7, 0x09C8},
|
||||
{0x09CB, 0x09CE}, {0x09D7, 0x09D7}, {0x09DC, 0x09DD},
|
||||
{0x09DF, 0x09E3}, {0x09E6, 0x09FE}, {0x0A01, 0x0A03},
|
||||
{0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28},
|
||||
{0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36},
|
||||
{0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42},
|
||||
{0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
|
||||
{0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76},
|
||||
{0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91},
|
||||
{0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3},
|
||||
{0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9},
|
||||
{0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3},
|
||||
{0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03},
|
||||
{0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28},
|
||||
{0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B35, 0x0B39},
|
||||
{0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D},
|
||||
{0x0B55, 0x0B57}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63},
|
||||
{0x0B66, 0x0B77}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A},
|
||||
{0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A},
|
||||
{0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4},
|
||||
{0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2},
|
||||
{0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0},
|
||||
{0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C},
|
||||
{0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C39},
|
||||
{0x0C3D, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
|
||||
{0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C63},
|
||||
{0x0600, 0x070D}, {0x070F, 0x074A}, {0x074D, 0x07B1},
|
||||
{0x07C0, 0x07FA}, {0x07FD, 0x082D}, {0x0830, 0x083E},
|
||||
{0x0840, 0x085B}, {0x085E, 0x085E}, {0x0860, 0x086A},
|
||||
{0x0870, 0x088E}, {0x0890, 0x0891}, {0x0898, 0x0983},
|
||||
{0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8},
|
||||
{0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9},
|
||||
{0x09BC, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CE},
|
||||
{0x09D7, 0x09D7}, {0x09DC, 0x09DD}, {0x09DF, 0x09E3},
|
||||
{0x09E6, 0x09FE}, {0x0A01, 0x0A03}, {0x0A05, 0x0A0A},
|
||||
{0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30},
|
||||
{0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39},
|
||||
{0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, {0x0A47, 0x0A48},
|
||||
{0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, {0x0A59, 0x0A5C},
|
||||
{0x0A5E, 0x0A5E}, {0x0A66, 0x0A76}, {0x0A81, 0x0A83},
|
||||
{0x0A85, 0x0A8D}, {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8},
|
||||
{0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9},
|
||||
{0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9}, {0x0ACB, 0x0ACD},
|
||||
{0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3}, {0x0AE6, 0x0AF1},
|
||||
{0x0AF9, 0x0AFF}, {0x0B01, 0x0B03}, {0x0B05, 0x0B0C},
|
||||
{0x0B0F, 0x0B10}, {0x0B13, 0x0B28}, {0x0B2A, 0x0B30},
|
||||
{0x0B32, 0x0B33}, {0x0B35, 0x0B39}, {0x0B3C, 0x0B44},
|
||||
{0x0B47, 0x0B48}, {0x0B4B, 0x0B4D}, {0x0B55, 0x0B57},
|
||||
{0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63}, {0x0B66, 0x0B77},
|
||||
{0x0B82, 0x0B83}, {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90},
|
||||
{0x0B92, 0x0B95}, {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C},
|
||||
{0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA},
|
||||
{0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8},
|
||||
{0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7},
|
||||
{0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C}, {0x0C0E, 0x0C10},
|
||||
{0x0C12, 0x0C28}, {0x0C2A, 0x0C39}, {0x0C3C, 0x0C44},
|
||||
{0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56},
|
||||
{0x0C58, 0x0C5A}, {0x0C5D, 0x0C5D}, {0x0C60, 0x0C63},
|
||||
{0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90},
|
||||
{0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
|
||||
{0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
|
||||
{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3},
|
||||
{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D00, 0x0D0C},
|
||||
{0x0CD5, 0x0CD6}, {0x0CDD, 0x0CDE}, {0x0CE0, 0x0CE3},
|
||||
{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF3}, {0x0D00, 0x0D0C},
|
||||
{0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48},
|
||||
{0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F},
|
||||
{0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1},
|
||||
|
|
@ -200,7 +202,7 @@ var neutral = table{
|
|||
{0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82},
|
||||
{0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3},
|
||||
{0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4},
|
||||
{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9},
|
||||
{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECE}, {0x0ED0, 0x0ED9},
|
||||
{0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
|
||||
{0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
|
||||
{0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
|
||||
|
|
@ -212,20 +214,19 @@ var neutral = table{
|
|||
{0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
|
||||
{0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
|
||||
{0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
|
||||
{0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736},
|
||||
{0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
|
||||
{0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9},
|
||||
{0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819},
|
||||
{0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5},
|
||||
{0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B},
|
||||
{0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974},
|
||||
{0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA},
|
||||
{0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C},
|
||||
{0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD},
|
||||
{0x1AB0, 0x1AC0}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C},
|
||||
{0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49},
|
||||
{0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7},
|
||||
{0x1CD0, 0x1CFA}, {0x1D00, 0x1DF9}, {0x1DFB, 0x1F15},
|
||||
{0x1700, 0x1715}, {0x171F, 0x1736}, {0x1740, 0x1753},
|
||||
{0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773},
|
||||
{0x1780, 0x17DD}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9},
|
||||
{0x1800, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA},
|
||||
{0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B},
|
||||
{0x1930, 0x193B}, {0x1940, 0x1940}, {0x1944, 0x196D},
|
||||
{0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9},
|
||||
{0x19D0, 0x19DA}, {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E},
|
||||
{0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99},
|
||||
{0x1AA0, 0x1AAD}, {0x1AB0, 0x1ACE}, {0x1B00, 0x1B4C},
|
||||
{0x1B50, 0x1B7E}, {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37},
|
||||
{0x1C3B, 0x1C49}, {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA},
|
||||
{0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, {0x1D00, 0x1F15},
|
||||
{0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
|
||||
{0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
|
||||
{0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
|
||||
|
|
@ -237,7 +238,7 @@ var neutral = table{
|
|||
{0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
|
||||
{0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
|
||||
{0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
|
||||
{0x20AA, 0x20AB}, {0x20AD, 0x20BF}, {0x20D0, 0x20F0},
|
||||
{0x20AA, 0x20AB}, {0x20AD, 0x20C0}, {0x20D0, 0x20F0},
|
||||
{0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
|
||||
{0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
|
||||
{0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
|
||||
|
|
@ -275,15 +276,15 @@ var neutral = table{
|
|||
{0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE},
|
||||
{0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A},
|
||||
{0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73},
|
||||
{0x2B76, 0x2B95}, {0x2B97, 0x2C2E}, {0x2C30, 0x2C5E},
|
||||
{0x2C60, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27},
|
||||
{0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70},
|
||||
{0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE},
|
||||
{0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6},
|
||||
{0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE},
|
||||
{0x2DE0, 0x2E52}, {0x303F, 0x303F}, {0x4DC0, 0x4DFF},
|
||||
{0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7BF},
|
||||
{0xA7C2, 0xA7CA}, {0xA7F5, 0xA82C}, {0xA830, 0xA839},
|
||||
{0x2B76, 0x2B95}, {0x2B97, 0x2CF3}, {0x2CF9, 0x2D25},
|
||||
{0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67},
|
||||
{0x2D6F, 0x2D70}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6},
|
||||
{0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE},
|
||||
{0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6},
|
||||
{0x2DD8, 0x2DDE}, {0x2DE0, 0x2E5D}, {0x303F, 0x303F},
|
||||
{0x4DC0, 0x4DFF}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7},
|
||||
{0xA700, 0xA7CA}, {0xA7D0, 0xA7D1}, {0xA7D3, 0xA7D3},
|
||||
{0xA7D5, 0xA7D9}, {0xA7F2, 0xA82C}, {0xA830, 0xA839},
|
||||
{0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9},
|
||||
{0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
|
||||
{0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
|
||||
|
|
@ -294,8 +295,8 @@ var neutral = table{
|
|||
{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
|
||||
{0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
|
||||
{0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
|
||||
{0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F},
|
||||
{0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD},
|
||||
{0xFB43, 0xFB44}, {0xFB46, 0xFBC2}, {0xFBD3, 0xFD8F},
|
||||
{0xFD92, 0xFDC7}, {0xFDCF, 0xFDCF}, {0xFDF0, 0xFDFF},
|
||||
{0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
|
||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
|
||||
{0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
|
||||
|
|
@ -307,44 +308,48 @@ var neutral = table{
|
|||
{0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
|
||||
{0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
|
||||
{0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},
|
||||
{0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
|
||||
{0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},
|
||||
{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},
|
||||
{0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7},
|
||||
{0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},
|
||||
{0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35},
|
||||
{0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58},
|
||||
{0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},
|
||||
{0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},
|
||||
{0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
|
||||
{0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
|
||||
{0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10E60, 0x10E7E},
|
||||
{0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1},
|
||||
{0x10F00, 0x10F27}, {0x10F30, 0x10F59}, {0x10FB0, 0x10FCB},
|
||||
{0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x1106F},
|
||||
{0x1107F, 0x110C1}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8},
|
||||
{0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147},
|
||||
{0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1123E}, {0x11280, 0x11286},
|
||||
{0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D},
|
||||
{0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9},
|
||||
{0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},
|
||||
{0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},
|
||||
{0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348},
|
||||
{0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357},
|
||||
{0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
|
||||
{0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7},
|
||||
{0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD},
|
||||
{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},
|
||||
{0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x11700, 0x1171A},
|
||||
{0x1171D, 0x1172B}, {0x11730, 0x1173F}, {0x11800, 0x1183B},
|
||||
{0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909},
|
||||
{0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935},
|
||||
{0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959},
|
||||
{0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4},
|
||||
{0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AC0, 0x11AF8},
|
||||
{0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592},
|
||||
{0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1},
|
||||
{0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10600, 0x10736},
|
||||
{0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785},
|
||||
{0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805},
|
||||
{0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838},
|
||||
{0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E},
|
||||
{0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5},
|
||||
{0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x1093F},
|
||||
{0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A03},
|
||||
{0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17},
|
||||
{0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48},
|
||||
{0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6},
|
||||
{0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55},
|
||||
{0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C},
|
||||
{0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2},
|
||||
{0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, {0x10D30, 0x10D39},
|
||||
{0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD},
|
||||
{0x10EB0, 0x10EB1}, {0x10EFD, 0x10F27}, {0x10F30, 0x10F59},
|
||||
{0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6},
|
||||
{0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110C2},
|
||||
{0x110CD, 0x110CD}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9},
|
||||
{0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176},
|
||||
{0x11180, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211},
|
||||
{0x11213, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288},
|
||||
{0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9},
|
||||
{0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303},
|
||||
{0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328},
|
||||
{0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339},
|
||||
{0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D},
|
||||
{0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363},
|
||||
{0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x1145B},
|
||||
{0x1145D, 0x11461}, {0x11480, 0x114C7}, {0x114D0, 0x114D9},
|
||||
{0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644},
|
||||
{0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B9},
|
||||
{0x116C0, 0x116C9}, {0x11700, 0x1171A}, {0x1171D, 0x1172B},
|
||||
{0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2},
|
||||
{0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913},
|
||||
{0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938},
|
||||
{0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7},
|
||||
{0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47},
|
||||
{0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09},
|
||||
{0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},
|
||||
{0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},
|
||||
{0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
|
||||
|
|
@ -352,30 +357,36 @@ var neutral = table{
|
|||
{0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},
|
||||
{0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},
|
||||
{0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8},
|
||||
{0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F59},
|
||||
{0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},
|
||||
{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342E}, {0x13430, 0x13438}, {0x14400, 0x14646},
|
||||
{0x12F90, 0x12FF2}, {0x13000, 0x13455}, {0x14400, 0x14646},
|
||||
{0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},
|
||||
{0x16A6E, 0x16A6F}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5},
|
||||
{0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
|
||||
{0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A},
|
||||
{0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F},
|
||||
{0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88},
|
||||
{0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1D000, 0x1D0F5},
|
||||
{0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, {0x1D200, 0x1D245},
|
||||
{0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378},
|
||||
{0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F},
|
||||
{0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC},
|
||||
{0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3},
|
||||
{0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514},
|
||||
{0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E},
|
||||
{0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550},
|
||||
{0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B},
|
||||
{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
|
||||
{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
|
||||
{0x1E026, 0x1E02A}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
|
||||
{0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E2C0, 0x1E2F9},
|
||||
{0x1E2FF, 0x1E2FF}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
|
||||
{0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED},
|
||||
{0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59},
|
||||
{0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F},
|
||||
{0x16E40, 0x16E9A}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87},
|
||||
{0x16F8F, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
|
||||
{0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3},
|
||||
{0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3},
|
||||
{0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1EA},
|
||||
{0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3},
|
||||
{0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454},
|
||||
{0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2},
|
||||
{0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9},
|
||||
{0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505},
|
||||
{0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C},
|
||||
{0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544},
|
||||
{0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5},
|
||||
{0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F},
|
||||
{0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A},
|
||||
{0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
|
||||
{0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D},
|
||||
{0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
|
||||
{0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE},
|
||||
{0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9},
|
||||
{0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE},
|
||||
{0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
|
||||
{0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
|
||||
{0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03},
|
||||
{0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24},
|
||||
|
|
@ -400,8 +411,8 @@ var neutral = table{
|
|||
{0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
|
||||
{0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
|
||||
{0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4},
|
||||
{0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773},
|
||||
{0x1F780, 0x1F7D8}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
|
||||
{0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F776},
|
||||
{0x1F77B, 0x1F7D9}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
|
||||
{0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
|
||||
{0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B},
|
||||
{0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D},
|
||||
|
|
|
|||
131
vendor/github.com/rs/zerolog/log/log.go
generated
vendored
Normal file
131
vendor/github.com/rs/zerolog/log/log.go
generated
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
// Package log provides a global logger for zerolog.
|
||||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// Logger is the global logger.
|
||||
var Logger = zerolog.New(os.Stderr).With().Timestamp().Logger()
|
||||
|
||||
// Output duplicates the global logger and sets w as its output.
|
||||
func Output(w io.Writer) zerolog.Logger {
|
||||
return Logger.Output(w)
|
||||
}
|
||||
|
||||
// With creates a child logger with the field added to its context.
|
||||
func With() zerolog.Context {
|
||||
return Logger.With()
|
||||
}
|
||||
|
||||
// Level creates a child logger with the minimum accepted level set to level.
|
||||
func Level(level zerolog.Level) zerolog.Logger {
|
||||
return Logger.Level(level)
|
||||
}
|
||||
|
||||
// Sample returns a logger with the s sampler.
|
||||
func Sample(s zerolog.Sampler) zerolog.Logger {
|
||||
return Logger.Sample(s)
|
||||
}
|
||||
|
||||
// Hook returns a logger with the h Hook.
|
||||
func Hook(h zerolog.Hook) zerolog.Logger {
|
||||
return Logger.Hook(h)
|
||||
}
|
||||
|
||||
// Err starts a new message with error level with err as a field if not nil or
|
||||
// with info level if err is nil.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Err(err error) *zerolog.Event {
|
||||
return Logger.Err(err)
|
||||
}
|
||||
|
||||
// Trace starts a new message with trace level.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Trace() *zerolog.Event {
|
||||
return Logger.Trace()
|
||||
}
|
||||
|
||||
// Debug starts a new message with debug level.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Debug() *zerolog.Event {
|
||||
return Logger.Debug()
|
||||
}
|
||||
|
||||
// Info starts a new message with info level.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Info() *zerolog.Event {
|
||||
return Logger.Info()
|
||||
}
|
||||
|
||||
// Warn starts a new message with warn level.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Warn() *zerolog.Event {
|
||||
return Logger.Warn()
|
||||
}
|
||||
|
||||
// Error starts a new message with error level.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Error() *zerolog.Event {
|
||||
return Logger.Error()
|
||||
}
|
||||
|
||||
// Fatal starts a new message with fatal level. The os.Exit(1) function
|
||||
// is called by the Msg method.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Fatal() *zerolog.Event {
|
||||
return Logger.Fatal()
|
||||
}
|
||||
|
||||
// Panic starts a new message with panic level. The message is also sent
|
||||
// to the panic function.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Panic() *zerolog.Event {
|
||||
return Logger.Panic()
|
||||
}
|
||||
|
||||
// WithLevel starts a new message with level.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func WithLevel(level zerolog.Level) *zerolog.Event {
|
||||
return Logger.WithLevel(level)
|
||||
}
|
||||
|
||||
// Log starts a new message with no level. Setting zerolog.GlobalLevel to
|
||||
// zerolog.Disabled will still disable events produced by this method.
|
||||
//
|
||||
// You must call Msg on the returned event in order to send the event.
|
||||
func Log() *zerolog.Event {
|
||||
return Logger.Log()
|
||||
}
|
||||
|
||||
// Print sends a log event using debug level and no extra field.
|
||||
// Arguments are handled in the manner of fmt.Print.
|
||||
func Print(v ...interface{}) {
|
||||
Logger.Debug().CallerSkipFrame(1).Msg(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
// Printf sends a log event using debug level and no extra field.
|
||||
// Arguments are handled in the manner of fmt.Printf.
|
||||
func Printf(format string, v ...interface{}) {
|
||||
Logger.Debug().CallerSkipFrame(1).Msgf(format, v...)
|
||||
}
|
||||
|
||||
// Ctx returns the Logger associated with the ctx. If no logger
|
||||
// is associated, a disabled logger is returned.
|
||||
func Ctx(ctx context.Context) *zerolog.Logger {
|
||||
return zerolog.Ctx(ctx)
|
||||
}
|
||||
2
vendor/gitlab.com/etke.cc/linkpearl/.golangci.yml
generated
vendored
2
vendor/gitlab.com/etke.cc/linkpearl/.golangci.yml
generated
vendored
|
|
@ -63,7 +63,6 @@ linters-settings:
|
|||
time-layout: true
|
||||
crypto-hash: true
|
||||
default-rpc-path: true
|
||||
os-dev-null: true
|
||||
sql-isolation-level: true
|
||||
tls-signature-scheme: true
|
||||
constant-kind: true
|
||||
|
|
@ -86,7 +85,6 @@ linters:
|
|||
- errchkjson
|
||||
- errname
|
||||
- errorlint
|
||||
- execinquery
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- forcetypeassert
|
||||
|
|
|
|||
42
vendor/go.mau.fi/util/dbutil/connlog.go
vendored
42
vendor/go.mau.fi/util/dbutil/connlog.go
vendored
|
|
@ -10,6 +10,7 @@ import (
|
|||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -96,6 +97,14 @@ func (le *LoggingExecable) QueryRowContext(ctx context.Context, query string, ar
|
|||
return row
|
||||
}
|
||||
|
||||
func (le *LoggingExecable) beginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
|
||||
txBeginner, ok := le.UnderlyingExecable.(UnderlyingExecutableWithTx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("can't start transaction with a %T", le.UnderlyingExecable)
|
||||
}
|
||||
return txBeginner.BeginTx(ctx, opts)
|
||||
}
|
||||
|
||||
// loggingDB is a wrapper for LoggingExecable that allows access to BeginTx.
|
||||
//
|
||||
// While LoggingExecable has a pointer to the database and could use BeginTx, it's not technically safe since
|
||||
|
|
@ -104,13 +113,36 @@ type loggingDB struct {
|
|||
LoggingExecable
|
||||
}
|
||||
|
||||
func (ld *loggingDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*LoggingTxn, error) {
|
||||
targetDB := ld.db.RawDB
|
||||
if opts != nil && opts.ReadOnly && ld.db.ReadOnlyDB != nil {
|
||||
targetDB = ld.db.ReadOnlyDB
|
||||
type internalTxnStarter interface {
|
||||
beginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
|
||||
}
|
||||
|
||||
type TxnOptions struct {
|
||||
Isolation sql.IsolationLevel
|
||||
ReadOnly bool
|
||||
Conn Conn
|
||||
}
|
||||
|
||||
func (ld *loggingDB) BeginTx(ctx context.Context, opts *TxnOptions) (*LoggingTxn, error) {
|
||||
if opts == nil {
|
||||
opts = &TxnOptions{}
|
||||
}
|
||||
sqlOpts := &sql.TxOptions{
|
||||
Isolation: opts.Isolation,
|
||||
ReadOnly: opts.ReadOnly,
|
||||
}
|
||||
var tx *sql.Tx
|
||||
var err error
|
||||
start := time.Now()
|
||||
tx, err := targetDB.BeginTx(ctx, opts)
|
||||
if opts.Conn != nil {
|
||||
tx, err = opts.Conn.beginTx(ctx, sqlOpts)
|
||||
} else {
|
||||
targetDB := ld.db.RawDB
|
||||
if opts.ReadOnly && ld.db.ReadOnlyDB != nil {
|
||||
targetDB = ld.db.ReadOnlyDB
|
||||
}
|
||||
tx, err = targetDB.BeginTx(ctx, sqlOpts)
|
||||
}
|
||||
ld.db.Log.QueryTiming(ctx, "Begin", "", nil, -1, time.Since(start), err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
20
vendor/go.mau.fi/util/dbutil/database.go
vendored
20
vendor/go.mau.fi/util/dbutil/database.go
vendored
|
|
@ -73,12 +73,22 @@ type UnderlyingExecable interface {
|
|||
QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
|
||||
}
|
||||
|
||||
type UnderlyingExecutableWithTx interface {
|
||||
UnderlyingExecable
|
||||
BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
|
||||
}
|
||||
|
||||
type Execable interface {
|
||||
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
|
||||
QueryContext(ctx context.Context, query string, args ...any) (Rows, error)
|
||||
QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
|
||||
}
|
||||
|
||||
type Conn interface {
|
||||
Execable
|
||||
internalTxnStarter
|
||||
}
|
||||
|
||||
type Transaction interface {
|
||||
Execable
|
||||
Commit() error
|
||||
|
|
@ -87,11 +97,11 @@ type Transaction interface {
|
|||
|
||||
// Expected implementations of Execable
|
||||
var (
|
||||
_ UnderlyingExecable = (*sql.Tx)(nil)
|
||||
_ UnderlyingExecable = (*sql.DB)(nil)
|
||||
_ UnderlyingExecable = (*sql.Conn)(nil)
|
||||
_ Execable = (*LoggingExecable)(nil)
|
||||
_ Transaction = (*LoggingTxn)(nil)
|
||||
_ UnderlyingExecable = (*sql.Tx)(nil)
|
||||
_ UnderlyingExecutableWithTx = (*sql.DB)(nil)
|
||||
_ UnderlyingExecutableWithTx = (*sql.Conn)(nil)
|
||||
_ Execable = (*LoggingExecable)(nil)
|
||||
_ Transaction = (*LoggingTxn)(nil)
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
|
|
|
|||
41
vendor/go.mau.fi/util/dbutil/iter.go
vendored
41
vendor/go.mau.fi/util/dbutil/iter.go
vendored
|
|
@ -6,7 +6,13 @@
|
|||
|
||||
package dbutil
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"go.mau.fi/util/exzerolog"
|
||||
)
|
||||
|
||||
var ErrAlreadyIterated = errors.New("this iterator has been already iterated")
|
||||
|
||||
|
|
@ -39,24 +45,38 @@ type ConvertRowFn[T any] func(Scannable) (T, error)
|
|||
// )
|
||||
// }
|
||||
func (crf ConvertRowFn[T]) NewRowIter(rows Rows, err error) RowIter[T] {
|
||||
return NewRowIterWithError(rows, crf, err)
|
||||
return newRowIterWithError(rows, crf, err)
|
||||
}
|
||||
|
||||
type rowIterImpl[T any] struct {
|
||||
Rows
|
||||
ConvertRow ConvertRowFn[T]
|
||||
|
||||
err error
|
||||
iterated bool
|
||||
caller string
|
||||
err error
|
||||
}
|
||||
|
||||
// NewRowIter creates a new RowIter from the given Rows and scanner function.
|
||||
func NewRowIter[T any](rows Rows, convertFn ConvertRowFn[T]) RowIter[T] {
|
||||
return &rowIterImpl[T]{Rows: rows, ConvertRow: convertFn}
|
||||
return newRowIterWithError(rows, convertFn, nil)
|
||||
}
|
||||
|
||||
// NewRowIterWithError creates a new RowIter from the given Rows and scanner function with default error. If not nil, it will be returned without calling iterator function.
|
||||
func NewRowIterWithError[T any](rows Rows, convertFn ConvertRowFn[T], err error) RowIter[T] {
|
||||
return &rowIterImpl[T]{Rows: rows, ConvertRow: convertFn, err: err}
|
||||
return newRowIterWithError(rows, convertFn, err)
|
||||
}
|
||||
|
||||
func newRowIterWithError[T any](rows Rows, convertFn ConvertRowFn[T], err error) RowIter[T] {
|
||||
ri := &rowIterImpl[T]{Rows: rows, ConvertRow: convertFn, err: err}
|
||||
if err == nil {
|
||||
callerSkip := 2
|
||||
if pc, file, line, ok := runtime.Caller(callerSkip); ok {
|
||||
ri.caller = exzerolog.CallerWithFunctionName(pc, file, line)
|
||||
}
|
||||
runtime.SetFinalizer(ri, (*rowIterImpl[T]).destroy)
|
||||
}
|
||||
return ri
|
||||
}
|
||||
|
||||
func ScanSingleColumn[T any](rows Scannable) (val T, err error) {
|
||||
|
|
@ -74,13 +94,22 @@ func ScanDataStruct[T NewableDataStruct[T]](rows Scannable) (T, error) {
|
|||
return val.New().Scan(rows)
|
||||
}
|
||||
|
||||
func (i *rowIterImpl[T]) destroy() {
|
||||
if !i.iterated {
|
||||
panic(fmt.Errorf("RowIter created at %s wasn't iterated", i.caller))
|
||||
}
|
||||
}
|
||||
|
||||
func (i *rowIterImpl[T]) Iter(fn func(T) (bool, error)) error {
|
||||
if i == nil {
|
||||
return nil
|
||||
} else if i.Rows == nil || i.err != nil {
|
||||
return i.err
|
||||
}
|
||||
defer i.Rows.Close()
|
||||
defer func() {
|
||||
_ = i.Rows.Close()
|
||||
i.iterated = true
|
||||
}()
|
||||
|
||||
for i.Rows.Next() {
|
||||
if item, err := i.ConvertRow(i.Rows); err != nil {
|
||||
|
|
|
|||
14
vendor/go.mau.fi/util/dbutil/log.go
vendored
14
vendor/go.mau.fi/util/dbutil/log.go
vendored
|
|
@ -13,7 +13,7 @@ type DatabaseLogger interface {
|
|||
QueryTiming(ctx context.Context, method, query string, args []any, nrows int, duration time.Duration, err error)
|
||||
WarnUnsupportedVersion(current, compat, latest int)
|
||||
PrepareUpgrade(current, compat, latest int)
|
||||
DoUpgrade(from, to int, message string, txn bool)
|
||||
DoUpgrade(from, to int, message string, txn TxnMode)
|
||||
// Deprecated: legacy warning method, return errors instead
|
||||
Warn(msg string, args ...any)
|
||||
}
|
||||
|
|
@ -22,10 +22,10 @@ type noopLogger struct{}
|
|||
|
||||
var NoopLogger DatabaseLogger = &noopLogger{}
|
||||
|
||||
func (n noopLogger) WarnUnsupportedVersion(_, _, _ int) {}
|
||||
func (n noopLogger) PrepareUpgrade(_, _, _ int) {}
|
||||
func (n noopLogger) DoUpgrade(_, _ int, _ string, _ bool) {}
|
||||
func (n noopLogger) Warn(msg string, args ...any) {}
|
||||
func (n noopLogger) WarnUnsupportedVersion(_, _, _ int) {}
|
||||
func (n noopLogger) PrepareUpgrade(_, _, _ int) {}
|
||||
func (n noopLogger) DoUpgrade(_, _ int, _ string, _ TxnMode) {}
|
||||
func (n noopLogger) Warn(msg string, args ...any) {}
|
||||
|
||||
func (n noopLogger) QueryTiming(_ context.Context, _, _ string, _ []any, _ int, _ time.Duration, _ error) {
|
||||
}
|
||||
|
|
@ -81,11 +81,11 @@ func (z zeroLogger) PrepareUpgrade(current, compat, latest int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (z zeroLogger) DoUpgrade(from, to int, message string, txn bool) {
|
||||
func (z zeroLogger) DoUpgrade(from, to int, message string, txn TxnMode) {
|
||||
z.l.Info().
|
||||
Int("from", from).
|
||||
Int("to", to).
|
||||
Bool("single_txn", txn).
|
||||
Str("txn_mode", string(txn)).
|
||||
Str("description", message).
|
||||
Msg("Upgrading database")
|
||||
}
|
||||
|
|
|
|||
2
vendor/go.mau.fi/util/dbutil/queryhelper.go
vendored
2
vendor/go.mau.fi/util/dbutil/queryhelper.go
vendored
|
|
@ -117,7 +117,7 @@ func (qh *QueryHelper[T]) scanNew(row Scannable) (T, error) {
|
|||
func (qh *QueryHelper[T]) QueryOne(ctx context.Context, query string, args ...any) (val T, err error) {
|
||||
val, err = qh.scanNew(qh.db.QueryRow(ctx, query, args...))
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
return *new(T), nil
|
||||
}
|
||||
return val, err
|
||||
}
|
||||
|
|
|
|||
30
vendor/go.mau.fi/util/dbutil/transaction.go
vendored
30
vendor/go.mau.fi/util/dbutil/transaction.go
vendored
|
|
@ -40,25 +40,25 @@ func init() {
|
|||
}
|
||||
|
||||
func (db *Database) Exec(ctx context.Context, query string, args ...any) (sql.Result, error) {
|
||||
return db.Conn(ctx).ExecContext(ctx, query, args...)
|
||||
return db.Execable(ctx).ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *Database) Query(ctx context.Context, query string, args ...any) (Rows, error) {
|
||||
return db.Conn(ctx).QueryContext(ctx, query, args...)
|
||||
return db.Execable(ctx).QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *Database) QueryRow(ctx context.Context, query string, args ...any) *sql.Row {
|
||||
return db.Conn(ctx).QueryRowContext(ctx, query, args...)
|
||||
return db.Execable(ctx).QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *Database) BeginTx(ctx context.Context, opts *sql.TxOptions) (*LoggingTxn, error) {
|
||||
func (db *Database) BeginTx(ctx context.Context, opts *TxnOptions) (*LoggingTxn, error) {
|
||||
if ctx == nil {
|
||||
panic("BeginTx() called with nil ctx")
|
||||
}
|
||||
return db.LoggingDB.BeginTx(ctx, opts)
|
||||
}
|
||||
|
||||
func (db *Database) DoTxn(ctx context.Context, opts *sql.TxOptions, fn func(ctx context.Context) error) error {
|
||||
func (db *Database) DoTxn(ctx context.Context, opts *TxnOptions, fn func(ctx context.Context) error) error {
|
||||
if ctx == nil {
|
||||
panic("DoTxn() called with nil ctx")
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ func (db *Database) DoTxn(ctx context.Context, opts *sql.TxOptions, fn func(ctx
|
|||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) Conn(ctx context.Context) Execable {
|
||||
func (db *Database) Execable(ctx context.Context) Execable {
|
||||
if ctx == nil {
|
||||
panic("Conn() called with nil ctx")
|
||||
}
|
||||
|
|
@ -143,3 +143,21 @@ func (db *Database) Conn(ctx context.Context) Execable {
|
|||
}
|
||||
return &db.LoggingDB
|
||||
}
|
||||
|
||||
func (db *Database) AcquireConn(ctx context.Context) (Conn, error) {
|
||||
if ctx == nil {
|
||||
return nil, fmt.Errorf("AcquireConn() called with nil ctx")
|
||||
}
|
||||
_, ok := ctx.Value(db.txnCtxKey).(Transaction)
|
||||
if ok {
|
||||
return nil, fmt.Errorf("cannot acquire connection while in a transaction")
|
||||
}
|
||||
conn, err := db.RawDB.Conn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &LoggingExecable{
|
||||
UnderlyingExecable: conn,
|
||||
db: db,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
51
vendor/go.mau.fi/util/dbutil/upgrades.go
vendored
51
vendor/go.mau.fi/util/dbutil/upgrades.go
vendored
|
|
@ -21,7 +21,11 @@ type upgrade struct {
|
|||
|
||||
upgradesTo int
|
||||
compatVersion int
|
||||
transaction bool
|
||||
transaction TxnMode
|
||||
}
|
||||
|
||||
func (u *upgrade) DangerouslyRun(ctx context.Context, db *Database) (upgradesTo, compat int, err error) {
|
||||
return u.upgradesTo, u.compatVersion, u.fn(ctx, db)
|
||||
}
|
||||
|
||||
var ErrUnsupportedDatabaseVersion = errors.New("unsupported database schema version")
|
||||
|
|
@ -153,6 +157,37 @@ func (db *Database) setVersion(ctx context.Context, version, compat int) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (db *Database) DoSQLiteTransactionWithoutForeignKeys(ctx context.Context, doUpgrade func(context.Context) error) error {
|
||||
conn, err := db.AcquireConn(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to acquire connection: %w", err)
|
||||
}
|
||||
_, err = conn.ExecContext(ctx, "PRAGMA foreign_keys=OFF")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to disable foreign keys: %w", err)
|
||||
}
|
||||
err = db.DoTxn(ctx, &TxnOptions{Conn: conn}, func(ctx context.Context) error {
|
||||
err := doUpgrade(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = conn.ExecContext(ctx, "PRAGMA foreign_key_check")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check foreign keys after upgrade: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
_, _ = conn.ExecContext(ctx, "PRAGMA foreign_keys=ON")
|
||||
return err
|
||||
}
|
||||
_, err = conn.ExecContext(ctx, "PRAGMA foreign_keys=ON")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to enable foreign keys: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) Upgrade(ctx context.Context) error {
|
||||
err := db.checkDatabaseOwner(ctx)
|
||||
if err != nil {
|
||||
|
|
@ -194,10 +229,18 @@ func (db *Database) Upgrade(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
db.Log.DoUpgrade(logVersion, upgradeItem.upgradesTo, upgradeItem.message, upgradeItem.transaction)
|
||||
if upgradeItem.transaction {
|
||||
err = db.DoTxn(ctx, nil, doUpgrade)
|
||||
} else {
|
||||
switch upgradeItem.transaction {
|
||||
case TxnModeOff:
|
||||
err = doUpgrade(ctx)
|
||||
case TxnModeOn:
|
||||
err = db.DoTxn(ctx, nil, doUpgrade)
|
||||
case TxnModeSQLiteForeignKeysOff:
|
||||
switch db.Dialect {
|
||||
case SQLite:
|
||||
err = db.DoSQLiteTransactionWithoutForeignKeys(ctx, doUpgrade)
|
||||
default:
|
||||
err = db.DoTxn(ctx, nil, doUpgrade)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
35
vendor/go.mau.fi/util/dbutil/upgradetable.go
vendored
35
vendor/go.mau.fi/util/dbutil/upgradetable.go
vendored
|
|
@ -18,6 +18,14 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type TxnMode string
|
||||
|
||||
const (
|
||||
TxnModeOn TxnMode = "on"
|
||||
TxnModeOff TxnMode = "off"
|
||||
TxnModeSQLiteForeignKeysOff TxnMode = "sqlite-fkey-off"
|
||||
)
|
||||
|
||||
type UpgradeTable []upgrade
|
||||
|
||||
func (ut *UpgradeTable) extend(toSize int) {
|
||||
|
|
@ -30,7 +38,7 @@ func (ut *UpgradeTable) extend(toSize int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ut *UpgradeTable) Register(from, to, compat int, message string, txn bool, fn upgradeFunc) {
|
||||
func (ut *UpgradeTable) Register(from, to, compat int, message string, txn TxnMode, fn upgradeFunc) {
|
||||
if from < 0 {
|
||||
from += to
|
||||
}
|
||||
|
|
@ -72,7 +80,7 @@ var upgradeHeaderRegex = regexp.MustCompile(`^-- (?:v(\d+) -> )?v(\d+)(?: \(comp
|
|||
// // do dangerous stuff
|
||||
var transactionDisableRegex = regexp.MustCompile(`^-- transaction: (\w*)`)
|
||||
|
||||
func parseFileHeader(file []byte) (from, to, compat int, message string, txn bool, lines [][]byte, err error) {
|
||||
func parseFileHeader(file []byte) (from, to, compat int, message string, txn TxnMode, lines [][]byte, err error) {
|
||||
lines = bytes.Split(file, []byte("\n"))
|
||||
if len(lines) < 2 {
|
||||
err = errors.New("upgrade file too short")
|
||||
|
|
@ -99,14 +107,17 @@ func parseFileHeader(file []byte) (from, to, compat int, message string, txn boo
|
|||
from = -1
|
||||
}
|
||||
message = string(match[4])
|
||||
txn = true
|
||||
txn = "on"
|
||||
match = transactionDisableRegex.FindSubmatch(lines[0])
|
||||
if match != nil {
|
||||
lines = lines[1:]
|
||||
if string(match[1]) != "off" {
|
||||
txn = TxnMode(match[1])
|
||||
switch txn {
|
||||
case TxnModeOff, TxnModeOn, TxnModeSQLiteForeignKeysOff:
|
||||
// ok
|
||||
default:
|
||||
err = fmt.Errorf("invalid value %q for transaction flag", match[1])
|
||||
}
|
||||
txn = false
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -157,6 +168,16 @@ func (db *Database) parseDialectFilter(line []byte) (dialect Dialect, lineCount
|
|||
|
||||
var endLineFilter = regexp.MustCompile(`^\s*-- end only (postgres|sqlite)$`)
|
||||
|
||||
func (db *Database) Internals() *publishDatabaseInternals {
|
||||
return (*publishDatabaseInternals)(db)
|
||||
}
|
||||
|
||||
type publishDatabaseInternals Database
|
||||
|
||||
func (di *publishDatabaseInternals) FilterSQLUpgrade(lines [][]byte) (string, error) {
|
||||
return (*Database)(di).filterSQLUpgrade(lines)
|
||||
}
|
||||
|
||||
func (db *Database) filterSQLUpgrade(lines [][]byte) (string, error) {
|
||||
output := make([][]byte, 0, len(lines))
|
||||
for i := 0; i < len(lines); i++ {
|
||||
|
|
@ -235,7 +256,7 @@ func splitSQLUpgradeFunc(sqliteData, postgresData string) upgradeFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func parseSplitSQLUpgrade(name string, fs fullFS, skipNames map[string]struct{}) (from, to, compat int, message string, txn bool, fn upgradeFunc) {
|
||||
func parseSplitSQLUpgrade(name string, fs fullFS, skipNames map[string]struct{}) (from, to, compat int, message string, txn TxnMode, fn upgradeFunc) {
|
||||
postgresName := fmt.Sprintf("%s.postgres.sql", name)
|
||||
sqliteName := fmt.Sprintf("%s.sqlite.sql", name)
|
||||
skipNames[postgresName] = struct{}{}
|
||||
|
|
@ -261,7 +282,7 @@ func parseSplitSQLUpgrade(name string, fs fullFS, skipNames map[string]struct{})
|
|||
} else if message != sqliteMessage {
|
||||
panic(fmt.Errorf("mismatching message in postgres and sqlite versions of %s: %q != %q", name, message, sqliteMessage))
|
||||
} else if txn != sqliteTxn {
|
||||
panic(fmt.Errorf("mismatching transaction flag in postgres and sqlite versions of %s: %t != %t", name, txn, sqliteTxn))
|
||||
panic(fmt.Errorf("mismatching transaction flag in postgres and sqlite versions of %s: %s != %s", name, txn, sqliteTxn))
|
||||
}
|
||||
fn = splitSQLUpgradeFunc(string(sqliteData), string(postgresData))
|
||||
return
|
||||
|
|
|
|||
28
vendor/go.mau.fi/util/exzerolog/callermarshal.go
vendored
Normal file
28
vendor/go.mau.fi/util/exzerolog/callermarshal.go
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2023 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package exzerolog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CallerWithFunctionName is an implementation for zerolog.CallerMarshalFunc that includes the caller function name
|
||||
// in addition to the file and line number.
|
||||
//
|
||||
// Use as
|
||||
//
|
||||
// zerolog.CallerMarshalFunc = exzerolog.CallerWithFunctionName
|
||||
func CallerWithFunctionName(pc uintptr, file string, line int) string {
|
||||
files := strings.Split(file, "/")
|
||||
file = files[len(files)-1]
|
||||
name := runtime.FuncForPC(pc).Name()
|
||||
fns := strings.Split(name, ".")
|
||||
name = fns[len(fns)-1]
|
||||
return fmt.Sprintf("%s:%d:%s()", file, line, name)
|
||||
}
|
||||
32
vendor/go.mau.fi/util/exzerolog/defaults.go
vendored
Normal file
32
vendor/go.mau.fi/util/exzerolog/defaults.go
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2024 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package exzerolog
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
deflog "github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// SetupDefaults updates zerolog globals with sensible defaults.
|
||||
//
|
||||
// * [zerolog.TimeFieldFormat] is set to time.RFC3339Nano instead of time.RFC3339
|
||||
// * [zerolog.CallerMarshalFunc] is set to [CallerWithFunctionName]
|
||||
// * [zerolog.DefaultContextLogger] is set to the given logger with default_context_log=true and caller info enabled
|
||||
// * The global default [log.Logger] is set to the given logger with global_log=true and caller info enabled
|
||||
// * [zerolog.LevelColors] are updated to swap trace and debug level colors
|
||||
func SetupDefaults(log *zerolog.Logger) {
|
||||
zerolog.TimeFieldFormat = time.RFC3339Nano
|
||||
zerolog.CallerMarshalFunc = CallerWithFunctionName
|
||||
defaultCtxLog := log.With().Bool("default_context_log", true).Caller().Logger()
|
||||
zerolog.DefaultContextLogger = &defaultCtxLog
|
||||
deflog.Logger = log.With().Bool("global_log", true).Caller().Logger()
|
||||
// Swap trace and debug level colors so trace pops out the least
|
||||
zerolog.LevelColors[zerolog.TraceLevel] = 0
|
||||
zerolog.LevelColors[zerolog.DebugLevel] = 34 // blue
|
||||
}
|
||||
45
vendor/go.mau.fi/util/exzerolog/generics.go
vendored
Normal file
45
vendor/go.mau.fi/util/exzerolog/generics.go
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) 2023 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package exzerolog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
func ArrayOf[T any](slice []T, fn func(arr *zerolog.Array, item T)) *zerolog.Array {
|
||||
arr := zerolog.Arr()
|
||||
for _, item := range slice {
|
||||
fn(arr, item)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func AddObject[T zerolog.LogObjectMarshaler](arr *zerolog.Array, obj T) {
|
||||
arr.Object(obj)
|
||||
}
|
||||
|
||||
func AddStringer[T fmt.Stringer](arr *zerolog.Array, str T) {
|
||||
arr.Str(str.String())
|
||||
}
|
||||
|
||||
func AddStr[T ~string](arr *zerolog.Array, str T) {
|
||||
arr.Str(string(str))
|
||||
}
|
||||
|
||||
func ArrayOfObjs[T zerolog.LogObjectMarshaler](slice []T) *zerolog.Array {
|
||||
return ArrayOf(slice, AddObject[T])
|
||||
}
|
||||
|
||||
func ArrayOfStringers[T fmt.Stringer](slice []T) *zerolog.Array {
|
||||
return ArrayOf(slice, AddStringer[T])
|
||||
}
|
||||
|
||||
func ArrayOfStrs[T ~string](slice []T) *zerolog.Array {
|
||||
return ArrayOf(slice, AddStr[T])
|
||||
}
|
||||
81
vendor/go.mau.fi/util/exzerolog/writer.go
vendored
Normal file
81
vendor/go.mau.fi/util/exzerolog/writer.go
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
// Copyright (c) 2023 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package exzerolog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// LogWriter wraps a zerolog.Logger and provides an io.Writer with buffering so each written line is logged separately.
|
||||
type LogWriter struct {
|
||||
log zerolog.Logger
|
||||
level zerolog.Level
|
||||
field string
|
||||
mu sync.Mutex
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
func NewLogWriter(log zerolog.Logger) *LogWriter {
|
||||
zerolog.Nop()
|
||||
return &LogWriter{
|
||||
log: log,
|
||||
level: zerolog.DebugLevel,
|
||||
field: zerolog.MessageFieldName,
|
||||
}
|
||||
}
|
||||
|
||||
func (lw *LogWriter) WithLevel(level zerolog.Level) *LogWriter {
|
||||
return &LogWriter{
|
||||
log: lw.log,
|
||||
level: level,
|
||||
field: lw.field,
|
||||
}
|
||||
}
|
||||
|
||||
func (lw *LogWriter) WithField(field string) *LogWriter {
|
||||
return &LogWriter{
|
||||
log: lw.log,
|
||||
level: lw.level,
|
||||
field: field,
|
||||
}
|
||||
}
|
||||
|
||||
func (lw *LogWriter) writeLine(data []byte) {
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
if data[len(data)-1] == '\n' {
|
||||
data = data[:len(data)-1]
|
||||
}
|
||||
if lw.buf.Len() > 0 {
|
||||
lw.buf.Write(data)
|
||||
data = lw.buf.Bytes()
|
||||
lw.buf.Reset()
|
||||
}
|
||||
lw.log.WithLevel(lw.level).Bytes(lw.field, data).Send()
|
||||
}
|
||||
|
||||
func (lw *LogWriter) Write(data []byte) (n int, err error) {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
newline := bytes.IndexByte(data, '\n')
|
||||
if newline == len(data)-1 {
|
||||
lw.writeLine(data)
|
||||
} else if newline < 0 {
|
||||
lw.buf.Write(data)
|
||||
} else {
|
||||
lines := bytes.Split(data, []byte{'\n'})
|
||||
for _, line := range lines[:len(lines)-1] {
|
||||
lw.writeLine(line)
|
||||
}
|
||||
lw.buf.Write(lines[len(lines)-1])
|
||||
}
|
||||
return len(data), nil
|
||||
}
|
||||
26
vendor/go.mau.fi/util/ptr/ptr.go
vendored
Normal file
26
vendor/go.mau.fi/util/ptr/ptr.go
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2024 Tulir Asokan
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package ptr
|
||||
|
||||
func Clone[T any](val *T) *T {
|
||||
if val == nil {
|
||||
return nil
|
||||
}
|
||||
valCopy := *val
|
||||
return &valCopy
|
||||
}
|
||||
|
||||
func Ptr[T any](val T) *T {
|
||||
return &val
|
||||
}
|
||||
|
||||
func Val[T any](ptr *T) (val T) {
|
||||
if ptr != nil {
|
||||
val = *ptr
|
||||
}
|
||||
return
|
||||
}
|
||||
2
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
2
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
|
|
@ -11,7 +11,7 @@
|
|||
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
|
||||
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
|
||||
// golang.org/x/crypto/chacha20poly1305).
|
||||
package blowfish // import "golang.org/x/crypto/blowfish"
|
||||
package blowfish
|
||||
|
||||
// The code is a port of Bruce Schneier's C implementation.
|
||||
// See https://www.schneier.com/blowfish.html.
|
||||
|
|
|
|||
39
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
39
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
|
|
@ -6,9 +6,11 @@
|
|||
// performs scalar multiplication on the elliptic curve known as Curve25519.
|
||||
// See RFC 7748.
|
||||
//
|
||||
// Starting in Go 1.20, this package is a wrapper for the X25519 implementation
|
||||
// This package is a wrapper for the X25519 implementation
|
||||
// in the crypto/ecdh package.
|
||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
package curve25519
|
||||
|
||||
import "crypto/ecdh"
|
||||
|
||||
// ScalarMult sets dst to the product scalar * point.
|
||||
//
|
||||
|
|
@ -16,7 +18,13 @@ package curve25519 // import "golang.org/x/crypto/curve25519"
|
|||
// zeroes, irrespective of the scalar. Instead, use the X25519 function, which
|
||||
// will return an error.
|
||||
func ScalarMult(dst, scalar, point *[32]byte) {
|
||||
scalarMult(dst, scalar, point)
|
||||
if _, err := x25519(dst, scalar[:], point[:]); err != nil {
|
||||
// The only error condition for x25519 when the inputs are 32 bytes long
|
||||
// is if the output would have been the all-zero value.
|
||||
for i := range dst {
|
||||
dst[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets dst to the product scalar * base where base is the
|
||||
|
|
@ -25,7 +33,12 @@ func ScalarMult(dst, scalar, point *[32]byte) {
|
|||
// It is recommended to use the X25519 function with Basepoint instead, as
|
||||
// copying into fixed size arrays can lead to unexpected bugs.
|
||||
func ScalarBaseMult(dst, scalar *[32]byte) {
|
||||
scalarBaseMult(dst, scalar)
|
||||
curve := ecdh.X25519()
|
||||
priv, err := curve.NewPrivateKey(scalar[:])
|
||||
if err != nil {
|
||||
panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
|
||||
}
|
||||
copy(dst[:], priv.PublicKey().Bytes())
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
@ -57,3 +70,21 @@ func X25519(scalar, point []byte) ([]byte, error) {
|
|||
var dst [32]byte
|
||||
return x25519(&dst, scalar, point)
|
||||
}
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
curve := ecdh.X25519()
|
||||
pub, err := curve.NewPublicKey(point)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priv, err := curve.NewPrivateKey(scalar)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := priv.ECDH(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(dst[:], out)
|
||||
return dst[:], nil
|
||||
}
|
||||
|
|
|
|||
105
vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
generated
vendored
105
vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
generated
vendored
|
|
@ -1,105 +0,0 @@
|
|||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package curve25519
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/curve25519/internal/field"
|
||||
)
|
||||
|
||||
func scalarMult(dst, scalar, point *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], scalar[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
|
||||
x1.SetBytes(point[:])
|
||||
x2.One()
|
||||
x3.Set(&x1)
|
||||
z3.One()
|
||||
|
||||
swap := 0
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int(b)
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
swap = int(b)
|
||||
|
||||
tmp0.Subtract(&x3, &z3)
|
||||
tmp1.Subtract(&x2, &z2)
|
||||
x2.Add(&x2, &z2)
|
||||
z2.Add(&x3, &z3)
|
||||
z3.Multiply(&tmp0, &x2)
|
||||
z2.Multiply(&z2, &tmp1)
|
||||
tmp0.Square(&tmp1)
|
||||
tmp1.Square(&x2)
|
||||
x3.Add(&z3, &z2)
|
||||
z2.Subtract(&z3, &z2)
|
||||
x2.Multiply(&tmp1, &tmp0)
|
||||
tmp1.Subtract(&tmp1, &tmp0)
|
||||
z2.Square(&z2)
|
||||
|
||||
z3.Mult32(&tmp1, 121666)
|
||||
x3.Square(&x3)
|
||||
tmp0.Add(&tmp0, &z3)
|
||||
z3.Multiply(&x1, &z2)
|
||||
z2.Multiply(&tmp1, &tmp0)
|
||||
}
|
||||
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
|
||||
z2.Invert(&z2)
|
||||
x2.Multiply(&x2, &z2)
|
||||
copy(dst[:], x2.Bytes())
|
||||
}
|
||||
|
||||
func scalarBaseMult(dst, scalar *[32]byte) {
|
||||
checkBasepoint()
|
||||
scalarMult(dst, scalar, &basePoint)
|
||||
}
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
var in [32]byte
|
||||
if l := len(scalar); l != 32 {
|
||||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
if l := len(point); l != 32 {
|
||||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
copy(in[:], scalar)
|
||||
if &point[0] == &Basepoint[0] {
|
||||
scalarBaseMult(dst, &in)
|
||||
} else {
|
||||
var base, zero [32]byte
|
||||
copy(base[:], point)
|
||||
scalarMult(dst, &in, &base)
|
||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
||||
return nil, errors.New("bad input point: low order point")
|
||||
}
|
||||
}
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
func checkBasepoint() {
|
||||
if subtle.ConstantTimeCompare(Basepoint, []byte{
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}) != 1 {
|
||||
panic("curve25519: global Basepoint value was modified")
|
||||
}
|
||||
}
|
||||
46
vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
generated
vendored
46
vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
generated
vendored
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package curve25519
|
||||
|
||||
import "crypto/ecdh"
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
curve := ecdh.X25519()
|
||||
pub, err := curve.NewPublicKey(point)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priv, err := curve.NewPrivateKey(scalar)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := priv.ECDH(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(dst[:], out)
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
func scalarMult(dst, scalar, point *[32]byte) {
|
||||
if _, err := x25519(dst, scalar[:], point[:]); err != nil {
|
||||
// The only error condition for x25519 when the inputs are 32 bytes long
|
||||
// is if the output would have been the all-zero value.
|
||||
for i := range dst {
|
||||
dst[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func scalarBaseMult(dst, scalar *[32]byte) {
|
||||
curve := ecdh.X25519()
|
||||
priv, err := curve.NewPrivateKey(scalar[:])
|
||||
if err != nil {
|
||||
panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
|
||||
}
|
||||
copy(dst[:], priv.PublicKey().Bytes())
|
||||
}
|
||||
7
vendor/golang.org/x/crypto/curve25519/internal/field/README
generated
vendored
7
vendor/golang.org/x/crypto/curve25519/internal/field/README
generated
vendored
|
|
@ -1,7 +0,0 @@
|
|||
This package is kept in sync with crypto/ed25519/internal/edwards25519/field in
|
||||
the standard library.
|
||||
|
||||
If there are any changes in the standard library that need to be synced to this
|
||||
package, run sync.sh. It will not overwrite any local changes made since the
|
||||
previous sync, so it's ok to land changes in this package first, and then sync
|
||||
to the standard library later.
|
||||
416
vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
generated
vendored
416
vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
generated
vendored
|
|
@ -1,416 +0,0 @@
|
|||
// Copyright (c) 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package field implements fast arithmetic modulo 2^255-19.
|
||||
package field
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"encoding/binary"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
// Element represents an element of the field GF(2^255-19). Note that this
|
||||
// is not a cryptographically secure group, and should only be used to interact
|
||||
// with edwards25519.Point coordinates.
|
||||
//
|
||||
// This type works similarly to math/big.Int, and all arguments and receivers
|
||||
// are allowed to alias.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type Element struct {
|
||||
// An element t represents the integer
|
||||
// t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
|
||||
//
|
||||
// Between operations, all limbs are expected to be lower than 2^52.
|
||||
l0 uint64
|
||||
l1 uint64
|
||||
l2 uint64
|
||||
l3 uint64
|
||||
l4 uint64
|
||||
}
|
||||
|
||||
const maskLow51Bits uint64 = (1 << 51) - 1
|
||||
|
||||
var feZero = &Element{0, 0, 0, 0, 0}
|
||||
|
||||
// Zero sets v = 0, and returns v.
|
||||
func (v *Element) Zero() *Element {
|
||||
*v = *feZero
|
||||
return v
|
||||
}
|
||||
|
||||
var feOne = &Element{1, 0, 0, 0, 0}
|
||||
|
||||
// One sets v = 1, and returns v.
|
||||
func (v *Element) One() *Element {
|
||||
*v = *feOne
|
||||
return v
|
||||
}
|
||||
|
||||
// reduce reduces v modulo 2^255 - 19 and returns it.
|
||||
func (v *Element) reduce() *Element {
|
||||
v.carryPropagate()
|
||||
|
||||
// After the light reduction we now have a field element representation
|
||||
// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
|
||||
|
||||
// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
|
||||
// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
|
||||
c := (v.l0 + 19) >> 51
|
||||
c = (v.l1 + c) >> 51
|
||||
c = (v.l2 + c) >> 51
|
||||
c = (v.l3 + c) >> 51
|
||||
c = (v.l4 + c) >> 51
|
||||
|
||||
// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
|
||||
// effectively applying the reduction identity to the carry.
|
||||
v.l0 += 19 * c
|
||||
|
||||
v.l1 += v.l0 >> 51
|
||||
v.l0 = v.l0 & maskLow51Bits
|
||||
v.l2 += v.l1 >> 51
|
||||
v.l1 = v.l1 & maskLow51Bits
|
||||
v.l3 += v.l2 >> 51
|
||||
v.l2 = v.l2 & maskLow51Bits
|
||||
v.l4 += v.l3 >> 51
|
||||
v.l3 = v.l3 & maskLow51Bits
|
||||
// no additional carry
|
||||
v.l4 = v.l4 & maskLow51Bits
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Add sets v = a + b, and returns v.
|
||||
func (v *Element) Add(a, b *Element) *Element {
|
||||
v.l0 = a.l0 + b.l0
|
||||
v.l1 = a.l1 + b.l1
|
||||
v.l2 = a.l2 + b.l2
|
||||
v.l3 = a.l3 + b.l3
|
||||
v.l4 = a.l4 + b.l4
|
||||
// Using the generic implementation here is actually faster than the
|
||||
// assembly. Probably because the body of this function is so simple that
|
||||
// the compiler can figure out better optimizations by inlining the carry
|
||||
// propagation. TODO
|
||||
return v.carryPropagateGeneric()
|
||||
}
|
||||
|
||||
// Subtract sets v = a - b, and returns v.
|
||||
func (v *Element) Subtract(a, b *Element) *Element {
|
||||
// We first add 2 * p, to guarantee the subtraction won't underflow, and
|
||||
// then subtract b (which can be up to 2^255 + 2^13 * 19).
|
||||
v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
|
||||
v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
|
||||
v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
|
||||
v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
|
||||
v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
|
||||
return v.carryPropagate()
|
||||
}
|
||||
|
||||
// Negate sets v = -a, and returns v.
|
||||
func (v *Element) Negate(a *Element) *Element {
|
||||
return v.Subtract(feZero, a)
|
||||
}
|
||||
|
||||
// Invert sets v = 1/z mod p, and returns v.
|
||||
//
|
||||
// If z == 0, Invert returns v = 0.
|
||||
func (v *Element) Invert(z *Element) *Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2. It uses the
|
||||
// same sequence of 255 squarings and 11 multiplications as [Curve25519].
|
||||
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
|
||||
|
||||
z2.Square(z) // 2
|
||||
t.Square(&z2) // 4
|
||||
t.Square(&t) // 8
|
||||
z9.Multiply(&t, z) // 9
|
||||
z11.Multiply(&z9, &z2) // 11
|
||||
t.Square(&z11) // 22
|
||||
z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
|
||||
|
||||
t.Square(&z2_5_0) // 2^6 - 2^1
|
||||
for i := 0; i < 4; i++ {
|
||||
t.Square(&t) // 2^10 - 2^5
|
||||
}
|
||||
z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
|
||||
|
||||
t.Square(&z2_10_0) // 2^11 - 2^1
|
||||
for i := 0; i < 9; i++ {
|
||||
t.Square(&t) // 2^20 - 2^10
|
||||
}
|
||||
z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
|
||||
|
||||
t.Square(&z2_20_0) // 2^21 - 2^1
|
||||
for i := 0; i < 19; i++ {
|
||||
t.Square(&t) // 2^40 - 2^20
|
||||
}
|
||||
t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
|
||||
|
||||
t.Square(&t) // 2^41 - 2^1
|
||||
for i := 0; i < 9; i++ {
|
||||
t.Square(&t) // 2^50 - 2^10
|
||||
}
|
||||
z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
|
||||
|
||||
t.Square(&z2_50_0) // 2^51 - 2^1
|
||||
for i := 0; i < 49; i++ {
|
||||
t.Square(&t) // 2^100 - 2^50
|
||||
}
|
||||
z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
|
||||
|
||||
t.Square(&z2_100_0) // 2^101 - 2^1
|
||||
for i := 0; i < 99; i++ {
|
||||
t.Square(&t) // 2^200 - 2^100
|
||||
}
|
||||
t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
|
||||
|
||||
t.Square(&t) // 2^201 - 2^1
|
||||
for i := 0; i < 49; i++ {
|
||||
t.Square(&t) // 2^250 - 2^50
|
||||
}
|
||||
t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
|
||||
|
||||
t.Square(&t) // 2^251 - 2^1
|
||||
t.Square(&t) // 2^252 - 2^2
|
||||
t.Square(&t) // 2^253 - 2^3
|
||||
t.Square(&t) // 2^254 - 2^4
|
||||
t.Square(&t) // 2^255 - 2^5
|
||||
|
||||
return v.Multiply(&t, &z11) // 2^255 - 21
|
||||
}
|
||||
|
||||
// Set sets v = a, and returns v.
|
||||
func (v *Element) Set(a *Element) *Element {
|
||||
*v = *a
|
||||
return v
|
||||
}
|
||||
|
||||
// SetBytes sets v to x, which must be a 32-byte little-endian encoding.
|
||||
//
|
||||
// Consistent with RFC 7748, the most significant bit (the high bit of the
|
||||
// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
|
||||
// are accepted. Note that this is laxer than specified by RFC 8032.
|
||||
func (v *Element) SetBytes(x []byte) *Element {
|
||||
if len(x) != 32 {
|
||||
panic("edwards25519: invalid field element input size")
|
||||
}
|
||||
|
||||
// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
|
||||
v.l0 = binary.LittleEndian.Uint64(x[0:8])
|
||||
v.l0 &= maskLow51Bits
|
||||
// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
|
||||
v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
|
||||
v.l1 &= maskLow51Bits
|
||||
// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
|
||||
v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
|
||||
v.l2 &= maskLow51Bits
|
||||
// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
|
||||
v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
|
||||
v.l3 &= maskLow51Bits
|
||||
// Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
|
||||
// Note: not bytes 25:33, shift 4, to avoid overread.
|
||||
v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
|
||||
v.l4 &= maskLow51Bits
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Bytes returns the canonical 32-byte little-endian encoding of v.
|
||||
func (v *Element) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [32]byte
|
||||
return v.bytes(&out)
|
||||
}
|
||||
|
||||
func (v *Element) bytes(out *[32]byte) []byte {
|
||||
t := *v
|
||||
t.reduce()
|
||||
|
||||
var buf [8]byte
|
||||
for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
|
||||
bitsOffset := i * 51
|
||||
binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
|
||||
for i, bb := range buf {
|
||||
off := bitsOffset/8 + i
|
||||
if off >= len(out) {
|
||||
break
|
||||
}
|
||||
out[off] |= bb
|
||||
}
|
||||
}
|
||||
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// Equal returns 1 if v and u are equal, and 0 otherwise.
|
||||
func (v *Element) Equal(u *Element) int {
|
||||
sa, sv := u.Bytes(), v.Bytes()
|
||||
return subtle.ConstantTimeCompare(sa, sv)
|
||||
}
|
||||
|
||||
// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
|
||||
func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *Element) Select(a, b *Element, cond int) *Element {
|
||||
m := mask64Bits(cond)
|
||||
v.l0 = (m & a.l0) | (^m & b.l0)
|
||||
v.l1 = (m & a.l1) | (^m & b.l1)
|
||||
v.l2 = (m & a.l2) | (^m & b.l2)
|
||||
v.l3 = (m & a.l3) | (^m & b.l3)
|
||||
v.l4 = (m & a.l4) | (^m & b.l4)
|
||||
return v
|
||||
}
|
||||
|
||||
// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
|
||||
func (v *Element) Swap(u *Element, cond int) {
|
||||
m := mask64Bits(cond)
|
||||
t := m & (v.l0 ^ u.l0)
|
||||
v.l0 ^= t
|
||||
u.l0 ^= t
|
||||
t = m & (v.l1 ^ u.l1)
|
||||
v.l1 ^= t
|
||||
u.l1 ^= t
|
||||
t = m & (v.l2 ^ u.l2)
|
||||
v.l2 ^= t
|
||||
u.l2 ^= t
|
||||
t = m & (v.l3 ^ u.l3)
|
||||
v.l3 ^= t
|
||||
u.l3 ^= t
|
||||
t = m & (v.l4 ^ u.l4)
|
||||
v.l4 ^= t
|
||||
u.l4 ^= t
|
||||
}
|
||||
|
||||
// IsNegative returns 1 if v is negative, and 0 otherwise.
|
||||
func (v *Element) IsNegative() int {
|
||||
return int(v.Bytes()[0] & 1)
|
||||
}
|
||||
|
||||
// Absolute sets v to |u|, and returns v.
|
||||
func (v *Element) Absolute(u *Element) *Element {
|
||||
return v.Select(new(Element).Negate(u), u, u.IsNegative())
|
||||
}
|
||||
|
||||
// Multiply sets v = x * y, and returns v.
|
||||
func (v *Element) Multiply(x, y *Element) *Element {
|
||||
feMul(v, x, y)
|
||||
return v
|
||||
}
|
||||
|
||||
// Square sets v = x * x, and returns v.
|
||||
func (v *Element) Square(x *Element) *Element {
|
||||
feSquare(v, x)
|
||||
return v
|
||||
}
|
||||
|
||||
// Mult32 sets v = x * y, and returns v.
|
||||
func (v *Element) Mult32(x *Element, y uint32) *Element {
|
||||
x0lo, x0hi := mul51(x.l0, y)
|
||||
x1lo, x1hi := mul51(x.l1, y)
|
||||
x2lo, x2hi := mul51(x.l2, y)
|
||||
x3lo, x3hi := mul51(x.l3, y)
|
||||
x4lo, x4hi := mul51(x.l4, y)
|
||||
v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
|
||||
v.l1 = x1lo + x0hi
|
||||
v.l2 = x2lo + x1hi
|
||||
v.l3 = x3lo + x2hi
|
||||
v.l4 = x4lo + x3hi
|
||||
// The hi portions are going to be only 32 bits, plus any previous excess,
|
||||
// so we can skip the carry propagation.
|
||||
return v
|
||||
}
|
||||
|
||||
// mul51 returns lo + hi * 2⁵¹ = a * b.
|
||||
func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
|
||||
mh, ml := bits.Mul64(a, uint64(b))
|
||||
lo = ml & maskLow51Bits
|
||||
hi = (mh << 13) | (ml >> 51)
|
||||
return
|
||||
}
|
||||
|
||||
// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
|
||||
func (v *Element) Pow22523(x *Element) *Element {
|
||||
var t0, t1, t2 Element
|
||||
|
||||
t0.Square(x) // x^2
|
||||
t1.Square(&t0) // x^4
|
||||
t1.Square(&t1) // x^8
|
||||
t1.Multiply(x, &t1) // x^9
|
||||
t0.Multiply(&t0, &t1) // x^11
|
||||
t0.Square(&t0) // x^22
|
||||
t0.Multiply(&t1, &t0) // x^31
|
||||
t1.Square(&t0) // x^62
|
||||
for i := 1; i < 5; i++ { // x^992
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1
|
||||
t1.Square(&t0) // 2^11 - 2
|
||||
for i := 1; i < 10; i++ { // 2^20 - 2^10
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t1.Multiply(&t1, &t0) // 2^20 - 1
|
||||
t2.Square(&t1) // 2^21 - 2
|
||||
for i := 1; i < 20; i++ { // 2^40 - 2^20
|
||||
t2.Square(&t2)
|
||||
}
|
||||
t1.Multiply(&t2, &t1) // 2^40 - 1
|
||||
t1.Square(&t1) // 2^41 - 2
|
||||
for i := 1; i < 10; i++ { // 2^50 - 2^10
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t0.Multiply(&t1, &t0) // 2^50 - 1
|
||||
t1.Square(&t0) // 2^51 - 2
|
||||
for i := 1; i < 50; i++ { // 2^100 - 2^50
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t1.Multiply(&t1, &t0) // 2^100 - 1
|
||||
t2.Square(&t1) // 2^101 - 2
|
||||
for i := 1; i < 100; i++ { // 2^200 - 2^100
|
||||
t2.Square(&t2)
|
||||
}
|
||||
t1.Multiply(&t2, &t1) // 2^200 - 1
|
||||
t1.Square(&t1) // 2^201 - 2
|
||||
for i := 1; i < 50; i++ { // 2^250 - 2^50
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t0.Multiply(&t1, &t0) // 2^250 - 1
|
||||
t0.Square(&t0) // 2^251 - 2
|
||||
t0.Square(&t0) // 2^252 - 4
|
||||
return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
|
||||
}
|
||||
|
||||
// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
|
||||
var sqrtM1 = &Element{1718705420411056, 234908883556509,
|
||||
2233514472574048, 2117202627021982, 765476049583133}
|
||||
|
||||
// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
|
||||
//
|
||||
// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
|
||||
// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
|
||||
// and returns r and 0.
|
||||
func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
|
||||
var a, b Element
|
||||
|
||||
// r = (u * v3) * (u * v7)^((p-5)/8)
|
||||
v2 := a.Square(v)
|
||||
uv3 := b.Multiply(u, b.Multiply(v2, v))
|
||||
uv7 := a.Multiply(uv3, a.Square(v2))
|
||||
r.Multiply(uv3, r.Pow22523(uv7))
|
||||
|
||||
check := a.Multiply(v, a.Square(r)) // check = v * r^2
|
||||
|
||||
uNeg := b.Negate(u)
|
||||
correctSignSqrt := check.Equal(u)
|
||||
flippedSignSqrt := check.Equal(uNeg)
|
||||
flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
|
||||
|
||||
rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
|
||||
// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
|
||||
r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
|
||||
|
||||
r.Absolute(r) // Choose the nonnegative square root.
|
||||
return r, correctSignSqrt | flippedSignSqrt
|
||||
}
|
||||
15
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
generated
vendored
15
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
generated
vendored
|
|
@ -1,15 +0,0 @@
|
|||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
||||
|
||||
//go:build amd64 && gc && !purego
|
||||
|
||||
package field
|
||||
|
||||
// feMul sets out = a * b. It works like feMulGeneric.
|
||||
//
|
||||
//go:noescape
|
||||
func feMul(out *Element, a *Element, b *Element)
|
||||
|
||||
// feSquare sets out = a * a. It works like feSquareGeneric.
|
||||
//
|
||||
//go:noescape
|
||||
func feSquare(out *Element, a *Element)
|
||||
378
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
generated
vendored
378
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
generated
vendored
|
|
@ -1,378 +0,0 @@
|
|||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
||||
|
||||
//go:build amd64 && gc && !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func feMul(out *Element, a *Element, b *Element)
|
||||
TEXT ·feMul(SB), NOSPLIT, $0-24
|
||||
MOVQ a+8(FP), CX
|
||||
MOVQ b+16(FP), BX
|
||||
|
||||
// r0 = a0×b0
|
||||
MOVQ (CX), AX
|
||||
MULQ (BX)
|
||||
MOVQ AX, DI
|
||||
MOVQ DX, SI
|
||||
|
||||
// r0 += 19×a1×b4
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r0 += 19×a2×b3
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r0 += 19×a3×b2
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r0 += 19×a4×b1
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r1 = a0×b1
|
||||
MOVQ (CX), AX
|
||||
MULQ 8(BX)
|
||||
MOVQ AX, R9
|
||||
MOVQ DX, R8
|
||||
|
||||
// r1 += a1×b0
|
||||
MOVQ 8(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r1 += 19×a2×b4
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r1 += 19×a3×b3
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r1 += 19×a4×b2
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r2 = a0×b2
|
||||
MOVQ (CX), AX
|
||||
MULQ 16(BX)
|
||||
MOVQ AX, R11
|
||||
MOVQ DX, R10
|
||||
|
||||
// r2 += a1×b1
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r2 += a2×b0
|
||||
MOVQ 16(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r2 += 19×a3×b4
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r2 += 19×a4×b3
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r3 = a0×b3
|
||||
MOVQ (CX), AX
|
||||
MULQ 24(BX)
|
||||
MOVQ AX, R13
|
||||
MOVQ DX, R12
|
||||
|
||||
// r3 += a1×b2
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r3 += a2×b1
|
||||
MOVQ 16(CX), AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r3 += a3×b0
|
||||
MOVQ 24(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r3 += 19×a4×b4
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r4 = a0×b4
|
||||
MOVQ (CX), AX
|
||||
MULQ 32(BX)
|
||||
MOVQ AX, R15
|
||||
MOVQ DX, R14
|
||||
|
||||
// r4 += a1×b3
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// r4 += a2×b2
|
||||
MOVQ 16(CX), AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// r4 += a3×b1
|
||||
MOVQ 24(CX), AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// r4 += a4×b0
|
||||
MOVQ 32(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// First reduction chain
|
||||
MOVQ $0x0007ffffffffffff, AX
|
||||
SHLQ $0x0d, DI, SI
|
||||
SHLQ $0x0d, R9, R8
|
||||
SHLQ $0x0d, R11, R10
|
||||
SHLQ $0x0d, R13, R12
|
||||
SHLQ $0x0d, R15, R14
|
||||
ANDQ AX, DI
|
||||
IMUL3Q $0x13, R14, R14
|
||||
ADDQ R14, DI
|
||||
ANDQ AX, R9
|
||||
ADDQ SI, R9
|
||||
ANDQ AX, R11
|
||||
ADDQ R8, R11
|
||||
ANDQ AX, R13
|
||||
ADDQ R10, R13
|
||||
ANDQ AX, R15
|
||||
ADDQ R12, R15
|
||||
|
||||
// Second reduction chain (carryPropagate)
|
||||
MOVQ DI, SI
|
||||
SHRQ $0x33, SI
|
||||
MOVQ R9, R8
|
||||
SHRQ $0x33, R8
|
||||
MOVQ R11, R10
|
||||
SHRQ $0x33, R10
|
||||
MOVQ R13, R12
|
||||
SHRQ $0x33, R12
|
||||
MOVQ R15, R14
|
||||
SHRQ $0x33, R14
|
||||
ANDQ AX, DI
|
||||
IMUL3Q $0x13, R14, R14
|
||||
ADDQ R14, DI
|
||||
ANDQ AX, R9
|
||||
ADDQ SI, R9
|
||||
ANDQ AX, R11
|
||||
ADDQ R8, R11
|
||||
ANDQ AX, R13
|
||||
ADDQ R10, R13
|
||||
ANDQ AX, R15
|
||||
ADDQ R12, R15
|
||||
|
||||
// Store output
|
||||
MOVQ out+0(FP), AX
|
||||
MOVQ DI, (AX)
|
||||
MOVQ R9, 8(AX)
|
||||
MOVQ R11, 16(AX)
|
||||
MOVQ R13, 24(AX)
|
||||
MOVQ R15, 32(AX)
|
||||
RET
|
||||
|
||||
// func feSquare(out *Element, a *Element)
|
||||
TEXT ·feSquare(SB), NOSPLIT, $0-16
|
||||
MOVQ a+8(FP), CX
|
||||
|
||||
// r0 = l0×l0
|
||||
MOVQ (CX), AX
|
||||
MULQ (CX)
|
||||
MOVQ AX, SI
|
||||
MOVQ DX, BX
|
||||
|
||||
// r0 += 38×l1×l4
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, SI
|
||||
ADCQ DX, BX
|
||||
|
||||
// r0 += 38×l2×l3
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX, SI
|
||||
ADCQ DX, BX
|
||||
|
||||
// r1 = 2×l0×l1
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 8(CX)
|
||||
MOVQ AX, R8
|
||||
MOVQ DX, DI
|
||||
|
||||
// r1 += 38×l2×l4
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, R8
|
||||
ADCQ DX, DI
|
||||
|
||||
// r1 += 19×l3×l3
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX, R8
|
||||
ADCQ DX, DI
|
||||
|
||||
// r2 = 2×l0×l2
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 16(CX)
|
||||
MOVQ AX, R10
|
||||
MOVQ DX, R9
|
||||
|
||||
// r2 += l1×l1
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX, R10
|
||||
ADCQ DX, R9
|
||||
|
||||
// r2 += 38×l3×l4
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, R10
|
||||
ADCQ DX, R9
|
||||
|
||||
// r3 = 2×l0×l3
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 24(CX)
|
||||
MOVQ AX, R12
|
||||
MOVQ DX, R11
|
||||
|
||||
// r3 += 2×l1×l2
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x02, AX, AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX, R12
|
||||
ADCQ DX, R11
|
||||
|
||||
// r3 += 19×l4×l4
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, R12
|
||||
ADCQ DX, R11
|
||||
|
||||
// r4 = 2×l0×l4
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 32(CX)
|
||||
MOVQ AX, R14
|
||||
MOVQ DX, R13
|
||||
|
||||
// r4 += 2×l1×l3
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x02, AX, AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX, R14
|
||||
ADCQ DX, R13
|
||||
|
||||
// r4 += l2×l2
|
||||
MOVQ 16(CX), AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX, R14
|
||||
ADCQ DX, R13
|
||||
|
||||
// First reduction chain
|
||||
MOVQ $0x0007ffffffffffff, AX
|
||||
SHLQ $0x0d, SI, BX
|
||||
SHLQ $0x0d, R8, DI
|
||||
SHLQ $0x0d, R10, R9
|
||||
SHLQ $0x0d, R12, R11
|
||||
SHLQ $0x0d, R14, R13
|
||||
ANDQ AX, SI
|
||||
IMUL3Q $0x13, R13, R13
|
||||
ADDQ R13, SI
|
||||
ANDQ AX, R8
|
||||
ADDQ BX, R8
|
||||
ANDQ AX, R10
|
||||
ADDQ DI, R10
|
||||
ANDQ AX, R12
|
||||
ADDQ R9, R12
|
||||
ANDQ AX, R14
|
||||
ADDQ R11, R14
|
||||
|
||||
// Second reduction chain (carryPropagate)
|
||||
MOVQ SI, BX
|
||||
SHRQ $0x33, BX
|
||||
MOVQ R8, DI
|
||||
SHRQ $0x33, DI
|
||||
MOVQ R10, R9
|
||||
SHRQ $0x33, R9
|
||||
MOVQ R12, R11
|
||||
SHRQ $0x33, R11
|
||||
MOVQ R14, R13
|
||||
SHRQ $0x33, R13
|
||||
ANDQ AX, SI
|
||||
IMUL3Q $0x13, R13, R13
|
||||
ADDQ R13, SI
|
||||
ANDQ AX, R8
|
||||
ADDQ BX, R8
|
||||
ANDQ AX, R10
|
||||
ADDQ DI, R10
|
||||
ANDQ AX, R12
|
||||
ADDQ R9, R12
|
||||
ANDQ AX, R14
|
||||
ADDQ R11, R14
|
||||
|
||||
// Store output
|
||||
MOVQ out+0(FP), AX
|
||||
MOVQ SI, (AX)
|
||||
MOVQ R8, 8(AX)
|
||||
MOVQ R10, 16(AX)
|
||||
MOVQ R12, 24(AX)
|
||||
MOVQ R14, 32(AX)
|
||||
RET
|
||||
11
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
generated
vendored
11
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
generated
vendored
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright (c) 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !amd64 || !gc || purego
|
||||
|
||||
package field
|
||||
|
||||
func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
|
||||
|
||||
func feSquare(v, x *Element) { feSquareGeneric(v, x) }
|
||||
15
vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
generated
vendored
15
vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
generated
vendored
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright (c) 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build arm64 && gc && !purego
|
||||
|
||||
package field
|
||||
|
||||
//go:noescape
|
||||
func carryPropagate(v *Element)
|
||||
|
||||
func (v *Element) carryPropagate() *Element {
|
||||
carryPropagate(v)
|
||||
return v
|
||||
}
|
||||
42
vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
generated
vendored
42
vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
generated
vendored
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build arm64 && gc && !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// carryPropagate works exactly like carryPropagateGeneric and uses the
|
||||
// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
|
||||
// avoids loading R0-R4 twice and uses LDP and STP.
|
||||
//
|
||||
// See https://golang.org/issues/43145 for the main compiler issue.
|
||||
//
|
||||
// func carryPropagate(v *Element)
|
||||
TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
|
||||
MOVD v+0(FP), R20
|
||||
|
||||
LDP 0(R20), (R0, R1)
|
||||
LDP 16(R20), (R2, R3)
|
||||
MOVD 32(R20), R4
|
||||
|
||||
AND $0x7ffffffffffff, R0, R10
|
||||
AND $0x7ffffffffffff, R1, R11
|
||||
AND $0x7ffffffffffff, R2, R12
|
||||
AND $0x7ffffffffffff, R3, R13
|
||||
AND $0x7ffffffffffff, R4, R14
|
||||
|
||||
ADD R0>>51, R11, R11
|
||||
ADD R1>>51, R12, R12
|
||||
ADD R2>>51, R13, R13
|
||||
ADD R3>>51, R14, R14
|
||||
// R4>>51 * 19 + R10 -> R10
|
||||
LSR $51, R4, R21
|
||||
MOVD $19, R22
|
||||
MADD R22, R10, R21, R10
|
||||
|
||||
STP (R10, R11), 0(R20)
|
||||
STP (R12, R13), 16(R20)
|
||||
MOVD R14, 32(R20)
|
||||
|
||||
RET
|
||||
11
vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
generated
vendored
11
vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
generated
vendored
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright (c) 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !arm64 || !gc || purego
|
||||
|
||||
package field
|
||||
|
||||
func (v *Element) carryPropagate() *Element {
|
||||
return v.carryPropagateGeneric()
|
||||
}
|
||||
264
vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
generated
vendored
264
vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
generated
vendored
|
|
@ -1,264 +0,0 @@
|
|||
// Copyright (c) 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package field
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
|
||||
// bits.Mul64 and bits.Add64 intrinsics.
|
||||
type uint128 struct {
|
||||
lo, hi uint64
|
||||
}
|
||||
|
||||
// mul64 returns a * b.
|
||||
func mul64(a, b uint64) uint128 {
|
||||
hi, lo := bits.Mul64(a, b)
|
||||
return uint128{lo, hi}
|
||||
}
|
||||
|
||||
// addMul64 returns v + a * b.
|
||||
func addMul64(v uint128, a, b uint64) uint128 {
|
||||
hi, lo := bits.Mul64(a, b)
|
||||
lo, c := bits.Add64(lo, v.lo, 0)
|
||||
hi, _ = bits.Add64(hi, v.hi, c)
|
||||
return uint128{lo, hi}
|
||||
}
|
||||
|
||||
// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
|
||||
func shiftRightBy51(a uint128) uint64 {
|
||||
return (a.hi << (64 - 51)) | (a.lo >> 51)
|
||||
}
|
||||
|
||||
func feMulGeneric(v, a, b *Element) {
|
||||
a0 := a.l0
|
||||
a1 := a.l1
|
||||
a2 := a.l2
|
||||
a3 := a.l3
|
||||
a4 := a.l4
|
||||
|
||||
b0 := b.l0
|
||||
b1 := b.l1
|
||||
b2 := b.l2
|
||||
b3 := b.l3
|
||||
b4 := b.l4
|
||||
|
||||
// Limb multiplication works like pen-and-paper columnar multiplication, but
|
||||
// with 51-bit limbs instead of digits.
|
||||
//
|
||||
// a4 a3 a2 a1 a0 x
|
||||
// b4 b3 b2 b1 b0 =
|
||||
// ------------------------
|
||||
// a4b0 a3b0 a2b0 a1b0 a0b0 +
|
||||
// a4b1 a3b1 a2b1 a1b1 a0b1 +
|
||||
// a4b2 a3b2 a2b2 a1b2 a0b2 +
|
||||
// a4b3 a3b3 a2b3 a1b3 a0b3 +
|
||||
// a4b4 a3b4 a2b4 a1b4 a0b4 =
|
||||
// ----------------------------------------------
|
||||
// r8 r7 r6 r5 r4 r3 r2 r1 r0
|
||||
//
|
||||
// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
|
||||
// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
|
||||
// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
|
||||
//
|
||||
// Reduction can be carried out simultaneously to multiplication. For
|
||||
// example, we do not compute r5: whenever the result of a multiplication
|
||||
// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
|
||||
//
|
||||
// a4b0 a3b0 a2b0 a1b0 a0b0 +
|
||||
// a3b1 a2b1 a1b1 a0b1 19×a4b1 +
|
||||
// a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
|
||||
// a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
|
||||
// a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
|
||||
// --------------------------------------
|
||||
// r4 r3 r2 r1 r0
|
||||
//
|
||||
// Finally we add up the columns into wide, overlapping limbs.
|
||||
|
||||
a1_19 := a1 * 19
|
||||
a2_19 := a2 * 19
|
||||
a3_19 := a3 * 19
|
||||
a4_19 := a4 * 19
|
||||
|
||||
// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
|
||||
r0 := mul64(a0, b0)
|
||||
r0 = addMul64(r0, a1_19, b4)
|
||||
r0 = addMul64(r0, a2_19, b3)
|
||||
r0 = addMul64(r0, a3_19, b2)
|
||||
r0 = addMul64(r0, a4_19, b1)
|
||||
|
||||
// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
|
||||
r1 := mul64(a0, b1)
|
||||
r1 = addMul64(r1, a1, b0)
|
||||
r1 = addMul64(r1, a2_19, b4)
|
||||
r1 = addMul64(r1, a3_19, b3)
|
||||
r1 = addMul64(r1, a4_19, b2)
|
||||
|
||||
// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
|
||||
r2 := mul64(a0, b2)
|
||||
r2 = addMul64(r2, a1, b1)
|
||||
r2 = addMul64(r2, a2, b0)
|
||||
r2 = addMul64(r2, a3_19, b4)
|
||||
r2 = addMul64(r2, a4_19, b3)
|
||||
|
||||
// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
|
||||
r3 := mul64(a0, b3)
|
||||
r3 = addMul64(r3, a1, b2)
|
||||
r3 = addMul64(r3, a2, b1)
|
||||
r3 = addMul64(r3, a3, b0)
|
||||
r3 = addMul64(r3, a4_19, b4)
|
||||
|
||||
// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
|
||||
r4 := mul64(a0, b4)
|
||||
r4 = addMul64(r4, a1, b3)
|
||||
r4 = addMul64(r4, a2, b2)
|
||||
r4 = addMul64(r4, a3, b1)
|
||||
r4 = addMul64(r4, a4, b0)
|
||||
|
||||
// After the multiplication, we need to reduce (carry) the five coefficients
|
||||
// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
|
||||
// to respect the Element invariant.
|
||||
//
|
||||
// Overall, the reduction works the same as carryPropagate, except with
|
||||
// wider inputs: we take the carry for each coefficient by shifting it right
|
||||
// by 51, and add it to the limb above it. The top carry is multiplied by 19
|
||||
// according to the reduction identity and added to the lowest limb.
|
||||
//
|
||||
// The largest coefficient (r0) will be at most 111 bits, which guarantees
|
||||
// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
|
||||
//
|
||||
// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
|
||||
// r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
|
||||
// r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
|
||||
// r0 < 2⁷ × 2⁵² × 2⁵²
|
||||
// r0 < 2¹¹¹
|
||||
//
|
||||
// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
|
||||
// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
|
||||
// allows us to easily apply the reduction identity.
|
||||
//
|
||||
// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
|
||||
// r4 < 5 × 2⁵² × 2⁵²
|
||||
// r4 < 2¹⁰⁷
|
||||
//
|
||||
|
||||
c0 := shiftRightBy51(r0)
|
||||
c1 := shiftRightBy51(r1)
|
||||
c2 := shiftRightBy51(r2)
|
||||
c3 := shiftRightBy51(r3)
|
||||
c4 := shiftRightBy51(r4)
|
||||
|
||||
rr0 := r0.lo&maskLow51Bits + c4*19
|
||||
rr1 := r1.lo&maskLow51Bits + c0
|
||||
rr2 := r2.lo&maskLow51Bits + c1
|
||||
rr3 := r3.lo&maskLow51Bits + c2
|
||||
rr4 := r4.lo&maskLow51Bits + c3
|
||||
|
||||
// Now all coefficients fit into 64-bit registers but are still too large to
|
||||
// be passed around as a Element. We therefore do one last carry chain,
|
||||
// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
|
||||
*v = Element{rr0, rr1, rr2, rr3, rr4}
|
||||
v.carryPropagate()
|
||||
}
|
||||
|
||||
func feSquareGeneric(v, a *Element) {
|
||||
l0 := a.l0
|
||||
l1 := a.l1
|
||||
l2 := a.l2
|
||||
l3 := a.l3
|
||||
l4 := a.l4
|
||||
|
||||
// Squaring works precisely like multiplication above, but thanks to its
|
||||
// symmetry we get to group a few terms together.
|
||||
//
|
||||
// l4 l3 l2 l1 l0 x
|
||||
// l4 l3 l2 l1 l0 =
|
||||
// ------------------------
|
||||
// l4l0 l3l0 l2l0 l1l0 l0l0 +
|
||||
// l4l1 l3l1 l2l1 l1l1 l0l1 +
|
||||
// l4l2 l3l2 l2l2 l1l2 l0l2 +
|
||||
// l4l3 l3l3 l2l3 l1l3 l0l3 +
|
||||
// l4l4 l3l4 l2l4 l1l4 l0l4 =
|
||||
// ----------------------------------------------
|
||||
// r8 r7 r6 r5 r4 r3 r2 r1 r0
|
||||
//
|
||||
// l4l0 l3l0 l2l0 l1l0 l0l0 +
|
||||
// l3l1 l2l1 l1l1 l0l1 19×l4l1 +
|
||||
// l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
|
||||
// l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
|
||||
// l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
|
||||
// --------------------------------------
|
||||
// r4 r3 r2 r1 r0
|
||||
//
|
||||
// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
|
||||
// only three Mul64 and four Add64, instead of five and eight.
|
||||
|
||||
l0_2 := l0 * 2
|
||||
l1_2 := l1 * 2
|
||||
|
||||
l1_38 := l1 * 38
|
||||
l2_38 := l2 * 38
|
||||
l3_38 := l3 * 38
|
||||
|
||||
l3_19 := l3 * 19
|
||||
l4_19 := l4 * 19
|
||||
|
||||
// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
|
||||
r0 := mul64(l0, l0)
|
||||
r0 = addMul64(r0, l1_38, l4)
|
||||
r0 = addMul64(r0, l2_38, l3)
|
||||
|
||||
// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
|
||||
r1 := mul64(l0_2, l1)
|
||||
r1 = addMul64(r1, l2_38, l4)
|
||||
r1 = addMul64(r1, l3_19, l3)
|
||||
|
||||
// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
|
||||
r2 := mul64(l0_2, l2)
|
||||
r2 = addMul64(r2, l1, l1)
|
||||
r2 = addMul64(r2, l3_38, l4)
|
||||
|
||||
// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
|
||||
r3 := mul64(l0_2, l3)
|
||||
r3 = addMul64(r3, l1_2, l2)
|
||||
r3 = addMul64(r3, l4_19, l4)
|
||||
|
||||
// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
|
||||
r4 := mul64(l0_2, l4)
|
||||
r4 = addMul64(r4, l1_2, l3)
|
||||
r4 = addMul64(r4, l2, l2)
|
||||
|
||||
c0 := shiftRightBy51(r0)
|
||||
c1 := shiftRightBy51(r1)
|
||||
c2 := shiftRightBy51(r2)
|
||||
c3 := shiftRightBy51(r3)
|
||||
c4 := shiftRightBy51(r4)
|
||||
|
||||
rr0 := r0.lo&maskLow51Bits + c4*19
|
||||
rr1 := r1.lo&maskLow51Bits + c0
|
||||
rr2 := r2.lo&maskLow51Bits + c1
|
||||
rr3 := r3.lo&maskLow51Bits + c2
|
||||
rr4 := r4.lo&maskLow51Bits + c3
|
||||
|
||||
*v = Element{rr0, rr1, rr2, rr3, rr4}
|
||||
v.carryPropagate()
|
||||
}
|
||||
|
||||
// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
|
||||
// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
|
||||
func (v *Element) carryPropagateGeneric() *Element {
|
||||
c0 := v.l0 >> 51
|
||||
c1 := v.l1 >> 51
|
||||
c2 := v.l2 >> 51
|
||||
c3 := v.l3 >> 51
|
||||
c4 := v.l4 >> 51
|
||||
|
||||
v.l0 = v.l0&maskLow51Bits + c4*19
|
||||
v.l1 = v.l1&maskLow51Bits + c0
|
||||
v.l2 = v.l2&maskLow51Bits + c1
|
||||
v.l3 = v.l3&maskLow51Bits + c2
|
||||
v.l4 = v.l4&maskLow51Bits + c3
|
||||
|
||||
return v
|
||||
}
|
||||
1
vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
generated
vendored
1
vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
generated
vendored
|
|
@ -1 +0,0 @@
|
|||
b0c49ae9f59d233526f8934262c5bbbe14d4358d
|
||||
19
vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
generated
vendored
19
vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
#! /bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
|
||||
STD_PATH=src/crypto/ed25519/internal/edwards25519/field
|
||||
LOCAL_PATH=curve25519/internal/field
|
||||
LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint)
|
||||
|
||||
git fetch https://go.googlesource.com/go master
|
||||
|
||||
if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then
|
||||
echo "No changes."
|
||||
else
|
||||
NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint)
|
||||
echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..."
|
||||
git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \
|
||||
git apply -3 --directory=$LOCAL_PATH
|
||||
fi
|
||||
4
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
4
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
|
|
@ -11,9 +11,7 @@
|
|||
// operations with the same key more efficient. This package refers to the RFC
|
||||
// 8032 private key as the “seed”.
|
||||
//
|
||||
// Beginning with Go 1.13, the functionality of this package was moved to the
|
||||
// standard library as crypto/ed25519. This package only acts as a compatibility
|
||||
// wrapper.
|
||||
// This package is a wrapper around the standard library crypto/ed25519 package.
|
||||
package ed25519
|
||||
|
||||
import (
|
||||
|
|
|
|||
2
vendor/golang.org/x/crypto/hkdf/hkdf.go
generated
vendored
2
vendor/golang.org/x/crypto/hkdf/hkdf.go
generated
vendored
|
|
@ -8,7 +8,7 @@
|
|||
// HKDF is a cryptographic key derivation function (KDF) with the goal of
|
||||
// expanding limited input keying material into one or more cryptographically
|
||||
// strong secret keys.
|
||||
package hkdf // import "golang.org/x/crypto/hkdf"
|
||||
package hkdf
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
|
|
|
|||
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
|
|
@ -16,7 +16,7 @@ Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
|
|||
choose, you can pass the `New` functions from the different SHA packages to
|
||||
pbkdf2.Key.
|
||||
*/
|
||||
package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
|
||||
package pbkdf2
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
|
|
|
|||
4
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
|
|
@ -71,6 +71,10 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||
for auth := AuthMethod(new(noneAuth)); auth != nil; {
|
||||
ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
|
||||
if err != nil {
|
||||
// On disconnect, return error immediately
|
||||
if _, ok := err.(*disconnectMsg); ok {
|
||||
return err
|
||||
}
|
||||
// We return the error later if there is no other method left to
|
||||
// try.
|
||||
ok = authFailure
|
||||
|
|
|
|||
2
vendor/golang.org/x/crypto/ssh/doc.go
generated
vendored
2
vendor/golang.org/x/crypto/ssh/doc.go
generated
vendored
|
|
@ -20,4 +20,4 @@ References:
|
|||
This package does not fall under the stability promise of the Go language itself,
|
||||
so its API may be changed when pressing needs arise.
|
||||
*/
|
||||
package ssh // import "golang.org/x/crypto/ssh"
|
||||
package ssh
|
||||
|
|
|
|||
4
vendor/golang.org/x/exp/LICENSE
generated
vendored
4
vendor/golang.org/x/exp/LICENSE
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
|
@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
|||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
|
|
|
|||
5
vendor/golang.org/x/sys/unix/mremap.go
generated
vendored
5
vendor/golang.org/x/sys/unix/mremap.go
generated
vendored
|
|
@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
|
|||
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||
return mapper.Mremap(oldData, newLength, flags)
|
||||
}
|
||||
|
||||
func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {
|
||||
xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))
|
||||
return unsafe.Pointer(xaddr), err
|
||||
}
|
||||
|
|
|
|||
12
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
12
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
|
|
@ -542,6 +542,18 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
|
|||
}
|
||||
}
|
||||
|
||||
//sys pthread_chdir_np(path string) (err error)
|
||||
|
||||
func PthreadChdir(path string) (err error) {
|
||||
return pthread_chdir_np(path)
|
||||
}
|
||||
|
||||
//sys pthread_fchdir_np(fd int) (err error)
|
||||
|
||||
func PthreadFchdir(fd int) (err error) {
|
||||
return pthread_fchdir_np(fd)
|
||||
}
|
||||
|
||||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
||||
|
||||
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
||||
|
|
|
|||
9
vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
9
vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
|
|
@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) {
|
|||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
|
||||
xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
|
||||
return unsafe.Pointer(xaddr), err
|
||||
}
|
||||
|
||||
func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
|
||||
return mapper.munmap(uintptr(addr), length)
|
||||
}
|
||||
|
||||
func Read(fd int, p []byte) (n int, err error) {
|
||||
n, err = read(fd, p)
|
||||
if raceenabled {
|
||||
|
|
|
|||
33
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
generated
vendored
33
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
generated
vendored
|
|
@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pthread_chdir_np(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_pthread_chdir_np_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pthread_fchdir_np(fd int) (err error) {
|
||||
_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_pthread_fchdir_np_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
|
||||
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
|
||||
if e1 != 0 {
|
||||
|
|
|
|||
10
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
generated
vendored
10
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
generated
vendored
|
|
@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
|
|||
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
|
||||
|
||||
TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_pthread_chdir_np(SB)
|
||||
GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
|
||||
|
||||
TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_pthread_fchdir_np(SB)
|
||||
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
|
||||
|
||||
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendfile(SB)
|
||||
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
|
||||
|
|
|
|||
33
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
generated
vendored
33
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
generated
vendored
|
|
@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pthread_chdir_np(path string) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_pthread_chdir_np_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func pthread_fchdir_np(fd int) (err error) {
|
||||
_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_pthread_fchdir_np_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
|
||||
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
|
||||
if e1 != 0 {
|
||||
|
|
|
|||
10
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
generated
vendored
10
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
generated
vendored
|
|
@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
|
|||
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
|
||||
|
||||
TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_pthread_chdir_np(SB)
|
||||
GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
|
||||
|
||||
TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_pthread_fchdir_np(SB)
|
||||
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
|
||||
|
||||
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendfile(SB)
|
||||
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
|
||||
|
|
|
|||
24
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
24
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
|
|
@ -894,7 +894,7 @@ type ACL struct {
|
|||
aclRevision byte
|
||||
sbz1 byte
|
||||
aclSize uint16
|
||||
aceCount uint16
|
||||
AceCount uint16
|
||||
sbz2 uint16
|
||||
}
|
||||
|
||||
|
|
@ -1087,6 +1087,27 @@ type EXPLICIT_ACCESS struct {
|
|||
Trustee TRUSTEE
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
|
||||
type ACE_HEADER struct {
|
||||
AceType uint8
|
||||
AceFlags uint8
|
||||
AceSize uint16
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
|
||||
type ACCESS_ALLOWED_ACE struct {
|
||||
Header ACE_HEADER
|
||||
Mask ACCESS_MASK
|
||||
SidStart uint32
|
||||
}
|
||||
|
||||
const (
|
||||
// Constants for AceType
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
|
||||
ACCESS_ALLOWED_ACE_TYPE = 0
|
||||
ACCESS_DENIED_ACE_TYPE = 1
|
||||
)
|
||||
|
||||
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
|
||||
type TrusteeValue uintptr
|
||||
|
||||
|
|
@ -1158,6 +1179,7 @@ type OBJECTS_AND_NAME struct {
|
|||
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
|
||||
|
||||
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
|
||||
//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) = advapi32.GetAce
|
||||
|
||||
// Control returns the security descriptor control bits.
|
||||
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
|
||||
|
|
|
|||
9
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
9
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
|
|
@ -91,6 +91,7 @@ var (
|
|||
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
|
||||
procEqualSid = modadvapi32.NewProc("EqualSid")
|
||||
procFreeSid = modadvapi32.NewProc("FreeSid")
|
||||
procGetAce = modadvapi32.NewProc("GetAce")
|
||||
procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
|
||||
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
|
||||
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
|
||||
|
|
@ -1224,6 +1225,14 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE
|
|||
return
|
||||
}
|
||||
|
||||
func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) {
|
||||
r0, _, _ := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
|
||||
if r0 == 0 {
|
||||
ret = GetLastError()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor)))
|
||||
if r1 == 0 {
|
||||
|
|
|
|||
2
vendor/maunium.net/go/mautrix/.gitignore
generated
vendored
2
vendor/maunium.net/go/mautrix/.gitignore
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
.idea/
|
||||
.vscode/
|
||||
*.db
|
||||
*.db*
|
||||
*.log
|
||||
|
|
|
|||
3
vendor/maunium.net/go/mautrix/.pre-commit-config.yaml
generated
vendored
3
vendor/maunium.net/go/mautrix/.pre-commit-config.yaml
generated
vendored
|
|
@ -1,6 +1,6 @@
|
|||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
exclude_types: [markdown]
|
||||
|
|
@ -17,6 +17,7 @@ repos:
|
|||
- "maunium.net/go/mautrix"
|
||||
- "-w"
|
||||
- id: go-vet-repo-mod
|
||||
- id: go-mod-tidy
|
||||
|
||||
- repo: https://github.com/beeper/pre-commit-go
|
||||
rev: v0.3.1
|
||||
|
|
|
|||
66
vendor/maunium.net/go/mautrix/CHANGELOG.md
generated
vendored
66
vendor/maunium.net/go/mautrix/CHANGELOG.md
generated
vendored
|
|
@ -1,3 +1,69 @@
|
|||
## v0.19.0 (2024-07-16)
|
||||
|
||||
* Renamed `master` branch to `main`.
|
||||
* *(bridgev2)* Added more features.
|
||||
* *(crypto)* Fixed bug with copying `m.relates_to` from wire content to
|
||||
decrypted content.
|
||||
* *(mediaproxy)* Added module for implementing simple media repos that proxy
|
||||
requests elsewhere.
|
||||
* *(client)* Changed `Members()` to automatically parse event content for all
|
||||
returned events.
|
||||
* *(bridge)* Added `/register` call if `/versions` fails with `M_FORBIDDEN`.
|
||||
* *(crypto)* Fixed `DecryptMegolmEvent` sometimes calling database without
|
||||
transaction by using the non-context version of `ResolveTrust`.
|
||||
* *(crypto/attachment)* Implemented `io.Seeker` in `EncryptStream` to allow
|
||||
using it in retriable HTTP requests.
|
||||
* *(event)* Added helper method to add user ID to a `Mentions` object.
|
||||
* *(event)* Fixed default power level for invites
|
||||
(thanks to [@rudis] in [#250]).
|
||||
* *(client)* Fixed incorrect warning log in `State()` when state store returns
|
||||
no error (thanks to [@rudis] in [#249]).
|
||||
* *(crypto/verificationhelper)* Fixed deadlock when ignoring unknown
|
||||
cancellation events (thanks to [@rudis] in [#247]).
|
||||
|
||||
[@rudis]: https://github.com/rudis
|
||||
[#250]: https://github.com/mautrix/go/pull/250
|
||||
[#249]: https://github.com/mautrix/go/pull/249
|
||||
[#247]: https://github.com/mautrix/go/pull/247
|
||||
|
||||
### beta.1 (2024-06-16)
|
||||
|
||||
* *(bridgev2)* Added experimental high-level bridge framework.
|
||||
* *(hicli)* Added experimental high-level client framework.
|
||||
* **Slightly breaking changes**
|
||||
* *(crypto)* Added room ID and first known index parameters to
|
||||
`SessionReceived` callback.
|
||||
* *(crypto)* Changed `ImportRoomKeyFromBackup` to return the imported
|
||||
session.
|
||||
* *(client)* Added `error` parameter to `ResponseHook`.
|
||||
* *(client)* Changed `Download` to return entire response instead of just an
|
||||
`io.Reader`.
|
||||
* *(crypto)* Changed initial olm device sharing to save keys before sharing to
|
||||
ensure keys aren't accidentally regenerated in case the request fails.
|
||||
* *(crypto)* Changed `EncryptMegolmEvent` and `ShareGroupSession` to return
|
||||
more errors instead of only logging and ignoring them.
|
||||
* *(crypto)* Added option to completely disable megolm ratchet tracking.
|
||||
* The tracking is meant for bots and bridges which may want to delete old
|
||||
keys, but for normal clients it's just unnecessary overhead.
|
||||
* *(crypto)* Changed Megolm session storage methods in `Store` to not take
|
||||
sender key as parameter.
|
||||
* This causes a breaking change to the layout of the `MemoryStore` struct.
|
||||
Using MemoryStore in production is not recommended.
|
||||
* *(crypto)* Changed `DecryptMegolmEvent` to copy `m.relates_to` in the raw
|
||||
content too instead of only in the parsed struct.
|
||||
* *(crypto)* Exported function to parse megolm message index from raw
|
||||
ciphertext bytes.
|
||||
* *(crypto/sqlstore)* Fixed schema of `crypto_secrets` table to include
|
||||
account ID.
|
||||
* *(crypto/verificationhelper)* Fixed more bugs.
|
||||
* *(client)* Added `UpdateRequestOnRetry` hook which is called immediately
|
||||
before retrying a normal HTTP request.
|
||||
* *(client)* Added support for MSC3916 media download endpoint.
|
||||
* Support is automatically detected from spec versions. The `SpecVersions`
|
||||
property can either be filled manually, or `Versions` can be called to
|
||||
automatically populate the field with the response.
|
||||
* *(event)* Added constants for known room versions.
|
||||
|
||||
## v0.18.1 (2024-04-16)
|
||||
|
||||
* *(format)* Added a `context.Context` field to HTMLParser's Context struct.
|
||||
|
|
|
|||
5
vendor/maunium.net/go/mautrix/README.md
generated
vendored
5
vendor/maunium.net/go/mautrix/README.md
generated
vendored
|
|
@ -5,7 +5,7 @@ A Golang Matrix framework. Used by [gomuks](https://matrix.org/docs/projects/cli
|
|||
[go-neb](https://github.com/matrix-org/go-neb), [mautrix-whatsapp](https://github.com/mautrix/whatsapp)
|
||||
and others.
|
||||
|
||||
Matrix room: [`#maunium:maunium.net`](https://matrix.to/#/#maunium:maunium.net)
|
||||
Matrix room: [`#go:maunium.net`](https://matrix.to/#/#go:maunium.net)
|
||||
|
||||
This project is based on [matrix-org/gomatrix](https://github.com/matrix-org/gomatrix).
|
||||
The original project is licensed under [Apache 2.0](https://github.com/matrix-org/gomatrix/blob/master/LICENSE).
|
||||
|
|
@ -14,6 +14,9 @@ In addition to the basic client API features the original project has, this fram
|
|||
|
||||
* Appservice support (Intent API like mautrix-python, room state storage, etc)
|
||||
* End-to-end encryption support (incl. interactive SAS verification)
|
||||
* High-level module for building puppeting bridges
|
||||
* High-level module for building chat clients
|
||||
* Wrapper functions for the Synapse admin API
|
||||
* Structs for parsing event content
|
||||
* Helpers for parsing and generating Matrix HTML
|
||||
* Helpers for handling push rules
|
||||
|
|
|
|||
271
vendor/maunium.net/go/mautrix/client.go
generated
vendored
271
vendor/maunium.net/go/mautrix/client.go
generated
vendored
|
|
@ -61,11 +61,14 @@ type Client struct {
|
|||
StateStore StateStore
|
||||
Crypto CryptoHelper
|
||||
Verification VerificationHelper
|
||||
SpecVersions *RespVersions
|
||||
|
||||
Log zerolog.Logger
|
||||
|
||||
RequestHook func(req *http.Request)
|
||||
ResponseHook func(req *http.Request, resp *http.Response, duration time.Duration)
|
||||
ResponseHook func(req *http.Request, resp *http.Response, err error, duration time.Duration)
|
||||
|
||||
UpdateRequestOnRetry func(req *http.Request, cause error) *http.Request
|
||||
|
||||
SyncPresence event.Presence
|
||||
|
||||
|
|
@ -74,6 +77,8 @@ type Client struct {
|
|||
// Number of times that mautrix will retry any HTTP request
|
||||
// if the request fails entirely or returns a HTTP gateway error (502-504)
|
||||
DefaultHTTPRetries int
|
||||
// Amount of time to wait between HTTP retries, defaults to 4 seconds
|
||||
DefaultHTTPBackoff time.Duration
|
||||
// Set to true to disable automatically sleeping on 429 errors.
|
||||
IgnoreRateLimit bool
|
||||
|
||||
|
|
@ -197,14 +202,20 @@ func (cli *Client) SyncWithContext(ctx context.Context) error {
|
|||
}
|
||||
}
|
||||
lastSuccessfulSync := time.Now().Add(-cli.StreamSyncMinAge - 1*time.Hour)
|
||||
// Always do first sync with 0 timeout
|
||||
isFailing := true
|
||||
for {
|
||||
streamResp := false
|
||||
if cli.StreamSyncMinAge > 0 && time.Since(lastSuccessfulSync) > cli.StreamSyncMinAge {
|
||||
cli.Log.Debug().Msg("Last sync is old, will stream next response")
|
||||
streamResp = true
|
||||
}
|
||||
timeout := 30000
|
||||
if isFailing {
|
||||
timeout = 0
|
||||
}
|
||||
resSync, err := cli.FullSyncRequest(ctx, ReqSync{
|
||||
Timeout: 30000,
|
||||
Timeout: timeout,
|
||||
Since: nextBatch,
|
||||
FilterID: filterID,
|
||||
FullState: false,
|
||||
|
|
@ -212,6 +223,7 @@ func (cli *Client) SyncWithContext(ctx context.Context) error {
|
|||
StreamResponse: streamResp,
|
||||
})
|
||||
if err != nil {
|
||||
isFailing = true
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
|
@ -219,6 +231,9 @@ func (cli *Client) SyncWithContext(ctx context.Context) error {
|
|||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
if duration <= 0 {
|
||||
continue
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
|
@ -226,6 +241,7 @@ func (cli *Client) SyncWithContext(ctx context.Context) error {
|
|||
continue
|
||||
}
|
||||
}
|
||||
isFailing = false
|
||||
lastSuccessfulSync = time.Now()
|
||||
|
||||
// Check that the syncing state hasn't changed
|
||||
|
|
@ -291,10 +307,10 @@ func (cli *Client) LogRequestDone(req *http.Request, resp *http.Response, err er
|
|||
Str("method", req.Method).
|
||||
Str("url", req.URL.String()).
|
||||
Dur("duration", duration)
|
||||
if cli.ResponseHook != nil {
|
||||
cli.ResponseHook(req, resp, err, duration)
|
||||
}
|
||||
if resp != nil {
|
||||
if cli.ResponseHook != nil {
|
||||
cli.ResponseHook(req, resp, duration)
|
||||
}
|
||||
mime := resp.Header.Get("Content-Type")
|
||||
length := resp.ContentLength
|
||||
if length == -1 && contentLength > 0 {
|
||||
|
|
@ -319,7 +335,7 @@ func (cli *Client) LogRequestDone(req *http.Request, resp *http.Response, err er
|
|||
}
|
||||
}
|
||||
|
||||
func (cli *Client) MakeRequest(ctx context.Context, method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
|
||||
func (cli *Client) MakeRequest(ctx context.Context, method string, httpURL string, reqBody any, resBody any) ([]byte, error) {
|
||||
return cli.MakeFullRequest(ctx, FullRequest{Method: method, URL: httpURL, RequestJSON: reqBody, ResponseJSON: resBody})
|
||||
}
|
||||
|
||||
|
|
@ -335,8 +351,10 @@ type FullRequest struct {
|
|||
RequestLength int64
|
||||
ResponseJSON interface{}
|
||||
MaxAttempts int
|
||||
BackoffDuration time.Duration
|
||||
SensitiveContent bool
|
||||
Handler ClientResponseHandler
|
||||
DontReadResponse bool
|
||||
Logger *zerolog.Logger
|
||||
Client *http.Client
|
||||
}
|
||||
|
|
@ -401,25 +419,35 @@ func (params *FullRequest) compileRequest(ctx context.Context) (*http.Request, e
|
|||
return req, nil
|
||||
}
|
||||
|
||||
// MakeFullRequest makes a JSON HTTP request to the given URL.
|
||||
// If "resBody" is not nil, the response body will be json.Unmarshalled into it.
|
||||
//
|
||||
// Returns the HTTP body as bytes on 2xx with a nil error. Returns an error if the response is not 2xx along
|
||||
// with the HTTP body bytes if it got that far. This error is an HTTPError which includes the returned
|
||||
// HTTP status code and possibly a RespError as the WrappedError, if the HTTP body could be decoded as a RespError.
|
||||
func (cli *Client) MakeFullRequest(ctx context.Context, params FullRequest) ([]byte, error) {
|
||||
data, _, err := cli.MakeFullRequestWithResp(ctx, params)
|
||||
return data, err
|
||||
}
|
||||
|
||||
func (cli *Client) MakeFullRequestWithResp(ctx context.Context, params FullRequest) ([]byte, *http.Response, error) {
|
||||
if params.MaxAttempts == 0 {
|
||||
params.MaxAttempts = 1 + cli.DefaultHTTPRetries
|
||||
}
|
||||
if params.BackoffDuration == 0 {
|
||||
if cli.DefaultHTTPBackoff == 0 {
|
||||
params.BackoffDuration = 4 * time.Second
|
||||
} else {
|
||||
params.BackoffDuration = cli.DefaultHTTPBackoff
|
||||
}
|
||||
}
|
||||
if params.Logger == nil {
|
||||
params.Logger = &cli.Log
|
||||
}
|
||||
req, err := params.compileRequest(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
if params.Handler == nil {
|
||||
params.Handler = handleNormalResponse
|
||||
if params.DontReadResponse {
|
||||
params.Handler = noopHandleResponse
|
||||
} else {
|
||||
params.Handler = handleNormalResponse
|
||||
}
|
||||
}
|
||||
req.Header.Set("User-Agent", cli.UserAgent)
|
||||
if len(cli.AccessToken) > 0 {
|
||||
|
|
@ -428,7 +456,7 @@ func (cli *Client) MakeFullRequest(ctx context.Context, params FullRequest) ([]b
|
|||
if params.Client == nil {
|
||||
params.Client = cli.Client
|
||||
}
|
||||
return cli.executeCompiledRequest(req, params.MaxAttempts-1, 4*time.Second, params.ResponseJSON, params.Handler, params.Client)
|
||||
return cli.executeCompiledRequest(req, params.MaxAttempts-1, params.BackoffDuration, params.ResponseJSON, params.Handler, params.DontReadResponse, params.Client)
|
||||
}
|
||||
|
||||
func (cli *Client) cliOrContextLog(ctx context.Context) *zerolog.Logger {
|
||||
|
|
@ -439,28 +467,38 @@ func (cli *Client) cliOrContextLog(ctx context.Context) *zerolog.Logger {
|
|||
return log
|
||||
}
|
||||
|
||||
func (cli *Client) doRetry(req *http.Request, cause error, retries int, backoff time.Duration, responseJSON interface{}, handler ClientResponseHandler, client *http.Client) ([]byte, error) {
|
||||
func (cli *Client) doRetry(req *http.Request, cause error, retries int, backoff time.Duration, responseJSON any, handler ClientResponseHandler, dontReadResponse bool, client *http.Client) ([]byte, *http.Response, error) {
|
||||
log := zerolog.Ctx(req.Context())
|
||||
if req.Body != nil {
|
||||
if req.GetBody == nil {
|
||||
log.Warn().Msg("Failed to get new body to retry request: GetBody is nil")
|
||||
return nil, cause
|
||||
}
|
||||
var err error
|
||||
req.Body, err = req.GetBody()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to get new body to retry request")
|
||||
return nil, cause
|
||||
if req.GetBody != nil {
|
||||
req.Body, err = req.GetBody()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to get new body to retry request")
|
||||
return nil, nil, cause
|
||||
}
|
||||
} else if bodySeeker, ok := req.Body.(io.ReadSeeker); ok {
|
||||
_, err = bodySeeker.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to seek to beginning of request body")
|
||||
return nil, nil, cause
|
||||
}
|
||||
} else {
|
||||
log.Warn().Msg("Failed to get new body to retry request: GetBody is nil and Body is not an io.ReadSeeker")
|
||||
return nil, nil, cause
|
||||
}
|
||||
}
|
||||
log.Warn().Err(cause).
|
||||
Int("retry_in_seconds", int(backoff.Seconds())).
|
||||
Msg("Request failed, retrying")
|
||||
time.Sleep(backoff)
|
||||
return cli.executeCompiledRequest(req, retries-1, backoff*2, responseJSON, handler, client)
|
||||
if cli.UpdateRequestOnRetry != nil {
|
||||
req = cli.UpdateRequestOnRetry(req, cause)
|
||||
}
|
||||
return cli.executeCompiledRequest(req, retries-1, backoff*2, responseJSON, handler, dontReadResponse, client)
|
||||
}
|
||||
|
||||
func readRequestBody(req *http.Request, res *http.Response) ([]byte, error) {
|
||||
func readResponseBody(req *http.Request, res *http.Response) ([]byte, error) {
|
||||
contents, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, HTTPError{
|
||||
|
|
@ -502,8 +540,12 @@ func streamResponse(req *http.Request, res *http.Response, responseJSON interfac
|
|||
}
|
||||
}
|
||||
|
||||
func noopHandleResponse(req *http.Request, res *http.Response, responseJSON interface{}) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func handleNormalResponse(req *http.Request, res *http.Response, responseJSON interface{}) ([]byte, error) {
|
||||
if contents, err := readRequestBody(req, res); err != nil {
|
||||
if contents, err := readResponseBody(req, res); err != nil {
|
||||
return nil, err
|
||||
} else if responseJSON == nil {
|
||||
return contents, nil
|
||||
|
|
@ -522,7 +564,7 @@ func handleNormalResponse(req *http.Request, res *http.Response, responseJSON in
|
|||
}
|
||||
|
||||
func ParseErrorResponse(req *http.Request, res *http.Response) ([]byte, error) {
|
||||
contents, err := readRequestBody(req, res)
|
||||
contents, err := readResponseBody(req, res)
|
||||
if err != nil {
|
||||
return contents, err
|
||||
}
|
||||
|
|
@ -539,17 +581,17 @@ func ParseErrorResponse(req *http.Request, res *http.Response) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (cli *Client) executeCompiledRequest(req *http.Request, retries int, backoff time.Duration, responseJSON interface{}, handler ClientResponseHandler, client *http.Client) ([]byte, error) {
|
||||
func (cli *Client) executeCompiledRequest(req *http.Request, retries int, backoff time.Duration, responseJSON any, handler ClientResponseHandler, dontReadResponse bool, client *http.Client) ([]byte, *http.Response, error) {
|
||||
cli.RequestStart(req)
|
||||
startTime := time.Now()
|
||||
res, err := client.Do(req)
|
||||
duration := time.Now().Sub(startTime)
|
||||
if res != nil {
|
||||
if res != nil && !dontReadResponse {
|
||||
defer res.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
if retries > 0 {
|
||||
return cli.doRetry(req, err, retries, backoff, responseJSON, handler, client)
|
||||
return cli.doRetry(req, err, retries, backoff, responseJSON, handler, dontReadResponse, client)
|
||||
}
|
||||
err = HTTPError{
|
||||
Request: req,
|
||||
|
|
@ -559,12 +601,12 @@ func (cli *Client) executeCompiledRequest(req *http.Request, retries int, backof
|
|||
WrappedError: err,
|
||||
}
|
||||
cli.LogRequestDone(req, res, err, nil, 0, duration)
|
||||
return nil, err
|
||||
return nil, res, err
|
||||
}
|
||||
|
||||
if retries > 0 && retryafter.Should(res.StatusCode, !cli.IgnoreRateLimit) {
|
||||
backoff = retryafter.Parse(res.Header.Get("Retry-After"), backoff)
|
||||
return cli.doRetry(req, fmt.Errorf("HTTP %d", res.StatusCode), retries, backoff, responseJSON, handler, client)
|
||||
return cli.doRetry(req, fmt.Errorf("HTTP %d", res.StatusCode), retries, backoff, responseJSON, handler, dontReadResponse, client)
|
||||
}
|
||||
|
||||
var body []byte
|
||||
|
|
@ -575,7 +617,7 @@ func (cli *Client) executeCompiledRequest(req *http.Request, retries int, backof
|
|||
body, err = handler(req, res, responseJSON)
|
||||
cli.LogRequestDone(req, res, nil, err, len(body), duration)
|
||||
}
|
||||
return body, err
|
||||
return body, res, err
|
||||
}
|
||||
|
||||
// Whoami gets the user ID of the current user. See https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3accountwhoami
|
||||
|
|
@ -605,12 +647,14 @@ func (cli *Client) SyncRequest(ctx context.Context, timeout int, since, filterID
|
|||
}
|
||||
|
||||
type ReqSync struct {
|
||||
Timeout int
|
||||
Since string
|
||||
FilterID string
|
||||
FullState bool
|
||||
SetPresence event.Presence
|
||||
StreamResponse bool
|
||||
Timeout int
|
||||
Since string
|
||||
FilterID string
|
||||
FullState bool
|
||||
SetPresence event.Presence
|
||||
StreamResponse bool
|
||||
BeeperStreaming bool
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
func (req *ReqSync) BuildQuery() map[string]string {
|
||||
|
|
@ -629,6 +673,11 @@ func (req *ReqSync) BuildQuery() map[string]string {
|
|||
if req.FullState {
|
||||
query["full_state"] = "true"
|
||||
}
|
||||
if req.BeeperStreaming {
|
||||
// TODO remove this
|
||||
query["streaming"] = ""
|
||||
query["com.beeper.streaming"] = "true"
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
|
|
@ -639,6 +688,7 @@ func (cli *Client) FullSyncRequest(ctx context.Context, req ReqSync) (resp *Resp
|
|||
Method: http.MethodGet,
|
||||
URL: urlPath,
|
||||
ResponseJSON: &resp,
|
||||
Client: req.Client,
|
||||
// We don't want automatic retries for SyncRequest, the Sync() wrapper handles those.
|
||||
MaxAttempts: 1,
|
||||
}
|
||||
|
|
@ -830,6 +880,9 @@ func (cli *Client) LogoutAll(ctx context.Context) (resp *RespLogout, err error)
|
|||
func (cli *Client) Versions(ctx context.Context) (resp *RespVersions, err error) {
|
||||
urlPath := cli.BuildClientURL("versions")
|
||||
_, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp)
|
||||
if resp != nil {
|
||||
cli.SpecVersions = resp
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -941,9 +994,9 @@ func (cli *Client) SetAvatarURL(ctx context.Context, url id.ContentURI) (err err
|
|||
}
|
||||
|
||||
// BeeperUpdateProfile sets custom fields in the user's profile.
|
||||
func (cli *Client) BeeperUpdateProfile(ctx context.Context, data map[string]any) (err error) {
|
||||
func (cli *Client) BeeperUpdateProfile(ctx context.Context, data any) (err error) {
|
||||
urlPath := cli.BuildClientURL("v3", "profile", cli.UserID)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPatch, urlPath, &data, nil)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPatch, urlPath, data, nil)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -1358,9 +1411,11 @@ func (cli *Client) State(ctx context.Context, roomID id.RoomID) (stateMap RoomSt
|
|||
})
|
||||
if err == nil && cli.StateStore != nil {
|
||||
clearErr := cli.StateStore.ClearCachedMembers(ctx, roomID)
|
||||
cli.cliOrContextLog(ctx).Warn().Err(clearErr).
|
||||
Stringer("room_id", roomID).
|
||||
Msg("Failed to clear cached member list after fetching state")
|
||||
if clearErr != nil {
|
||||
cli.cliOrContextLog(ctx).Warn().Err(clearErr).
|
||||
Stringer("room_id", roomID).
|
||||
Msg("Failed to clear cached member list after fetching state")
|
||||
}
|
||||
for _, evts := range stateMap {
|
||||
for _, evt := range evts {
|
||||
UpdateStateStore(ctx, cli.StateStore, evt)
|
||||
|
|
@ -1372,7 +1427,12 @@ func (cli *Client) State(ctx context.Context, roomID id.RoomID) (stateMap RoomSt
|
|||
|
||||
// GetMediaConfig fetches the configuration of the content repository, such as upload limitations.
|
||||
func (cli *Client) GetMediaConfig(ctx context.Context) (resp *RespMediaConfig, err error) {
|
||||
u := cli.BuildURL(MediaURLPath{"v3", "config"})
|
||||
var u string
|
||||
if cli.SpecVersions.ContainsGreaterOrEqual(SpecV111) {
|
||||
u = cli.BuildClientURL("v1", "media", "config")
|
||||
} else {
|
||||
u = cli.BuildURL(MediaURLPath{"v3", "config"})
|
||||
}
|
||||
_, err = cli.MakeRequest(ctx, http.MethodGet, u, nil, &resp)
|
||||
return
|
||||
}
|
||||
|
|
@ -1394,29 +1454,29 @@ func (cli *Client) UploadLink(ctx context.Context, link string) (*RespMediaUploa
|
|||
return cli.Upload(ctx, res.Body, res.Header.Get("Content-Type"), res.ContentLength)
|
||||
}
|
||||
|
||||
// Deprecated: unauthenticated media is deprecated as of Matrix v1.11. Use [Download] or [DownloadBytes] instead.
|
||||
func (cli *Client) GetDownloadURL(mxcURL id.ContentURI) string {
|
||||
return cli.BuildURLWithQuery(MediaURLPath{"v3", "download", mxcURL.Homeserver, mxcURL.FileID}, map[string]string{"allow_redirect": "true"})
|
||||
}
|
||||
|
||||
func (cli *Client) Download(ctx context.Context, mxcURL id.ContentURI) (io.ReadCloser, error) {
|
||||
resp, err := cli.download(ctx, mxcURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
func (cli *Client) doMediaRetry(req *http.Request, cause error, retries int, backoff time.Duration) (*http.Response, error) {
|
||||
log := zerolog.Ctx(req.Context())
|
||||
if req.Body != nil {
|
||||
if req.GetBody == nil {
|
||||
log.Warn().Msg("Failed to get new body to retry request: GetBody is nil")
|
||||
return nil, cause
|
||||
}
|
||||
var err error
|
||||
req.Body, err = req.GetBody()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to get new body to retry request")
|
||||
if req.GetBody != nil {
|
||||
req.Body, err = req.GetBody()
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to get new body to retry request")
|
||||
return nil, cause
|
||||
}
|
||||
} else if bodySeeker, ok := req.Body.(io.ReadSeeker); ok {
|
||||
_, err = bodySeeker.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to seek to beginning of request body")
|
||||
return nil, cause
|
||||
}
|
||||
} else {
|
||||
log.Warn().Msg("Failed to get new body to retry request: GetBody is nil and Body is not an io.ReadSeeker")
|
||||
return nil, cause
|
||||
}
|
||||
}
|
||||
|
|
@ -1462,21 +1522,30 @@ func (cli *Client) doMediaRequest(req *http.Request, retries int, backoff time.D
|
|||
return res, err
|
||||
}
|
||||
|
||||
func (cli *Client) download(ctx context.Context, mxcURL id.ContentURI) (*http.Response, error) {
|
||||
func (cli *Client) Download(ctx context.Context, mxcURL id.ContentURI) (*http.Response, error) {
|
||||
ctxLog := zerolog.Ctx(ctx)
|
||||
if ctxLog.GetLevel() == zerolog.Disabled || ctxLog == zerolog.DefaultContextLogger {
|
||||
ctx = cli.Log.WithContext(ctx)
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, cli.GetDownloadURL(mxcURL), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if cli.SpecVersions.ContainsGreaterOrEqual(SpecV111) {
|
||||
_, resp, err := cli.MakeFullRequestWithResp(ctx, FullRequest{
|
||||
Method: http.MethodGet,
|
||||
URL: cli.BuildClientURL("v1", "media", "download", mxcURL.Homeserver, mxcURL.FileID),
|
||||
DontReadResponse: true,
|
||||
})
|
||||
return resp, err
|
||||
} else {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, cli.GetDownloadURL(mxcURL), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("User-Agent", cli.UserAgent+" (media downloader)")
|
||||
return cli.doMediaRequest(req, cli.DefaultHTTPRetries, 4*time.Second)
|
||||
}
|
||||
req.Header.Set("User-Agent", cli.UserAgent+" (media downloader)")
|
||||
return cli.doMediaRequest(req, cli.DefaultHTTPRetries, 4*time.Second)
|
||||
}
|
||||
|
||||
func (cli *Client) DownloadBytes(ctx context.Context, mxcURL id.ContentURI) ([]byte, error) {
|
||||
resp, err := cli.download(ctx, mxcURL)
|
||||
resp, err := cli.Download(ctx, mxcURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1488,13 +1557,8 @@ func (cli *Client) DownloadBytes(ctx context.Context, mxcURL id.ContentURI) ([]b
|
|||
//
|
||||
// See https://spec.matrix.org/v1.7/client-server-api/#post_matrixmediav1create
|
||||
func (cli *Client) CreateMXC(ctx context.Context) (*RespCreateMXC, error) {
|
||||
u, _ := url.Parse(cli.BuildURL(MediaURLPath{"v1", "create"}))
|
||||
var m RespCreateMXC
|
||||
_, err := cli.MakeFullRequest(ctx, FullRequest{
|
||||
Method: http.MethodPost,
|
||||
URL: u.String(),
|
||||
ResponseJSON: &m,
|
||||
})
|
||||
_, err := cli.MakeRequest(ctx, http.MethodPost, cli.BuildURL(MediaURLPath{"v1", "create"}), nil, &m)
|
||||
return &m, err
|
||||
}
|
||||
|
||||
|
|
@ -1558,12 +1622,13 @@ type ReqUploadMedia struct {
|
|||
UnstableUploadURL string
|
||||
}
|
||||
|
||||
func (cli *Client) tryUploadMediaToURL(ctx context.Context, url, contentType string, content io.Reader) (*http.Response, error) {
|
||||
func (cli *Client) tryUploadMediaToURL(ctx context.Context, url, contentType string, content io.Reader, contentLength int64) (*http.Response, error) {
|
||||
cli.Log.Debug().Str("url", url).Msg("Uploading media to external URL")
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, url, content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.ContentLength = contentLength
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.Header.Set("User-Agent", cli.UserAgent+" (external media uploader)")
|
||||
|
||||
|
|
@ -1572,18 +1637,17 @@ func (cli *Client) tryUploadMediaToURL(ctx context.Context, url, contentType str
|
|||
|
||||
func (cli *Client) uploadMediaToURL(ctx context.Context, data ReqUploadMedia) (*RespMediaUpload, error) {
|
||||
retries := cli.DefaultHTTPRetries
|
||||
if data.ContentBytes == nil {
|
||||
// Can't retry with a reader
|
||||
reader := data.Content
|
||||
if data.ContentBytes != nil {
|
||||
data.ContentLength = int64(len(data.ContentBytes))
|
||||
reader = bytes.NewReader(data.ContentBytes)
|
||||
}
|
||||
readerSeeker, canSeek := reader.(io.ReadSeeker)
|
||||
if !canSeek {
|
||||
retries = 0
|
||||
}
|
||||
for {
|
||||
reader := data.Content
|
||||
if reader == nil {
|
||||
reader = bytes.NewReader(data.ContentBytes)
|
||||
} else {
|
||||
data.Content = nil
|
||||
}
|
||||
resp, err := cli.tryUploadMediaToURL(ctx, data.UnstableUploadURL, data.ContentType, reader)
|
||||
resp, err := cli.tryUploadMediaToURL(ctx, data.UnstableUploadURL, data.ContentType, reader, data.ContentLength)
|
||||
if err == nil {
|
||||
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||
// Everything is fine
|
||||
|
|
@ -1599,6 +1663,10 @@ func (cli *Client) uploadMediaToURL(ctx context.Context, data ReqUploadMedia) (*
|
|||
cli.Log.Warn().Str("url", data.UnstableUploadURL).Err(err).
|
||||
Msg("Error uploading media to external URL, retrying")
|
||||
retries--
|
||||
_, err = readerSeeker.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to seek back to start of reader: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
query := map[string]string{}
|
||||
|
|
@ -1609,11 +1677,7 @@ func (cli *Client) uploadMediaToURL(ctx context.Context, data ReqUploadMedia) (*
|
|||
notifyURL := cli.BuildURLWithQuery(MediaURLPath{"unstable", "com.beeper.msc3870", "upload", data.MXC.Homeserver, data.MXC.FileID, "complete"}, query)
|
||||
|
||||
var m *RespMediaUpload
|
||||
_, err := cli.MakeFullRequest(ctx, FullRequest{
|
||||
Method: http.MethodPost,
|
||||
URL: notifyURL,
|
||||
ResponseJSON: m,
|
||||
})
|
||||
_, err := cli.MakeRequest(ctx, http.MethodPost, notifyURL, nil, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1664,7 +1728,13 @@ func (cli *Client) UploadMedia(ctx context.Context, data ReqUploadMedia) (*RespM
|
|||
//
|
||||
// See https://spec.matrix.org/v1.2/client-server-api/#get_matrixmediav3preview_url
|
||||
func (cli *Client) GetURLPreview(ctx context.Context, url string) (*RespPreviewURL, error) {
|
||||
reqURL := cli.BuildURLWithQuery(MediaURLPath{"v3", "preview_url"}, map[string]string{
|
||||
var urlPath PrefixableURLPath
|
||||
if cli.SpecVersions.ContainsGreaterOrEqual(SpecV111) {
|
||||
urlPath = ClientURLPath{"v1", "media", "preview_url"}
|
||||
} else {
|
||||
urlPath = MediaURLPath{"v3", "preview_url"}
|
||||
}
|
||||
reqURL := cli.BuildURLWithQuery(urlPath, map[string]string{
|
||||
"url": url,
|
||||
})
|
||||
var output RespPreviewURL
|
||||
|
|
@ -1720,6 +1790,11 @@ func (cli *Client) Members(ctx context.Context, roomID id.RoomID, req ...ReqMemb
|
|||
}
|
||||
u := cli.BuildURLWithQuery(ClientURLPath{"v3", "rooms", roomID, "members"}, query)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodGet, u, nil, &resp)
|
||||
if err == nil {
|
||||
for _, evt := range resp.Chunk {
|
||||
_ = evt.Content.ParseRaw(evt.Type)
|
||||
}
|
||||
}
|
||||
if err == nil && cli.StateStore != nil {
|
||||
var clearMemberships []event.Membership
|
||||
if extra.Membership != "" {
|
||||
|
|
@ -1857,15 +1932,13 @@ func (cli *Client) SetReadMarkers(ctx context.Context, roomID id.RoomID, content
|
|||
return
|
||||
}
|
||||
|
||||
func (cli *Client) AddTag(ctx context.Context, roomID id.RoomID, tag string, order float64) error {
|
||||
var tagData event.Tag
|
||||
if order == order {
|
||||
tagData.Order = json.Number(strconv.FormatFloat(order, 'e', -1, 64))
|
||||
}
|
||||
return cli.AddTagWithCustomData(ctx, roomID, tag, tagData)
|
||||
func (cli *Client) AddTag(ctx context.Context, roomID id.RoomID, tag event.RoomTag, order float64) error {
|
||||
return cli.AddTagWithCustomData(ctx, roomID, tag, &event.TagMetadata{
|
||||
Order: json.Number(strconv.FormatFloat(order, 'e', -1, 64)),
|
||||
})
|
||||
}
|
||||
|
||||
func (cli *Client) AddTagWithCustomData(ctx context.Context, roomID id.RoomID, tag string, data interface{}) (err error) {
|
||||
func (cli *Client) AddTagWithCustomData(ctx context.Context, roomID id.RoomID, tag event.RoomTag, data any) (err error) {
|
||||
urlPath := cli.BuildClientURL("v3", "user", cli.UserID, "rooms", roomID, "tags", tag)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodPut, urlPath, data, nil)
|
||||
return
|
||||
|
|
@ -1876,13 +1949,13 @@ func (cli *Client) GetTags(ctx context.Context, roomID id.RoomID) (tags event.Ta
|
|||
return
|
||||
}
|
||||
|
||||
func (cli *Client) GetTagsWithCustomData(ctx context.Context, roomID id.RoomID, resp interface{}) (err error) {
|
||||
func (cli *Client) GetTagsWithCustomData(ctx context.Context, roomID id.RoomID, resp any) (err error) {
|
||||
urlPath := cli.BuildClientURL("v3", "user", cli.UserID, "rooms", roomID, "tags")
|
||||
_, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp)
|
||||
return
|
||||
}
|
||||
|
||||
func (cli *Client) RemoveTag(ctx context.Context, roomID id.RoomID, tag string) (err error) {
|
||||
func (cli *Client) RemoveTag(ctx context.Context, roomID id.RoomID, tag event.RoomTag) (err error) {
|
||||
urlPath := cli.BuildClientURL("v3", "user", cli.UserID, "rooms", roomID, "tags", tag)
|
||||
_, err = cli.MakeRequest(ctx, http.MethodDelete, urlPath, nil, nil)
|
||||
return
|
||||
|
|
|
|||
1
vendor/maunium.net/go/mautrix/crypto/account.go
generated
vendored
1
vendor/maunium.net/go/mautrix/crypto/account.go
generated
vendored
|
|
@ -81,6 +81,5 @@ func (account *OlmAccount) getOneTimeKeys(userID id.UserID, deviceID id.DeviceID
|
|||
key.IsSigned = true
|
||||
oneTimeKeys[id.NewKeyID(id.KeyAlgorithmSignedCurve25519, keyID)] = key
|
||||
}
|
||||
account.Internal.MarkKeysAsPublished()
|
||||
return oneTimeKeys
|
||||
}
|
||||
|
|
|
|||
22
vendor/maunium.net/go/mautrix/crypto/attachment/attachments.go
generated
vendored
22
vendor/maunium.net/go/mautrix/crypto/attachment/attachments.go
generated
vendored
|
|
@ -12,6 +12,7 @@ import (
|
|||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
|
||||
|
|
@ -136,6 +137,27 @@ type encryptingReader struct {
|
|||
isDecrypting bool
|
||||
}
|
||||
|
||||
func (r *encryptingReader) Seek(offset int64, whence int) (int64, error) {
|
||||
if r.closed {
|
||||
return 0, ReaderClosed
|
||||
}
|
||||
if offset != 0 || whence != io.SeekStart {
|
||||
return 0, fmt.Errorf("attachments.EncryptStream: only seeking to the beginning is supported")
|
||||
}
|
||||
seeker, ok := r.source.(io.ReadSeeker)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("attachments.EncryptStream: source reader (%T) is not an io.ReadSeeker", r.source)
|
||||
}
|
||||
n, err := seeker.Seek(offset, whence)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
block, _ := aes.NewCipher(r.file.decoded.key[:])
|
||||
r.stream = cipher.NewCTR(block, r.file.decoded.iv[:])
|
||||
r.hash.Reset()
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (r *encryptingReader) Read(dst []byte) (n int, err error) {
|
||||
if r.closed {
|
||||
return 0, ReaderClosed
|
||||
|
|
|
|||
10
vendor/maunium.net/go/mautrix/crypto/cross_sign_key.go
generated
vendored
10
vendor/maunium.net/go/mautrix/crypto/cross_sign_key.go
generated
vendored
|
|
@ -142,6 +142,16 @@ func (mach *OlmMachine) PublishCrossSigningKeys(ctx context.Context, keys *Cross
|
|||
return err
|
||||
}
|
||||
|
||||
if err := mach.CryptoStore.PutSignature(ctx, userID, keys.MasterKey.PublicKey(), userID, mach.account.SigningKey(), masterSig); err != nil {
|
||||
return fmt.Errorf("error storing signature of master key by device signing key in crypto store: %w", err)
|
||||
}
|
||||
if err := mach.CryptoStore.PutSignature(ctx, userID, keys.SelfSigningKey.PublicKey(), userID, keys.MasterKey.PublicKey(), selfSig); err != nil {
|
||||
return fmt.Errorf("error storing signature of self-signing key by master key in crypto store: %w", err)
|
||||
}
|
||||
if err := mach.CryptoStore.PutSignature(ctx, userID, keys.UserSigningKey.PublicKey(), userID, keys.MasterKey.PublicKey(), userSig); err != nil {
|
||||
return fmt.Errorf("error storing signature of user-signing key by master key in crypto store: %w", err)
|
||||
}
|
||||
|
||||
mach.CrossSigningKeys = keys
|
||||
mach.crossSigningPubkeys = keys.PublicKeys()
|
||||
|
||||
|
|
|
|||
25
vendor/maunium.net/go/mautrix/crypto/cross_sign_signing.go
generated
vendored
25
vendor/maunium.net/go/mautrix/crypto/cross_sign_signing.go
generated
vendored
|
|
@ -19,15 +19,15 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrCrossSigningKeysNotCached = errors.New("cross-signing private keys not in cache")
|
||||
ErrUserSigningKeyNotCached = errors.New("user-signing private key not in cache")
|
||||
ErrSelfSigningKeyNotCached = errors.New("self-signing private key not in cache")
|
||||
ErrSignatureUploadFail = errors.New("server-side failure uploading signatures")
|
||||
ErrCantSignOwnMasterKey = errors.New("signing your own master key is not allowed")
|
||||
ErrCantSignOtherDevice = errors.New("signing other users' devices is not allowed")
|
||||
ErrUserNotInQueryResponse = errors.New("could not find user in query keys response")
|
||||
ErrDeviceNotInQueryResponse = errors.New("could not find device in query keys response")
|
||||
ErrOlmAccountNotLoaded = errors.New("olm account has not been loaded")
|
||||
ErrCrossSigningPubkeysNotCached = errors.New("cross-signing public keys not in cache")
|
||||
ErrUserSigningKeyNotCached = errors.New("user-signing private key not in cache")
|
||||
ErrSelfSigningKeyNotCached = errors.New("self-signing private key not in cache")
|
||||
ErrSignatureUploadFail = errors.New("server-side failure uploading signatures")
|
||||
ErrCantSignOwnMasterKey = errors.New("signing your own master key is not allowed")
|
||||
ErrCantSignOtherDevice = errors.New("signing other users' devices is not allowed")
|
||||
ErrUserNotInQueryResponse = errors.New("could not find user in query keys response")
|
||||
ErrDeviceNotInQueryResponse = errors.New("could not find device in query keys response")
|
||||
ErrOlmAccountNotLoaded = errors.New("olm account has not been loaded")
|
||||
|
||||
ErrCrossSigningMasterKeyNotFound = errors.New("cross-signing master key not found")
|
||||
ErrMasterKeyMACNotFound = errors.New("found cross-signing master key, but didn't find corresponding MAC in verification request")
|
||||
|
|
@ -69,15 +69,16 @@ func (mach *OlmMachine) SignUser(ctx context.Context, userID id.UserID, masterKe
|
|||
|
||||
// SignOwnMasterKey uses the current account for signing the current user's master key and uploads the signature.
|
||||
func (mach *OlmMachine) SignOwnMasterKey(ctx context.Context) error {
|
||||
if mach.CrossSigningKeys == nil {
|
||||
return ErrCrossSigningKeysNotCached
|
||||
crossSigningPubkeys := mach.GetOwnCrossSigningPublicKeys(ctx)
|
||||
if crossSigningPubkeys == nil {
|
||||
return ErrCrossSigningPubkeysNotCached
|
||||
} else if mach.account == nil {
|
||||
return ErrOlmAccountNotLoaded
|
||||
}
|
||||
|
||||
userID := mach.Client.UserID
|
||||
deviceID := mach.Client.DeviceID
|
||||
masterKey := mach.CrossSigningKeys.MasterKey.PublicKey()
|
||||
masterKey := crossSigningPubkeys.MasterKey
|
||||
|
||||
masterKeyObj := mautrix.ReqKeysSignatures{
|
||||
UserID: userID,
|
||||
|
|
|
|||
4
vendor/maunium.net/go/mautrix/crypto/cross_sign_store.go
generated
vendored
4
vendor/maunium.net/go/mautrix/crypto/cross_sign_store.go
generated
vendored
|
|
@ -10,6 +10,8 @@ package crypto
|
|||
import (
|
||||
"context"
|
||||
|
||||
"go.mau.fi/util/exzerolog"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto/signatures"
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
|
@ -47,7 +49,7 @@ func (mach *OlmMachine) storeCrossSigningKeys(ctx context.Context, crossSigningK
|
|||
}
|
||||
|
||||
for _, key := range userKeys.Keys {
|
||||
log := log.With().Str("key", key.String()).Strs("usages", strishArray(userKeys.Usage)).Logger()
|
||||
log := log.With().Str("key", key.String()).Array("usages", exzerolog.ArrayOfStrs(userKeys.Usage)).Logger()
|
||||
for _, usage := range userKeys.Usage {
|
||||
log.Debug().Str("usage", string(usage)).Msg("Storing cross-signing key")
|
||||
if err = mach.CryptoStore.PutCrossSigningKey(ctx, userID, usage, key); err != nil {
|
||||
|
|
|
|||
66
vendor/maunium.net/go/mautrix/crypto/decryptmegolm.go
generated
vendored
66
vendor/maunium.net/go/mautrix/crypto/decryptmegolm.go
generated
vendored
|
|
@ -14,6 +14,9 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
"go.mau.fi/util/exgjson"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/olm"
|
||||
"maunium.net/go/mautrix/event"
|
||||
|
|
@ -36,6 +39,11 @@ type megolmEvent struct {
|
|||
Content event.Content `json:"content"`
|
||||
}
|
||||
|
||||
var (
|
||||
relatesToContentPath = exgjson.Path("m.relates_to")
|
||||
relatesToTopLevelPath = exgjson.Path("content", "m.relates_to")
|
||||
)
|
||||
|
||||
// DecryptMegolmEvent decrypts an m.room.encrypted event where the algorithm is m.megolm.v1.aes-sha2
|
||||
func (mach *OlmMachine) DecryptMegolmEvent(ctx context.Context, evt *event.Event) (*event.Event, error) {
|
||||
content, ok := evt.Content.Parsed.(*event.EncryptedEventContent)
|
||||
|
|
@ -90,14 +98,20 @@ func (mach *OlmMachine) DecryptMegolmEvent(ctx context.Context, evt *event.Event
|
|||
} else if device.SigningKey != sess.SigningKey || device.IdentityKey != sess.SenderKey {
|
||||
return nil, DeviceKeyMismatch
|
||||
} else {
|
||||
trustLevel = mach.ResolveTrust(device)
|
||||
trustLevel, err = mach.ResolveTrustContext(ctx, device)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
forwardedKeys = true
|
||||
lastChainItem := sess.ForwardingChains[len(sess.ForwardingChains)-1]
|
||||
device, _ = mach.CryptoStore.FindDeviceByKey(ctx, evt.Sender, id.IdentityKey(lastChainItem))
|
||||
if device != nil {
|
||||
trustLevel = mach.ResolveTrust(device)
|
||||
trustLevel, err = mach.ResolveTrustContext(ctx, device)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
log.Debug().
|
||||
Str("forward_last_sender_key", lastChainItem).
|
||||
|
|
@ -107,6 +121,26 @@ func (mach *OlmMachine) DecryptMegolmEvent(ctx context.Context, evt *event.Event
|
|||
}
|
||||
}
|
||||
|
||||
if content.RelatesTo != nil {
|
||||
relation := gjson.GetBytes(evt.Content.VeryRaw, relatesToContentPath)
|
||||
if relation.Exists() && !gjson.GetBytes(plaintext, relatesToTopLevelPath).IsObject() {
|
||||
var raw []byte
|
||||
if relation.Index > 0 {
|
||||
raw = evt.Content.VeryRaw[relation.Index : relation.Index+len(relation.Raw)]
|
||||
} else {
|
||||
raw = []byte(relation.Raw)
|
||||
}
|
||||
updatedPlaintext, err := sjson.SetRawBytes(plaintext, relatesToTopLevelPath, raw)
|
||||
if err != nil {
|
||||
log.Warn().Msg("Failed to copy m.relates_to to decrypted payload")
|
||||
} else if updatedPlaintext != nil {
|
||||
plaintext = updatedPlaintext
|
||||
}
|
||||
} else if !relation.Exists() {
|
||||
log.Warn().Msg("Failed to find m.relates_to in raw encrypted event even though it was present in parsed content")
|
||||
}
|
||||
}
|
||||
|
||||
megolmEvt := &megolmEvent{}
|
||||
err = json.Unmarshal(plaintext, &megolmEvt)
|
||||
if err != nil {
|
||||
|
|
@ -124,19 +158,6 @@ func (mach *OlmMachine) DecryptMegolmEvent(ctx context.Context, evt *event.Event
|
|||
return nil, fmt.Errorf("failed to parse content of megolm payload event: %w", err)
|
||||
}
|
||||
}
|
||||
if content.RelatesTo != nil {
|
||||
relatable, ok := megolmEvt.Content.Parsed.(event.Relatable)
|
||||
if ok {
|
||||
if relatable.OptionalGetRelatesTo() == nil {
|
||||
relatable.SetRelatesTo(content.RelatesTo)
|
||||
} else {
|
||||
log.Trace().Msg("Not overriding relation data as encrypted payload already has it")
|
||||
}
|
||||
}
|
||||
if _, hasRelation := megolmEvt.Content.Raw["m.relates_to"]; !hasRelation {
|
||||
megolmEvt.Content.Raw["m.relates_to"] = evt.Content.Raw["m.relates_to"]
|
||||
}
|
||||
}
|
||||
log.Debug().Msg("Event decrypted successfully")
|
||||
megolmEvt.Type.Class = evt.Type.Class
|
||||
return &event.Event{
|
||||
|
|
@ -170,7 +191,7 @@ const missedIndexCutoff = 10
|
|||
|
||||
func (mach *OlmMachine) checkUndecryptableMessageIndexDuplication(ctx context.Context, sess *InboundGroupSession, evt *event.Event, content *event.EncryptedEventContent) (uint, error) {
|
||||
log := *zerolog.Ctx(ctx)
|
||||
messageIndex, decodeErr := parseMessageIndex(content.MegolmCiphertext)
|
||||
messageIndex, decodeErr := ParseMegolmMessageIndex(content.MegolmCiphertext)
|
||||
if decodeErr != nil {
|
||||
log.Warn().Err(decodeErr).Msg("Failed to parse message index to check if it's a duplicate for message that failed to decrypt")
|
||||
return 0, fmt.Errorf("%w (also failed to parse message index)", olm.UnknownMessageIndex)
|
||||
|
|
@ -192,7 +213,7 @@ func (mach *OlmMachine) actuallyDecryptMegolmEvent(ctx context.Context, evt *eve
|
|||
mach.megolmDecryptLock.Lock()
|
||||
defer mach.megolmDecryptLock.Unlock()
|
||||
|
||||
sess, err := mach.CryptoStore.GetGroupSession(ctx, encryptionRoomID, content.SenderKey, content.SessionID)
|
||||
sess, err := mach.CryptoStore.GetGroupSession(ctx, encryptionRoomID, content.SessionID)
|
||||
if err != nil {
|
||||
return nil, nil, 0, fmt.Errorf("failed to get group session: %w", err)
|
||||
} else if sess == nil {
|
||||
|
|
@ -213,6 +234,11 @@ func (mach *OlmMachine) actuallyDecryptMegolmEvent(ctx context.Context, evt *eve
|
|||
return sess, nil, messageIndex, fmt.Errorf("%w %d", DuplicateMessageIndex, messageIndex)
|
||||
}
|
||||
|
||||
// Normal clients don't care about tracking the ratchet state, so let them bypass the rest of the function
|
||||
if mach.DisableRatchetTracking {
|
||||
return sess, plaintext, messageIndex, nil
|
||||
}
|
||||
|
||||
expectedMessageIndex := sess.RatchetSafety.NextIndex
|
||||
didModify := false
|
||||
switch {
|
||||
|
|
@ -254,7 +280,7 @@ func (mach *OlmMachine) actuallyDecryptMegolmEvent(ctx context.Context, evt *eve
|
|||
Int("max_messages", sess.MaxMessages).
|
||||
Logger()
|
||||
if sess.MaxMessages > 0 && int(ratchetTargetIndex) >= sess.MaxMessages && len(sess.RatchetSafety.MissedIndices) == 0 && mach.DeleteFullyUsedKeysOnDecrypt {
|
||||
err = mach.CryptoStore.RedactGroupSession(ctx, sess.RoomID, sess.SenderKey, sess.ID(), "maximum messages reached")
|
||||
err = mach.CryptoStore.RedactGroupSession(ctx, sess.RoomID, sess.ID(), "maximum messages reached")
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to delete fully used session")
|
||||
return sess, plaintext, messageIndex, RatchetError
|
||||
|
|
@ -265,14 +291,14 @@ func (mach *OlmMachine) actuallyDecryptMegolmEvent(ctx context.Context, evt *eve
|
|||
if err = sess.RatchetTo(ratchetTargetIndex); err != nil {
|
||||
log.Err(err).Msg("Failed to ratchet session")
|
||||
return sess, plaintext, messageIndex, RatchetError
|
||||
} else if err = mach.CryptoStore.PutGroupSession(ctx, sess.RoomID, sess.SenderKey, sess.ID(), sess); err != nil {
|
||||
} else if err = mach.CryptoStore.PutGroupSession(ctx, sess); err != nil {
|
||||
log.Err(err).Msg("Failed to store ratcheted session")
|
||||
return sess, plaintext, messageIndex, RatchetError
|
||||
} else {
|
||||
log.Info().Msg("Ratcheted session forward")
|
||||
}
|
||||
} else if didModify {
|
||||
if err = mach.CryptoStore.PutGroupSession(ctx, sess.RoomID, sess.SenderKey, sess.ID(), sess); err != nil {
|
||||
if err = mach.CryptoStore.PutGroupSession(ctx, sess); err != nil {
|
||||
log.Err(err).Msg("Failed to store updated ratchet safety data")
|
||||
return sess, plaintext, messageIndex, RatchetError
|
||||
} else {
|
||||
|
|
|
|||
9
vendor/maunium.net/go/mautrix/crypto/devicelist.go
generated
vendored
9
vendor/maunium.net/go/mautrix/crypto/devicelist.go
generated
vendored
|
|
@ -12,6 +12,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"go.mau.fi/util/exzerolog"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto/signatures"
|
||||
|
|
@ -93,6 +94,10 @@ func (mach *OlmMachine) storeDeviceSelfSignatures(ctx context.Context, userID id
|
|||
}
|
||||
}
|
||||
|
||||
// FetchKeys fetches the devices of a list of other users. If includeUntracked
|
||||
// is set to false, then the users are filtered to to only include user IDs
|
||||
// whose device lists have been stored with the PutDevices function on the
|
||||
// [Store]. See the FilterTrackedUsers function on [Store] for details.
|
||||
func (mach *OlmMachine) FetchKeys(ctx context.Context, users []id.UserID, includeUntracked bool) (data map[id.UserID]map[id.DeviceID]*id.Device, err error) {
|
||||
req := &mautrix.ReqQueryKeys{
|
||||
DeviceKeys: mautrix.DeviceKeysRequest{},
|
||||
|
|
@ -111,7 +116,7 @@ func (mach *OlmMachine) FetchKeys(ctx context.Context, users []id.UserID, includ
|
|||
for _, userID := range users {
|
||||
req.DeviceKeys[userID] = mautrix.DeviceIDList{}
|
||||
}
|
||||
log.Debug().Strs("users", strishArray(users)).Msg("Querying keys for users")
|
||||
log.Debug().Array("users", exzerolog.ArrayOfStrs(users)).Msg("Querying keys for users")
|
||||
resp, err := mach.Client.QueryKeys(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to query keys: %w", err)
|
||||
|
|
@ -177,7 +182,7 @@ func (mach *OlmMachine) FetchKeys(ctx context.Context, users []id.UserID, includ
|
|||
log.Err(err).Msg("Failed to redact megolm sessions from deleted device")
|
||||
} else {
|
||||
log.Info().
|
||||
Strs("session_ids", stringifyArray(sessionIDs)).
|
||||
Array("session_ids", exzerolog.ArrayOfStrs(sessionIDs)).
|
||||
Msg("Redacted megolm sessions from deleted device")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
64
vendor/maunium.net/go/mautrix/crypto/encryptmegolm.go
generated
vendored
64
vendor/maunium.net/go/mautrix/crypto/encryptmegolm.go
generated
vendored
|
|
@ -15,6 +15,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"go.mau.fi/util/exzerolog"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
|
|
@ -61,7 +62,7 @@ func IsShareError(err error) bool {
|
|||
return err == SessionExpired || err == SessionNotShared || err == NoGroupSession
|
||||
}
|
||||
|
||||
func parseMessageIndex(ciphertext []byte) (uint, error) {
|
||||
func ParseMegolmMessageIndex(ciphertext []byte) (uint, error) {
|
||||
decoded := make([]byte, base64.RawStdEncoding.DecodedLen(len(ciphertext)))
|
||||
var err error
|
||||
_, err = base64.RawStdEncoding.Decode(decoded, ciphertext)
|
||||
|
|
@ -109,7 +110,7 @@ func (mach *OlmMachine) EncryptMegolmEvent(ctx context.Context, roomID id.RoomID
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
idx, err := parseMessageIndex(ciphertext)
|
||||
idx, err := ParseMegolmMessageIndex(ciphertext)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to get megolm message index of encrypted event")
|
||||
} else {
|
||||
|
|
@ -136,19 +137,23 @@ func (mach *OlmMachine) EncryptMegolmEvent(ctx context.Context, roomID id.RoomID
|
|||
return encrypted, nil
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) newOutboundGroupSession(ctx context.Context, roomID id.RoomID) *OutboundGroupSession {
|
||||
func (mach *OlmMachine) newOutboundGroupSession(ctx context.Context, roomID id.RoomID) (*OutboundGroupSession, error) {
|
||||
encryptionEvent, err := mach.StateStore.GetEncryptionEvent(ctx, roomID)
|
||||
if err != nil {
|
||||
mach.machOrContextLog(ctx).Err(err).
|
||||
Stringer("room_id", roomID).
|
||||
Msg("Failed to get encryption event in room")
|
||||
return nil, fmt.Errorf("failed to get encryption event in room %s: %w", roomID, err)
|
||||
}
|
||||
session := NewOutboundGroupSession(roomID, encryptionEvent)
|
||||
if !mach.DontStoreOutboundKeys {
|
||||
signingKey, idKey := mach.account.Keys()
|
||||
mach.createGroupSession(ctx, idKey, signingKey, roomID, session.ID(), session.Internal.Key(), session.MaxAge, session.MaxMessages, false)
|
||||
err := mach.createGroupSession(ctx, idKey, signingKey, roomID, session.ID(), session.Internal.Key(), session.MaxAge, session.MaxMessages, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return session
|
||||
return session, err
|
||||
}
|
||||
|
||||
type deviceSessionWrapper struct {
|
||||
|
|
@ -156,14 +161,6 @@ type deviceSessionWrapper struct {
|
|||
identity *id.Device
|
||||
}
|
||||
|
||||
func strishArray[T ~string](arr []T) []string {
|
||||
out := make([]string, len(arr))
|
||||
for i, item := range arr {
|
||||
out[i] = string(item)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ShareGroupSession shares a group session for a specific room with all the devices of the given user list.
|
||||
//
|
||||
// For devices with TrustStateBlacklisted, a m.room_key.withheld event with code=m.blacklisted is sent.
|
||||
|
|
@ -183,27 +180,30 @@ func (mach *OlmMachine) ShareGroupSession(ctx context.Context, roomID id.RoomID,
|
|||
Logger()
|
||||
ctx = log.WithContext(ctx)
|
||||
if session == nil || session.Expired() {
|
||||
session = mach.newOutboundGroupSession(ctx, roomID)
|
||||
if session, err = mach.newOutboundGroupSession(ctx, roomID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
log = log.With().Str("session_id", session.ID().String()).Logger()
|
||||
ctx = log.WithContext(ctx)
|
||||
log.Debug().Strs("users", strishArray(users)).Msg("Sharing group session for room")
|
||||
log.Debug().Array("users", exzerolog.ArrayOfStrs(users)).Msg("Sharing group session for room")
|
||||
|
||||
withheldCount := 0
|
||||
toDeviceWithheld := &mautrix.ReqSendToDevice{Messages: make(map[id.UserID]map[id.DeviceID]*event.Content)}
|
||||
olmSessions := make(map[id.UserID]map[id.DeviceID]deviceSessionWrapper)
|
||||
missingSessions := make(map[id.UserID]map[id.DeviceID]*id.Device)
|
||||
missingUserSessions := make(map[id.DeviceID]*id.Device)
|
||||
var fetchKeys []id.UserID
|
||||
var fetchKeysForUsers []id.UserID
|
||||
|
||||
for _, userID := range users {
|
||||
log := log.With().Str("target_user_id", userID.String()).Logger()
|
||||
devices, err := mach.CryptoStore.GetDevices(ctx, userID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get devices of user")
|
||||
log.Err(err).Msg("Failed to get devices of user")
|
||||
return fmt.Errorf("failed to get devices of user %s: %w", userID, err)
|
||||
} else if devices == nil {
|
||||
log.Debug().Msg("GetDevices returned nil, will fetch keys and retry")
|
||||
fetchKeys = append(fetchKeys, userID)
|
||||
fetchKeysForUsers = append(fetchKeysForUsers, userID)
|
||||
} else if len(devices) == 0 {
|
||||
log.Trace().Msg("User has no devices, skipping")
|
||||
} else {
|
||||
|
|
@ -227,18 +227,19 @@ func (mach *OlmMachine) ShareGroupSession(ctx context.Context, roomID id.RoomID,
|
|||
}
|
||||
}
|
||||
|
||||
if len(fetchKeys) > 0 {
|
||||
log.Debug().Strs("users", strishArray(fetchKeys)).Msg("Fetching missing keys")
|
||||
if keys, err := mach.FetchKeys(ctx, fetchKeys, true); err != nil {
|
||||
log.Err(err).Strs("users", strishArray(fetchKeys)).Msg("Failed to fetch missing keys")
|
||||
} else if keys != nil {
|
||||
for userID, devices := range keys {
|
||||
log.Debug().
|
||||
Int("device_count", len(devices)).
|
||||
Str("target_user_id", userID.String()).
|
||||
Msg("Got device keys for user")
|
||||
missingSessions[userID] = devices
|
||||
}
|
||||
if len(fetchKeysForUsers) > 0 {
|
||||
log.Debug().Array("users", exzerolog.ArrayOfStrs(fetchKeysForUsers)).Msg("Fetching missing keys")
|
||||
keys, err := mach.FetchKeys(ctx, fetchKeysForUsers, true)
|
||||
if err != nil {
|
||||
log.Err(err).Array("users", exzerolog.ArrayOfStrs(fetchKeysForUsers)).Msg("Failed to fetch missing keys")
|
||||
return fmt.Errorf("failed to fetch missing keys: %w", err)
|
||||
}
|
||||
for userID, devices := range keys {
|
||||
log.Debug().
|
||||
Int("device_count", len(devices)).
|
||||
Str("target_user_id", userID.String()).
|
||||
Msg("Got device keys for user")
|
||||
missingSessions[userID] = devices
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +247,8 @@ func (mach *OlmMachine) ShareGroupSession(ctx context.Context, roomID id.RoomID,
|
|||
log.Debug().Msg("Creating missing olm sessions")
|
||||
err = mach.createOutboundSessions(ctx, missingSessions)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to create missing olm sessions")
|
||||
log.Err(err).Msg("Failed to create missing olm sessions")
|
||||
return fmt.Errorf("failed to create missing olm sessions: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
5
vendor/maunium.net/go/mautrix/crypto/goolm/crypto/ed25519.go
generated
vendored
5
vendor/maunium.net/go/mautrix/crypto/goolm/crypto/ed25519.go
generated
vendored
|
|
@ -1,7 +1,6 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
|
@ -118,7 +117,7 @@ type Ed25519PrivateKey ed25519.PrivateKey
|
|||
|
||||
// Equal compares the private key to the given private key.
|
||||
func (c Ed25519PrivateKey) Equal(x Ed25519PrivateKey) bool {
|
||||
return bytes.Equal(c, x)
|
||||
return ed25519.PrivateKey(c).Equal(ed25519.PrivateKey(x))
|
||||
}
|
||||
|
||||
// PubKey returns the public key derived from the private key.
|
||||
|
|
@ -137,7 +136,7 @@ type Ed25519PublicKey ed25519.PublicKey
|
|||
|
||||
// Equal compares the public key to the given public key.
|
||||
func (c Ed25519PublicKey) Equal(x Ed25519PublicKey) bool {
|
||||
return bytes.Equal(c, x)
|
||||
return ed25519.PublicKey(c).Equal(ed25519.PublicKey(x))
|
||||
}
|
||||
|
||||
// B64Encoded returns a base64 encoded string of the public key.
|
||||
|
|
|
|||
24
vendor/maunium.net/go/mautrix/crypto/keybackup.go
generated
vendored
24
vendor/maunium.net/go/mautrix/crypto/keybackup.go
generated
vendored
|
|
@ -54,6 +54,9 @@ func (mach *OlmMachine) GetAndVerifyLatestKeyBackupVersion(ctx context.Context)
|
|||
}
|
||||
|
||||
crossSigningPubkeys := mach.GetOwnCrossSigningPublicKeys(ctx)
|
||||
if crossSigningPubkeys == nil {
|
||||
return nil, ErrCrossSigningPubkeysNotCached
|
||||
}
|
||||
|
||||
signatureVerified := false
|
||||
for keyID := range userSignatures {
|
||||
|
|
@ -114,7 +117,7 @@ func (mach *OlmMachine) GetAndStoreKeyBackup(ctx context.Context, version id.Key
|
|||
continue
|
||||
}
|
||||
|
||||
err = mach.ImportRoomKeyFromBackup(ctx, version, roomID, sessionID, sessionData)
|
||||
_, err = mach.ImportRoomKeyFromBackup(ctx, version, roomID, sessionID, sessionData)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to import room key from backup")
|
||||
failedCount++
|
||||
|
|
@ -132,23 +135,23 @@ func (mach *OlmMachine) GetAndStoreKeyBackup(ctx context.Context, version id.Key
|
|||
return nil
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) ImportRoomKeyFromBackup(ctx context.Context, version id.KeyBackupVersion, roomID id.RoomID, sessionID id.SessionID, keyBackupData *backup.MegolmSessionData) error {
|
||||
func (mach *OlmMachine) ImportRoomKeyFromBackup(ctx context.Context, version id.KeyBackupVersion, roomID id.RoomID, sessionID id.SessionID, keyBackupData *backup.MegolmSessionData) (*InboundGroupSession, error) {
|
||||
log := zerolog.Ctx(ctx).With().
|
||||
Str("room_id", roomID.String()).
|
||||
Str("session_id", sessionID.String()).
|
||||
Logger()
|
||||
if keyBackupData.Algorithm != id.AlgorithmMegolmV1 {
|
||||
return fmt.Errorf("ignoring room key in backup with weird algorithm %s", keyBackupData.Algorithm)
|
||||
return nil, fmt.Errorf("ignoring room key in backup with weird algorithm %s", keyBackupData.Algorithm)
|
||||
}
|
||||
|
||||
igsInternal, err := olm.InboundGroupSessionImport([]byte(keyBackupData.SessionKey))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to import inbound group session: %w", err)
|
||||
return nil, fmt.Errorf("failed to import inbound group session: %w", err)
|
||||
} else if igsInternal.ID() != sessionID {
|
||||
log.Warn().
|
||||
Stringer("actual_session_id", igsInternal.ID()).
|
||||
Msg("Mismatched session ID while creating inbound group session from key backup")
|
||||
return fmt.Errorf("mismatched session ID while creating inbound group session from key backup")
|
||||
return nil, fmt.Errorf("mismatched session ID while creating inbound group session from key backup")
|
||||
}
|
||||
|
||||
var maxAge time.Duration
|
||||
|
|
@ -160,7 +163,8 @@ func (mach *OlmMachine) ImportRoomKeyFromBackup(ctx context.Context, version id.
|
|||
maxMessages = config.RotationPeriodMessages
|
||||
}
|
||||
|
||||
if firstKnownIndex := igsInternal.FirstKnownIndex(); firstKnownIndex > 0 {
|
||||
firstKnownIndex := igsInternal.FirstKnownIndex()
|
||||
if firstKnownIndex > 0 {
|
||||
log.Warn().Uint32("first_known_index", firstKnownIndex).Msg("Importing partial session")
|
||||
}
|
||||
|
||||
|
|
@ -177,10 +181,10 @@ func (mach *OlmMachine) ImportRoomKeyFromBackup(ctx context.Context, version id.
|
|||
MaxMessages: maxMessages,
|
||||
KeyBackupVersion: version,
|
||||
}
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, roomID, keyBackupData.SenderKey, sessionID, igs)
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, igs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to store new inbound group session: %w", err)
|
||||
return nil, fmt.Errorf("failed to store new inbound group session: %w", err)
|
||||
}
|
||||
mach.markSessionReceived(ctx, sessionID)
|
||||
return nil
|
||||
mach.markSessionReceived(ctx, roomID, sessionID, firstKnownIndex)
|
||||
return igs, nil
|
||||
}
|
||||
|
|
|
|||
24
vendor/maunium.net/go/mautrix/crypto/keyexport.go
generated
vendored
24
vendor/maunium.net/go/mautrix/crypto/keyexport.go
generated
vendored
|
|
@ -11,7 +11,6 @@ import (
|
|||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
|
|
@ -20,9 +19,9 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
|
||||
"go.mau.fi/util/random"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/olm"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
|
|
@ -66,25 +65,15 @@ func computeKey(passphrase string, salt []byte, rounds int) (encryptionKey, hash
|
|||
}
|
||||
|
||||
func makeExportIV() []byte {
|
||||
iv := make([]byte, 16)
|
||||
_, err := rand.Read(iv)
|
||||
if err != nil {
|
||||
panic(olm.NotEnoughGoRandom)
|
||||
}
|
||||
iv := random.Bytes(16)
|
||||
// Set bit 63 to zero
|
||||
iv[7] &= 0b11111110
|
||||
return iv
|
||||
}
|
||||
|
||||
func makeExportKeys(passphrase string) (encryptionKey, hashKey, salt, iv []byte) {
|
||||
salt = make([]byte, 16)
|
||||
_, err := rand.Read(salt)
|
||||
if err != nil {
|
||||
panic(olm.NotEnoughGoRandom)
|
||||
}
|
||||
|
||||
salt = random.Bytes(16)
|
||||
encryptionKey, hashKey = computeKey(passphrase, salt, defaultPassphraseRounds)
|
||||
|
||||
iv = makeExportIV()
|
||||
return
|
||||
}
|
||||
|
|
@ -117,13 +106,6 @@ func exportSessionsJSON(sessions []*InboundGroupSession) ([]byte, error) {
|
|||
return json.Marshal(exportedSessions)
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a > b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func formatKeyExportData(data []byte) []byte {
|
||||
base64Data := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
|
||||
base64.StdEncoding.Encode(base64Data, data)
|
||||
|
|
|
|||
9
vendor/maunium.net/go/mautrix/crypto/keyimport.go
generated
vendored
9
vendor/maunium.net/go/mautrix/crypto/keyimport.go
generated
vendored
|
|
@ -113,16 +113,17 @@ func (mach *OlmMachine) importExportedRoomKey(ctx context.Context, session Expor
|
|||
|
||||
ReceivedAt: time.Now().UTC(),
|
||||
}
|
||||
existingIGS, _ := mach.CryptoStore.GetGroupSession(ctx, igs.RoomID, igs.SenderKey, igs.ID())
|
||||
if existingIGS != nil && existingIGS.Internal.FirstKnownIndex() <= igs.Internal.FirstKnownIndex() {
|
||||
existingIGS, _ := mach.CryptoStore.GetGroupSession(ctx, igs.RoomID, igs.ID())
|
||||
firstKnownIndex := igs.Internal.FirstKnownIndex()
|
||||
if existingIGS != nil && existingIGS.Internal.FirstKnownIndex() <= firstKnownIndex {
|
||||
// We already have an equivalent or better session in the store, so don't override it.
|
||||
return false, nil
|
||||
}
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, igs.RoomID, igs.SenderKey, igs.ID(), igs)
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, igs)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to store imported session: %w", err)
|
||||
}
|
||||
mach.markSessionReceived(ctx, igs.ID())
|
||||
mach.markSessionReceived(ctx, session.RoomID, igs.ID(), firstKnownIndex)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
15
vendor/maunium.net/go/mautrix/crypto/keysharing.go
generated
vendored
15
vendor/maunium.net/go/mautrix/crypto/keysharing.go
generated
vendored
|
|
@ -168,7 +168,8 @@ func (mach *OlmMachine) importForwardedRoomKey(ctx context.Context, evt *Decrypt
|
|||
if content.MaxMessages != 0 {
|
||||
maxMessages = content.MaxMessages
|
||||
}
|
||||
if firstKnownIndex := igsInternal.FirstKnownIndex(); firstKnownIndex > 0 {
|
||||
firstKnownIndex := igsInternal.FirstKnownIndex()
|
||||
if firstKnownIndex > 0 {
|
||||
log.Warn().Uint32("first_known_index", firstKnownIndex).Msg("Importing partial session")
|
||||
}
|
||||
igs := &InboundGroupSession{
|
||||
|
|
@ -184,17 +185,17 @@ func (mach *OlmMachine) importForwardedRoomKey(ctx context.Context, evt *Decrypt
|
|||
MaxMessages: maxMessages,
|
||||
IsScheduled: content.IsScheduled,
|
||||
}
|
||||
existingIGS, _ := mach.CryptoStore.GetGroupSession(ctx, igs.RoomID, igs.SenderKey, igs.ID())
|
||||
existingIGS, _ := mach.CryptoStore.GetGroupSession(ctx, igs.RoomID, igs.ID())
|
||||
if existingIGS != nil && existingIGS.Internal.FirstKnownIndex() <= igs.Internal.FirstKnownIndex() {
|
||||
// We already have an equivalent or better session in the store, so don't override it.
|
||||
return false
|
||||
}
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, content.RoomID, content.SenderKey, content.SessionID, igs)
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, igs)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to store new inbound group session")
|
||||
return false
|
||||
}
|
||||
mach.markSessionReceived(ctx, content.SessionID)
|
||||
mach.markSessionReceived(ctx, content.RoomID, content.SessionID, firstKnownIndex)
|
||||
log.Debug().Msg("Received forwarded inbound group session")
|
||||
return true
|
||||
}
|
||||
|
|
@ -308,7 +309,7 @@ func (mach *OlmMachine) HandleRoomKeyRequest(ctx context.Context, sender id.User
|
|||
return
|
||||
}
|
||||
|
||||
igs, err := mach.CryptoStore.GetGroupSession(ctx, content.Body.RoomID, content.Body.SenderKey, content.Body.SessionID)
|
||||
igs, err := mach.CryptoStore.GetGroupSession(ctx, content.Body.RoomID, content.Body.SessionID)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrGroupSessionWithheld) {
|
||||
log.Debug().Err(err).Msg("Requested group session not available")
|
||||
|
|
@ -365,7 +366,7 @@ func (mach *OlmMachine) HandleBeeperRoomKeyAck(ctx context.Context, sender id.Us
|
|||
Int("first_message_index", content.FirstMessageIndex).
|
||||
Logger()
|
||||
|
||||
sess, err := mach.CryptoStore.GetGroupSession(ctx, content.RoomID, "", content.SessionID)
|
||||
sess, err := mach.CryptoStore.GetGroupSession(ctx, content.RoomID, content.SessionID)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrGroupSessionWithheld) {
|
||||
log.Debug().Err(err).Msg("Acked group session was already redacted")
|
||||
|
|
@ -385,7 +386,7 @@ func (mach *OlmMachine) HandleBeeperRoomKeyAck(ctx context.Context, sender id.Us
|
|||
isInbound := sess.SenderKey == mach.OwnIdentity().IdentityKey
|
||||
if isInbound && mach.DeleteOutboundKeysOnAck && content.FirstMessageIndex == 0 {
|
||||
log.Debug().Msg("Redacting inbound copy of outbound group session after ack")
|
||||
err = mach.CryptoStore.RedactGroupSession(ctx, content.RoomID, sess.SenderKey, content.SessionID, "outbound session acked")
|
||||
err = mach.CryptoStore.RedactGroupSession(ctx, content.RoomID, content.SessionID, "outbound session acked")
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to redact group session")
|
||||
}
|
||||
|
|
|
|||
56
vendor/maunium.net/go/mautrix/crypto/machine.go
generated
vendored
56
vendor/maunium.net/go/mautrix/crypto/machine.go
generated
vendored
|
|
@ -15,11 +15,12 @@ import (
|
|||
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/ssss"
|
||||
"maunium.net/go/mautrix/id"
|
||||
"go.mau.fi/util/exzerolog"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto/ssss"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// OlmMachine is the main struct for handling Matrix end-to-end encryption.
|
||||
|
|
@ -53,7 +54,7 @@ type OlmMachine struct {
|
|||
keyWaitersLock sync.Mutex
|
||||
|
||||
// Optional callback which is called when we save a session to store
|
||||
SessionReceived func(context.Context, id.SessionID)
|
||||
SessionReceived func(context.Context, id.RoomID, id.SessionID, uint32)
|
||||
|
||||
devicesToUnwedge map[id.IdentityKey]bool
|
||||
devicesToUnwedgeLock sync.Mutex
|
||||
|
|
@ -78,6 +79,7 @@ type OlmMachine struct {
|
|||
RatchetKeysOnDecrypt bool
|
||||
DeleteFullyUsedKeysOnDecrypt bool
|
||||
DeleteKeysOnDeviceDelete bool
|
||||
DisableRatchetTracking bool
|
||||
|
||||
DisableDeviceChangeKeyRotation bool
|
||||
|
||||
|
|
@ -505,25 +507,24 @@ func (mach *OlmMachine) SendEncryptedToDevice(ctx context.Context, device *id.De
|
|||
return err
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) createGroupSession(ctx context.Context, senderKey id.SenderKey, signingKey id.Ed25519, roomID id.RoomID, sessionID id.SessionID, sessionKey string, maxAge time.Duration, maxMessages int, isScheduled bool) {
|
||||
func (mach *OlmMachine) createGroupSession(ctx context.Context, senderKey id.SenderKey, signingKey id.Ed25519, roomID id.RoomID, sessionID id.SessionID, sessionKey string, maxAge time.Duration, maxMessages int, isScheduled bool) error {
|
||||
log := zerolog.Ctx(ctx)
|
||||
igs, err := NewInboundGroupSession(senderKey, signingKey, roomID, sessionKey, maxAge, maxMessages, isScheduled)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to create inbound group session")
|
||||
return
|
||||
return fmt.Errorf("failed to create inbound group session: %w", err)
|
||||
} else if igs.ID() != sessionID {
|
||||
log.Warn().
|
||||
Str("expected_session_id", sessionID.String()).
|
||||
Str("actual_session_id", igs.ID().String()).
|
||||
Msg("Mismatched session ID while creating inbound group session")
|
||||
return
|
||||
return fmt.Errorf("mismatched session ID while creating inbound group session")
|
||||
}
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, roomID, senderKey, sessionID, igs)
|
||||
err = mach.CryptoStore.PutGroupSession(ctx, igs)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("session_id", sessionID.String()).Msg("Failed to store new inbound group session")
|
||||
return
|
||||
log.Err(err).Str("session_id", sessionID.String()).Msg("Failed to store new inbound group session")
|
||||
return fmt.Errorf("failed to store new inbound group session: %w", err)
|
||||
}
|
||||
mach.markSessionReceived(ctx, sessionID)
|
||||
mach.markSessionReceived(ctx, roomID, sessionID, igs.Internal.FirstKnownIndex())
|
||||
log.Debug().
|
||||
Str("session_id", sessionID.String()).
|
||||
Str("sender_key", senderKey.String()).
|
||||
|
|
@ -531,11 +532,12 @@ func (mach *OlmMachine) createGroupSession(ctx context.Context, senderKey id.Sen
|
|||
Int("max_messages", maxMessages).
|
||||
Bool("is_scheduled", isScheduled).
|
||||
Msg("Received inbound group session")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) markSessionReceived(ctx context.Context, id id.SessionID) {
|
||||
func (mach *OlmMachine) markSessionReceived(ctx context.Context, roomID id.RoomID, id id.SessionID, firstKnownIndex uint32) {
|
||||
if mach.SessionReceived != nil {
|
||||
mach.SessionReceived(ctx, id)
|
||||
mach.SessionReceived(ctx, roomID, id, firstKnownIndex)
|
||||
}
|
||||
|
||||
mach.keyWaitersLock.Lock()
|
||||
|
|
@ -557,7 +559,7 @@ func (mach *OlmMachine) WaitForSession(ctx context.Context, roomID id.RoomID, se
|
|||
}
|
||||
mach.keyWaitersLock.Unlock()
|
||||
// Handle race conditions where a session appears between the failed decryption and WaitForSession call.
|
||||
sess, err := mach.CryptoStore.GetGroupSession(ctx, roomID, senderKey, sessionID)
|
||||
sess, err := mach.CryptoStore.GetGroupSession(ctx, roomID, sessionID)
|
||||
if sess != nil || errors.Is(err, ErrGroupSessionWithheld) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -565,7 +567,7 @@ func (mach *OlmMachine) WaitForSession(ctx context.Context, roomID id.RoomID, se
|
|||
case <-ch:
|
||||
return true
|
||||
case <-time.After(timeout):
|
||||
sess, err = mach.CryptoStore.GetGroupSession(ctx, roomID, senderKey, sessionID)
|
||||
sess, err = mach.CryptoStore.GetGroupSession(ctx, roomID, sessionID)
|
||||
// Check if the session somehow appeared in the store without telling us
|
||||
// We accept withheld sessions as received, as then the decryption attempt will show the error.
|
||||
return sess != nil || errors.Is(err, ErrGroupSessionWithheld)
|
||||
|
|
@ -574,14 +576,6 @@ func (mach *OlmMachine) WaitForSession(ctx context.Context, roomID id.RoomID, se
|
|||
}
|
||||
}
|
||||
|
||||
func stringifyArray[T ~string](arr []T) []string {
|
||||
strs := make([]string, len(arr))
|
||||
for i, v := range arr {
|
||||
strs[i] = string(v)
|
||||
}
|
||||
return strs
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) receiveRoomKey(ctx context.Context, evt *DecryptedOlmEvent, content *event.RoomKeyEventContent) {
|
||||
log := zerolog.Ctx(ctx).With().
|
||||
Str("algorithm", string(content.Algorithm)).
|
||||
|
|
@ -622,11 +616,14 @@ func (mach *OlmMachine) receiveRoomKey(ctx context.Context, evt *DecryptedOlmEve
|
|||
log.Err(err).Msg("Failed to redact previous megolm sessions")
|
||||
} else {
|
||||
log.Info().
|
||||
Strs("session_ids", stringifyArray(sessionIDs)).
|
||||
Array("session_ids", exzerolog.ArrayOfStrs(sessionIDs)).
|
||||
Msg("Redacted previous megolm sessions")
|
||||
}
|
||||
}
|
||||
mach.createGroupSession(ctx, evt.SenderKey, evt.Keys.Ed25519, content.RoomID, content.SessionID, content.SessionKey, maxAge, maxMessages, content.IsScheduled)
|
||||
err = mach.createGroupSession(ctx, evt.SenderKey, evt.Keys.Ed25519, content.RoomID, content.SessionID, content.SessionKey, maxAge, maxMessages, content.IsScheduled)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to create inbound group session")
|
||||
}
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) HandleRoomKeyWithheld(ctx context.Context, content *event.RoomKeyWithheldEventContent) {
|
||||
|
|
@ -634,6 +631,7 @@ func (mach *OlmMachine) HandleRoomKeyWithheld(ctx context.Context, content *even
|
|||
zerolog.Ctx(ctx).Debug().Interface("content", content).Msg("Non-megolm room key withheld event")
|
||||
return
|
||||
}
|
||||
// TODO log if there's a conflict? (currently ignored)
|
||||
err := mach.CryptoStore.PutWithheldGroupSession(ctx, *content)
|
||||
if err != nil {
|
||||
zerolog.Ctx(ctx).Error().Err(err).Msg("Failed to save room key withheld event")
|
||||
|
|
@ -681,6 +679,11 @@ func (mach *OlmMachine) ShareKeys(ctx context.Context, currentOTKCount int) erro
|
|||
log.Debug().Msg("No one-time keys nor device keys got when trying to share keys")
|
||||
return nil
|
||||
}
|
||||
// Save the keys before sending the upload request in case there is a
|
||||
// network failure.
|
||||
if err := mach.saveAccount(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
req := &mautrix.ReqUploadKeys{
|
||||
DeviceKeys: deviceKeys,
|
||||
OneTimeKeys: oneTimeKeys,
|
||||
|
|
@ -691,6 +694,7 @@ func (mach *OlmMachine) ShareKeys(ctx context.Context, currentOTKCount int) erro
|
|||
return err
|
||||
}
|
||||
mach.lastOTKUpload = time.Now()
|
||||
mach.account.Internal.MarkKeysAsPublished()
|
||||
mach.account.Shared = true
|
||||
return mach.saveAccount(ctx)
|
||||
}
|
||||
|
|
@ -702,7 +706,7 @@ func (mach *OlmMachine) ExpiredKeyDeleteLoop(ctx context.Context) {
|
|||
if err != nil {
|
||||
log.Err(err).Msg("Failed to redact expired megolm sessions")
|
||||
} else if len(sessionIDs) > 0 {
|
||||
log.Info().Strs("session_ids", stringifyArray(sessionIDs)).Msg("Redacted expired megolm sessions")
|
||||
log.Info().Array("session_ids", exzerolog.ArrayOfStrs(sessionIDs)).Msg("Redacted expired megolm sessions")
|
||||
} else {
|
||||
log.Debug().Msg("Didn't find any expired megolm sessions")
|
||||
}
|
||||
|
|
|
|||
9
vendor/maunium.net/go/mautrix/crypto/olm/inboundgroupsession.go
generated
vendored
9
vendor/maunium.net/go/mautrix/crypto/olm/inboundgroupsession.go
generated
vendored
|
|
@ -7,6 +7,7 @@ package olm
|
|||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"unsafe"
|
||||
|
||||
|
|
@ -190,12 +191,6 @@ func (s *InboundGroupSession) UnmarshalJSON(data []byte) error {
|
|||
return s.Unpickle(data[1:len(data)-1], pickleKey)
|
||||
}
|
||||
|
||||
func clone(original []byte) []byte {
|
||||
clone := make([]byte, len(original))
|
||||
copy(clone, original)
|
||||
return clone
|
||||
}
|
||||
|
||||
// decryptMaxPlaintextLen returns the maximum number of bytes of plain-text a
|
||||
// given message could decode to. The actual size could be different due to
|
||||
// padding. Returns error on failure. If the message base64 couldn't be
|
||||
|
|
@ -208,7 +203,7 @@ func (s *InboundGroupSession) decryptMaxPlaintextLen(message []byte) (uint, erro
|
|||
return 0, EmptyInput
|
||||
}
|
||||
// olm_group_decrypt_max_plaintext_length destroys the input, so we have to clone it
|
||||
message = clone(message)
|
||||
message = bytes.Clone(message)
|
||||
r := C.olm_group_decrypt_max_plaintext_length(
|
||||
(*C.OlmInboundGroupSession)(s.int),
|
||||
(*C.uint8_t)(&message[0]),
|
||||
|
|
|
|||
6
vendor/maunium.net/go/mautrix/crypto/olm/olm.go
generated
vendored
6
vendor/maunium.net/go/mautrix/crypto/olm/olm.go
generated
vendored
|
|
@ -5,12 +5,6 @@ package olm
|
|||
// #cgo LDFLAGS: -lolm -lstdc++
|
||||
// #include <olm/olm.h>
|
||||
import "C"
|
||||
import (
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// Signatures is the data structure used to sign JSON objects.
|
||||
type Signatures map[id.UserID]map[id.DeviceKeyID]string
|
||||
|
||||
// Version returns the version number of the olm library.
|
||||
func Version() (major, minor, patch uint8) {
|
||||
|
|
|
|||
7
vendor/maunium.net/go/mautrix/crypto/olm/olm_goolm.go
generated
vendored
7
vendor/maunium.net/go/mautrix/crypto/olm/olm_goolm.go
generated
vendored
|
|
@ -2,13 +2,6 @@
|
|||
|
||||
package olm
|
||||
|
||||
import (
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// Signatures is the data structure used to sign JSON objects.
|
||||
type Signatures map[id.UserID]map[id.DeviceKeyID]string
|
||||
|
||||
// Version returns the version number of the olm library.
|
||||
func Version() (major, minor, patch uint8) {
|
||||
return 3, 2, 15
|
||||
|
|
|
|||
24
vendor/maunium.net/go/mautrix/crypto/pkcs7/pkcs7.go
generated
vendored
24
vendor/maunium.net/go/mautrix/crypto/pkcs7/pkcs7.go
generated
vendored
|
|
@ -8,23 +8,23 @@ package pkcs7
|
|||
|
||||
import "bytes"
|
||||
|
||||
// Pad implements PKCS#7 padding as defined in [RFC2315]. It pads the plaintext
|
||||
// to the given blockSize in the range [1, 255]. This is normally used in
|
||||
// AES-CBC encryption.
|
||||
// Pad implements PKCS#7 padding as defined in [RFC2315]. It pads the data to
|
||||
// the given blockSize in the range [1, 255]. This is normally used in AES-CBC
|
||||
// encryption.
|
||||
//
|
||||
// [RFC2315]: https://www.ietf.org/rfc/rfc2315.txt
|
||||
func Pad(plaintext []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(plaintext)%blockSize
|
||||
return append(plaintext, bytes.Repeat([]byte{byte(padding)}, padding)...)
|
||||
func Pad(data []byte, blockSize int) []byte {
|
||||
padding := blockSize - len(data)%blockSize
|
||||
return append(data, bytes.Repeat([]byte{byte(padding)}, padding)...)
|
||||
}
|
||||
|
||||
// Unpad implements PKCS#7 unpadding as defined in [RFC2315]. It unpads the
|
||||
// plaintext by reading the padding amount from the last byte of the plaintext.
|
||||
// This is normally used in AES-CBC decryption.
|
||||
// data by reading the padding amount from the last byte of the data. This is
|
||||
// normally used in AES-CBC decryption.
|
||||
//
|
||||
// [RFC2315]: https://www.ietf.org/rfc/rfc2315.txt
|
||||
func Unpad(plaintext []byte) []byte {
|
||||
length := len(plaintext)
|
||||
unpadding := int(plaintext[length-1])
|
||||
return plaintext[:length-unpadding]
|
||||
func Unpad(data []byte) []byte {
|
||||
length := len(data)
|
||||
unpadding := int(data[length-1])
|
||||
return data[:length-unpadding]
|
||||
}
|
||||
|
|
|
|||
5
vendor/maunium.net/go/mautrix/crypto/sessions.go
generated
vendored
5
vendor/maunium.net/go/mautrix/crypto/sessions.go
generated
vendored
|
|
@ -196,11 +196,14 @@ func NewOutboundGroupSession(roomID id.RoomID, encryptionContent *event.Encrypti
|
|||
RoomID: roomID,
|
||||
}
|
||||
if encryptionContent != nil {
|
||||
// Clamp rotation period to prevent unreasonable values
|
||||
// Similar to https://github.com/matrix-org/matrix-rust-sdk/blob/matrix-sdk-crypto-0.7.1/crates/matrix-sdk-crypto/src/olm/group_sessions/outbound.rs#L415-L441
|
||||
if encryptionContent.RotationPeriodMillis != 0 {
|
||||
ogs.MaxAge = time.Duration(encryptionContent.RotationPeriodMillis) * time.Millisecond
|
||||
ogs.MaxAge = min(max(ogs.MaxAge, 1*time.Hour), 365*24*time.Hour)
|
||||
}
|
||||
if encryptionContent.RotationPeriodMessages != 0 {
|
||||
ogs.MaxMessages = encryptionContent.RotationPeriodMessages
|
||||
ogs.MaxMessages = min(max(encryptionContent.RotationPeriodMessages, 1), 10000)
|
||||
}
|
||||
}
|
||||
return ogs
|
||||
|
|
|
|||
125
vendor/maunium.net/go/mautrix/crypto/sql_store.go
generated
vendored
125
vendor/maunium.net/go/mautrix/crypto/sql_store.go
generated
vendored
|
|
@ -77,8 +77,8 @@ func (store *SQLCryptoStore) PutNextBatch(ctx context.Context, nextBatch string)
|
|||
// GetNextBatch retrieves the next sync batch token for the current account.
|
||||
func (store *SQLCryptoStore) GetNextBatch(ctx context.Context) (string, error) {
|
||||
if store.SyncToken == "" {
|
||||
err := store.DB.Conn(ctx).
|
||||
QueryRowContext(ctx, "SELECT sync_token FROM crypto_account WHERE account_id=$1", store.AccountID).
|
||||
err := store.DB.
|
||||
QueryRow(ctx, "SELECT sync_token FROM crypto_account WHERE account_id=$1", store.AccountID).
|
||||
Scan(&store.SyncToken)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
return "", err
|
||||
|
|
@ -261,13 +261,6 @@ func (store *SQLCryptoStore) UpdateSession(ctx context.Context, _ id.SenderKey,
|
|||
return err
|
||||
}
|
||||
|
||||
func intishPtr[T int | int64](i T) *T {
|
||||
if i == 0 {
|
||||
return nil
|
||||
}
|
||||
return &i
|
||||
}
|
||||
|
||||
func datePtr(t time.Time) *time.Time {
|
||||
if t.IsZero() {
|
||||
return nil
|
||||
|
|
@ -276,13 +269,25 @@ func datePtr(t time.Time) *time.Time {
|
|||
}
|
||||
|
||||
// PutGroupSession stores an inbound Megolm group session for a room, sender and session.
|
||||
func (store *SQLCryptoStore) PutGroupSession(ctx context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, session *InboundGroupSession) error {
|
||||
func (store *SQLCryptoStore) PutGroupSession(ctx context.Context, session *InboundGroupSession) error {
|
||||
sessionBytes := session.Internal.Pickle(store.PickleKey)
|
||||
forwardingChains := strings.Join(session.ForwardingChains, ",")
|
||||
ratchetSafety, err := json.Marshal(&session.RatchetSafety)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal ratchet safety info: %w", err)
|
||||
}
|
||||
zerolog.Ctx(ctx).Debug().
|
||||
Stringer("session_id", session.ID()).
|
||||
Str("account_id", store.AccountID).
|
||||
Stringer("sender_key", session.SenderKey).
|
||||
Stringer("signing_key", session.SigningKey).
|
||||
Stringer("room_id", session.RoomID).
|
||||
Time("received_at", session.ReceivedAt).
|
||||
Int64("max_age", session.MaxAge).
|
||||
Int("max_messages", session.MaxMessages).
|
||||
Bool("is_scheduled", session.IsScheduled).
|
||||
Stringer("key_backup_version", session.KeyBackupVersion).
|
||||
Msg("Upserting megolm inbound group session")
|
||||
_, err = store.DB.Exec(ctx, `
|
||||
INSERT INTO crypto_megolm_inbound_session (
|
||||
session_id, sender_key, signing_key, room_id, session, forwarding_chains,
|
||||
|
|
@ -293,18 +298,18 @@ func (store *SQLCryptoStore) PutGroupSession(ctx context.Context, roomID id.Room
|
|||
room_id=excluded.room_id, session=excluded.session, forwarding_chains=excluded.forwarding_chains,
|
||||
ratchet_safety=excluded.ratchet_safety, received_at=excluded.received_at,
|
||||
max_age=excluded.max_age, max_messages=excluded.max_messages, is_scheduled=excluded.is_scheduled,
|
||||
key_backup_version=excluded.key_backup_version
|
||||
key_backup_version=excluded.key_backup_version
|
||||
`,
|
||||
sessionID, senderKey, session.SigningKey, roomID, sessionBytes, forwardingChains,
|
||||
ratchetSafety, datePtr(session.ReceivedAt), intishPtr(session.MaxAge), intishPtr(session.MaxMessages),
|
||||
session.ID(), session.SenderKey, session.SigningKey, session.RoomID, sessionBytes, forwardingChains,
|
||||
ratchetSafety, datePtr(session.ReceivedAt), dbutil.NumPtr(session.MaxAge), dbutil.NumPtr(session.MaxMessages),
|
||||
session.IsScheduled, session.KeyBackupVersion, store.AccountID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetGroupSession retrieves an inbound Megolm group session for a room, sender and session.
|
||||
func (store *SQLCryptoStore) GetGroupSession(ctx context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID) (*InboundGroupSession, error) {
|
||||
var senderKeyDB, signingKey, forwardingChains, withheldCode, withheldReason sql.NullString
|
||||
func (store *SQLCryptoStore) GetGroupSession(ctx context.Context, roomID id.RoomID, sessionID id.SessionID) (*InboundGroupSession, error) {
|
||||
var senderKey, signingKey, forwardingChains, withheldCode, withheldReason sql.NullString
|
||||
var sessionBytes, ratchetSafetyBytes []byte
|
||||
var receivedAt sql.NullTime
|
||||
var maxAge, maxMessages sql.NullInt64
|
||||
|
|
@ -313,9 +318,9 @@ func (store *SQLCryptoStore) GetGroupSession(ctx context.Context, roomID id.Room
|
|||
err := store.DB.QueryRow(ctx, `
|
||||
SELECT sender_key, signing_key, session, forwarding_chains, withheld_code, withheld_reason, ratchet_safety, received_at, max_age, max_messages, is_scheduled, key_backup_version
|
||||
FROM crypto_megolm_inbound_session
|
||||
WHERE room_id=$1 AND (sender_key=$2 OR $2 = '') AND session_id=$3 AND account_id=$4`,
|
||||
roomID, senderKey, sessionID, store.AccountID,
|
||||
).Scan(&senderKeyDB, &signingKey, &sessionBytes, &forwardingChains, &withheldCode, &withheldReason, &ratchetSafetyBytes, &receivedAt, &maxAge, &maxMessages, &isScheduled, &version)
|
||||
WHERE room_id=$1 AND session_id=$2 AND account_id=$3`,
|
||||
roomID, sessionID, store.AccountID,
|
||||
).Scan(&senderKey, &signingKey, &sessionBytes, &forwardingChains, &withheldCode, &withheldReason, &ratchetSafetyBytes, &receivedAt, &maxAge, &maxMessages, &isScheduled, &version)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
|
|
@ -325,19 +330,19 @@ func (store *SQLCryptoStore) GetGroupSession(ctx context.Context, roomID id.Room
|
|||
RoomID: roomID,
|
||||
Algorithm: id.AlgorithmMegolmV1,
|
||||
SessionID: sessionID,
|
||||
SenderKey: senderKey,
|
||||
SenderKey: id.Curve25519(senderKey.String),
|
||||
Code: event.RoomKeyWithheldCode(withheldCode.String),
|
||||
Reason: withheldReason.String,
|
||||
}
|
||||
}
|
||||
igs, chains, rs, err := store.postScanInboundGroupSession(sessionBytes, ratchetSafetyBytes, forwardingChains.String)
|
||||
if senderKey == "" {
|
||||
senderKey = id.Curve25519(senderKeyDB.String)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &InboundGroupSession{
|
||||
Internal: *igs,
|
||||
SigningKey: id.Ed25519(signingKey.String),
|
||||
SenderKey: senderKey,
|
||||
SenderKey: id.Curve25519(senderKey.String),
|
||||
RoomID: roomID,
|
||||
ForwardingChains: chains,
|
||||
RatchetSafety: rs,
|
||||
|
|
@ -349,7 +354,7 @@ func (store *SQLCryptoStore) GetGroupSession(ctx context.Context, roomID id.Room
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (store *SQLCryptoStore) RedactGroupSession(ctx context.Context, _ id.RoomID, _ id.SenderKey, sessionID id.SessionID, reason string) error {
|
||||
func (store *SQLCryptoStore) RedactGroupSession(ctx context.Context, _ id.RoomID, sessionID id.SessionID, reason string) error {
|
||||
_, err := store.DB.Exec(ctx, `
|
||||
UPDATE crypto_megolm_inbound_session
|
||||
SET withheld_code=$1, withheld_reason=$2, session=NULL, forwarding_chains=NULL
|
||||
|
|
@ -420,18 +425,21 @@ func (store *SQLCryptoStore) RedactOutdatedGroupSessions(ctx context.Context) ([
|
|||
}
|
||||
|
||||
func (store *SQLCryptoStore) PutWithheldGroupSession(ctx context.Context, content event.RoomKeyWithheldEventContent) error {
|
||||
_, err := store.DB.Exec(ctx, "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)
|
||||
_, err := store.DB.Exec(ctx, `
|
||||
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)
|
||||
ON CONFLICT (session_id, account_id) DO NOTHING
|
||||
`, content.SessionID, content.SenderKey, content.RoomID, content.Code, content.Reason, time.Now().UTC(), store.AccountID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (store *SQLCryptoStore) GetWithheldGroupSession(ctx context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID) (*event.RoomKeyWithheldEventContent, error) {
|
||||
var code, reason sql.NullString
|
||||
func (store *SQLCryptoStore) GetWithheldGroupSession(ctx context.Context, roomID id.RoomID, sessionID id.SessionID) (*event.RoomKeyWithheldEventContent, error) {
|
||||
var senderKey, code, reason sql.NullString
|
||||
err := store.DB.QueryRow(ctx, `
|
||||
SELECT withheld_code, withheld_reason FROM crypto_megolm_inbound_session
|
||||
WHERE room_id=$1 AND sender_key=$2 AND session_id=$3 AND account_id=$4`,
|
||||
roomID, senderKey, sessionID, store.AccountID,
|
||||
).Scan(&code, &reason)
|
||||
SELECT withheld_code, withheld_reason, sender_key FROM crypto_megolm_inbound_session
|
||||
WHERE room_id=$1 AND session_id=$2 AND account_id=$3`,
|
||||
roomID, sessionID, store.AccountID,
|
||||
).Scan(&code, &reason, &senderKey)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
} else if err != nil || !code.Valid {
|
||||
|
|
@ -441,7 +449,7 @@ func (store *SQLCryptoStore) GetWithheldGroupSession(ctx context.Context, roomID
|
|||
RoomID: roomID,
|
||||
Algorithm: id.AlgorithmMegolmV1,
|
||||
SessionID: sessionID,
|
||||
SenderKey: senderKey,
|
||||
SenderKey: id.Curve25519(senderKey.String),
|
||||
Code: event.RoomKeyWithheldCode(code.String),
|
||||
Reason: reason.String,
|
||||
}, nil
|
||||
|
|
@ -479,6 +487,9 @@ func (store *SQLCryptoStore) scanInboundGroupSession(rows dbutil.Scannable) (*In
|
|||
return nil, err
|
||||
}
|
||||
igs, chains, rs, err := store.postScanInboundGroupSession(sessionBytes, ratchetSafetyBytes, forwardingChains.String)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &InboundGroupSession{
|
||||
Internal: *igs,
|
||||
SigningKey: id.Ed25519(signingKey.String),
|
||||
|
|
@ -744,6 +755,17 @@ func (store *SQLCryptoStore) PutDevices(ctx context.Context, userID id.UserID, d
|
|||
})
|
||||
}
|
||||
|
||||
func userIDsToParams(users []id.UserID) (placeholders string, params []any) {
|
||||
queryString := make([]string, len(users))
|
||||
params = make([]any, len(users))
|
||||
for i, user := range users {
|
||||
queryString[i] = fmt.Sprintf("$%d", i+1)
|
||||
params[i] = user
|
||||
}
|
||||
placeholders = strings.Join(queryString, ",")
|
||||
return
|
||||
}
|
||||
|
||||
// FilterTrackedUsers finds all the user IDs out of the given ones for which the database contains identity information.
|
||||
func (store *SQLCryptoStore) FilterTrackedUsers(ctx context.Context, users []id.UserID) ([]id.UserID, error) {
|
||||
var rows dbutil.Rows
|
||||
|
|
@ -751,13 +773,8 @@ func (store *SQLCryptoStore) FilterTrackedUsers(ctx context.Context, users []id.
|
|||
if store.DB.Dialect == dbutil.Postgres && PostgresArrayWrapper != nil {
|
||||
rows, err = store.DB.Query(ctx, "SELECT user_id FROM crypto_tracked_user WHERE user_id = ANY($1)", PostgresArrayWrapper(users))
|
||||
} else {
|
||||
queryString := make([]string, len(users))
|
||||
params := make([]interface{}, len(users))
|
||||
for i, user := range users {
|
||||
queryString[i] = fmt.Sprintf("?%d", i+1)
|
||||
params[i] = user
|
||||
}
|
||||
rows, err = store.DB.Query(ctx, "SELECT user_id FROM crypto_tracked_user WHERE user_id IN ("+strings.Join(queryString, ",")+")", params...)
|
||||
placeholders, params := userIDsToParams(users)
|
||||
rows, err = store.DB.Query(ctx, "SELECT user_id FROM crypto_tracked_user WHERE user_id IN ("+placeholders+")", params...)
|
||||
}
|
||||
if err != nil {
|
||||
return users, err
|
||||
|
|
@ -766,18 +783,14 @@ func (store *SQLCryptoStore) FilterTrackedUsers(ctx context.Context, users []id.
|
|||
}
|
||||
|
||||
// MarkTrackedUsersOutdated flags that the device list for given users are outdated.
|
||||
func (store *SQLCryptoStore) MarkTrackedUsersOutdated(ctx context.Context, users []id.UserID) error {
|
||||
return store.DB.DoTxn(ctx, nil, func(ctx context.Context) error {
|
||||
// TODO refactor to use a single query
|
||||
for _, userID := range users {
|
||||
_, err := store.DB.Exec(ctx, "UPDATE crypto_tracked_user SET devices_outdated = true WHERE user_id = $1", userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update user in the tracked users list: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
func (store *SQLCryptoStore) MarkTrackedUsersOutdated(ctx context.Context, users []id.UserID) (err error) {
|
||||
if store.DB.Dialect == dbutil.Postgres && PostgresArrayWrapper != nil {
|
||||
_, err = store.DB.Exec(ctx, "UPDATE crypto_tracked_user SET devices_outdated = true WHERE user_id = ANY($1)", PostgresArrayWrapper(users))
|
||||
} else {
|
||||
placeholders, params := userIDsToParams(users)
|
||||
_, err = store.DB.Exec(ctx, "UPDATE crypto_tracked_user SET devices_outdated = true WHERE user_id IN ("+placeholders+")", params...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetOutdatedTrackerUsers gets all tracked users whose devices need to be updated.
|
||||
|
|
@ -876,15 +889,15 @@ func (store *SQLCryptoStore) PutSecret(ctx context.Context, name id.Secret, valu
|
|||
return err
|
||||
}
|
||||
_, err = store.DB.Exec(ctx, `
|
||||
INSERT INTO crypto_secrets (name, secret) VALUES ($1, $2)
|
||||
ON CONFLICT (name) DO UPDATE SET secret=excluded.secret
|
||||
`, name, bytes)
|
||||
INSERT INTO crypto_secrets (account_id, name, secret) VALUES ($1, $2, $3)
|
||||
ON CONFLICT (account_id, name) DO UPDATE SET secret=excluded.secret
|
||||
`, store.AccountID, name, bytes)
|
||||
return err
|
||||
}
|
||||
|
||||
func (store *SQLCryptoStore) GetSecret(ctx context.Context, name id.Secret) (value string, err error) {
|
||||
var bytes []byte
|
||||
err = store.DB.QueryRow(ctx, `SELECT secret FROM crypto_secrets WHERE name=$1`, name).Scan(&bytes)
|
||||
err = store.DB.QueryRow(ctx, `SELECT secret FROM crypto_secrets WHERE account_id=$1 AND name=$2`, store.AccountID, name).Scan(&bytes)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
|
|
@ -895,6 +908,6 @@ func (store *SQLCryptoStore) GetSecret(ctx context.Context, name id.Secret) (val
|
|||
}
|
||||
|
||||
func (store *SQLCryptoStore) DeleteSecret(ctx context.Context, name id.Secret) (err error) {
|
||||
_, err = store.DB.Exec(ctx, "DELETE FROM crypto_secrets WHERE name=$1", name)
|
||||
_, err = store.DB.Exec(ctx, "DELETE FROM crypto_secrets WHERE account_id=$1 AND name=$2", store.AccountID, name)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
9
vendor/maunium.net/go/mautrix/crypto/sql_store_upgrade/00-latest-revision.sql
generated
vendored
9
vendor/maunium.net/go/mautrix/crypto/sql_store_upgrade/00-latest-revision.sql
generated
vendored
|
|
@ -1,4 +1,4 @@
|
|||
-- v0 -> v14 (compatible with v9+): Latest revision
|
||||
-- v0 -> v15: Latest revision
|
||||
CREATE TABLE IF NOT EXISTS crypto_account (
|
||||
account_id TEXT PRIMARY KEY,
|
||||
device_id TEXT NOT NULL,
|
||||
|
|
@ -105,6 +105,9 @@ CREATE TABLE IF NOT EXISTS crypto_cross_signing_signatures (
|
|||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS crypto_secrets (
|
||||
name TEXT PRIMARY KEY NOT NULL,
|
||||
secret bytea NOT NULL
|
||||
account_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
secret bytea NOT NULL,
|
||||
|
||||
PRIMARY KEY (account_id, name)
|
||||
);
|
||||
|
|
|
|||
21
vendor/maunium.net/go/mautrix/crypto/sql_store_upgrade/15-fix-secrets.sql
generated
vendored
Normal file
21
vendor/maunium.net/go/mautrix/crypto/sql_store_upgrade/15-fix-secrets.sql
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
-- v15: Fix crypto_secrets table
|
||||
CREATE TABLE crypto_secrets_new (
|
||||
account_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
secret bytea NOT NULL,
|
||||
|
||||
PRIMARY KEY (account_id, name)
|
||||
);
|
||||
|
||||
INSERT INTO crypto_secrets_new (account_id, name, secret)
|
||||
SELECT '', name, secret
|
||||
FROM crypto_secrets;
|
||||
|
||||
DROP TABLE crypto_secrets;
|
||||
|
||||
ALTER TABLE crypto_secrets_new RENAME TO crypto_secrets;
|
||||
|
||||
-- only: sqlite
|
||||
UPDATE crypto_secrets SET account_id=(SELECT account_id FROM crypto_account ORDER BY rowid DESC LIMIT 1);
|
||||
-- only: postgres
|
||||
UPDATE crypto_secrets SET account_id=(SELECT account_id FROM crypto_account LIMIT 1);
|
||||
2
vendor/maunium.net/go/mautrix/crypto/sql_store_upgrade/upgrade.go
generated
vendored
2
vendor/maunium.net/go/mautrix/crypto/sql_store_upgrade/upgrade.go
generated
vendored
|
|
@ -22,7 +22,7 @@ const VersionTableName = "crypto_version"
|
|||
var fs embed.FS
|
||||
|
||||
func init() {
|
||||
Table.Register(-1, 3, 0, "Unsupported version", false, func(ctx context.Context, database *dbutil.Database) error {
|
||||
Table.Register(-1, 3, 0, "Unsupported version", dbutil.TxnModeOff, func(ctx context.Context, database *dbutil.Database) error {
|
||||
return fmt.Errorf("upgrading from versions 1 and 2 of the crypto store is no longer supported in mautrix-go v0.12+")
|
||||
})
|
||||
Table.RegisterFS(fs)
|
||||
|
|
|
|||
25
vendor/maunium.net/go/mautrix/crypto/ssss/key.go
generated
vendored
25
vendor/maunium.net/go/mautrix/crypto/ssss/key.go
generated
vendored
|
|
@ -7,11 +7,12 @@
|
|||
package ssss
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.mau.fi/util/random"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/utils"
|
||||
)
|
||||
|
||||
|
|
@ -33,10 +34,7 @@ func NewKey(passphrase string) (*Key, error) {
|
|||
if len(passphrase) > 0 {
|
||||
// There's a passphrase. We need to generate a salt for it, set the metadata
|
||||
// and then compute the key using the passphrase and the metadata.
|
||||
saltBytes := make([]byte, 24)
|
||||
if _, err := rand.Read(saltBytes); err != nil {
|
||||
return nil, fmt.Errorf("failed to get random bytes for salt: %w", err)
|
||||
}
|
||||
saltBytes := random.Bytes(24)
|
||||
keyData.Passphrase = &PassphraseMetadata{
|
||||
Algorithm: PassphraseAlgorithmPBKDF2,
|
||||
Iterations: 500000,
|
||||
|
|
@ -50,24 +48,15 @@ func NewKey(passphrase string) (*Key, error) {
|
|||
}
|
||||
} else {
|
||||
// No passphrase, just generate a random key
|
||||
ssssKey = make([]byte, 32)
|
||||
if _, err := rand.Read(ssssKey); err != nil {
|
||||
return nil, fmt.Errorf("failed to get random bytes for key: %w", err)
|
||||
}
|
||||
ssssKey = random.Bytes(32)
|
||||
}
|
||||
|
||||
// Generate a random ID for the key. It's what identifies the key in account data.
|
||||
keyIDBytes := make([]byte, 24)
|
||||
if _, err := rand.Read(keyIDBytes); err != nil {
|
||||
return nil, fmt.Errorf("failed to get random bytes for key ID: %w", err)
|
||||
}
|
||||
keyIDBytes := random.Bytes(24)
|
||||
|
||||
// We store a certain hash in the key metadata so that clients can check if the user entered the correct key.
|
||||
var ivBytes [utils.AESCTRIVLength]byte
|
||||
if _, err := rand.Read(ivBytes[:]); err != nil {
|
||||
return nil, fmt.Errorf("failed to get random bytes for IV: %w", err)
|
||||
}
|
||||
keyData.IV = base64.RawStdEncoding.EncodeToString(ivBytes[:])
|
||||
ivBytes := random.Bytes(utils.AESCTRIVLength)
|
||||
keyData.IV = base64.RawStdEncoding.EncodeToString(ivBytes)
|
||||
keyData.MAC = keyData.calculateHash(ssssKey)
|
||||
|
||||
return &Key{
|
||||
|
|
|
|||
215
vendor/maunium.net/go/mautrix/crypto/store.go
generated
vendored
215
vendor/maunium.net/go/mautrix/crypto/store.go
generated
vendored
|
|
@ -13,6 +13,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"go.mau.fi/util/dbutil"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
|
@ -50,13 +51,13 @@ type Store interface {
|
|||
// PutGroupSession inserts an inbound Megolm session into the store. If an earlier withhold event has been inserted
|
||||
// with PutWithheldGroupSession, this call should replace that. However, PutWithheldGroupSession must not replace
|
||||
// sessions inserted with this call.
|
||||
PutGroupSession(context.Context, id.RoomID, id.SenderKey, id.SessionID, *InboundGroupSession) error
|
||||
PutGroupSession(context.Context, *InboundGroupSession) error
|
||||
// GetGroupSession gets an inbound Megolm session from the store. If the group session has been withheld
|
||||
// (i.e. a room key withheld event has been saved with PutWithheldGroupSession), this should return the
|
||||
// ErrGroupSessionWithheld error. The caller may use GetWithheldGroupSession to find more details.
|
||||
GetGroupSession(context.Context, id.RoomID, id.SenderKey, id.SessionID) (*InboundGroupSession, error)
|
||||
GetGroupSession(context.Context, id.RoomID, id.SessionID) (*InboundGroupSession, error)
|
||||
// RedactGroupSession removes the session data for the given inbound Megolm session from the store.
|
||||
RedactGroupSession(context.Context, id.RoomID, id.SenderKey, id.SessionID, string) error
|
||||
RedactGroupSession(context.Context, id.RoomID, id.SessionID, string) error
|
||||
// RedactGroupSessions removes the session data for all inbound Megolm sessions from a specific device and/or in a specific room.
|
||||
RedactGroupSessions(context.Context, id.RoomID, id.SenderKey, string) ([]id.SessionID, error)
|
||||
// RedactExpiredGroupSessions removes the session data for all inbound Megolm sessions that have expired.
|
||||
|
|
@ -66,7 +67,7 @@ type Store interface {
|
|||
// PutWithheldGroupSession tells the store that a specific Megolm session was withheld.
|
||||
PutWithheldGroupSession(context.Context, event.RoomKeyWithheldEventContent) error
|
||||
// GetWithheldGroupSession gets the event content that was previously inserted with PutWithheldGroupSession.
|
||||
GetWithheldGroupSession(context.Context, id.RoomID, id.SenderKey, id.SessionID) (*event.RoomKeyWithheldEventContent, error)
|
||||
GetWithheldGroupSession(context.Context, id.RoomID, id.SessionID) (*event.RoomKeyWithheldEventContent, error)
|
||||
|
||||
// GetGroupSessionsForRoom gets all the inbound Megolm sessions for a specific room. This is used for creating key
|
||||
// export files. Unlike GetGroupSession, this should not return any errors about withheld keys.
|
||||
|
|
@ -160,8 +161,8 @@ type MemoryStore struct {
|
|||
|
||||
Account *OlmAccount
|
||||
Sessions map[id.SenderKey]OlmSessionList
|
||||
GroupSessions map[id.RoomID]map[id.SenderKey]map[id.SessionID]*InboundGroupSession
|
||||
WithheldGroupSessions map[id.RoomID]map[id.SenderKey]map[id.SessionID]*event.RoomKeyWithheldEventContent
|
||||
GroupSessions map[id.RoomID]map[id.SessionID]*InboundGroupSession
|
||||
WithheldGroupSessions map[id.RoomID]map[id.SessionID]*event.RoomKeyWithheldEventContent
|
||||
OutGroupSessions map[id.RoomID]*OutboundGroupSession
|
||||
SharedGroupSessions map[id.UserID]map[id.IdentityKey]map[id.SessionID]struct{}
|
||||
MessageIndices map[messageIndexKey]messageIndexValue
|
||||
|
|
@ -182,8 +183,8 @@ func NewMemoryStore(saveCallback func() error) *MemoryStore {
|
|||
save: saveCallback,
|
||||
|
||||
Sessions: make(map[id.SenderKey]OlmSessionList),
|
||||
GroupSessions: make(map[id.RoomID]map[id.SenderKey]map[id.SessionID]*InboundGroupSession),
|
||||
WithheldGroupSessions: make(map[id.RoomID]map[id.SenderKey]map[id.SessionID]*event.RoomKeyWithheldEventContent),
|
||||
GroupSessions: make(map[id.RoomID]map[id.SessionID]*InboundGroupSession),
|
||||
WithheldGroupSessions: make(map[id.RoomID]map[id.SessionID]*event.RoomKeyWithheldEventContent),
|
||||
OutGroupSessions: make(map[id.RoomID]*OutboundGroupSession),
|
||||
SharedGroupSessions: make(map[id.UserID]map[id.IdentityKey]map[id.SessionID]struct{}),
|
||||
MessageIndices: make(map[messageIndexKey]messageIndexValue),
|
||||
|
|
@ -197,9 +198,8 @@ func NewMemoryStore(saveCallback func() error) *MemoryStore {
|
|||
|
||||
func (gs *MemoryStore) Flush(_ context.Context) error {
|
||||
gs.lock.Lock()
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
defer gs.lock.Unlock()
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetAccount(_ context.Context) (*OlmAccount, error) {
|
||||
|
|
@ -208,31 +208,29 @@ func (gs *MemoryStore) GetAccount(_ context.Context) (*OlmAccount, error) {
|
|||
|
||||
func (gs *MemoryStore) PutAccount(_ context.Context, account *OlmAccount) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
gs.Account = account
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetSessions(_ context.Context, senderKey id.SenderKey) (OlmSessionList, error) {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
sessions, ok := gs.Sessions[senderKey]
|
||||
if !ok {
|
||||
sessions = []*OlmSession{}
|
||||
gs.Sessions[senderKey] = sessions
|
||||
}
|
||||
gs.lock.Unlock()
|
||||
return sessions, nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) AddSession(_ context.Context, senderKey id.SenderKey, session *OlmSession) error {
|
||||
gs.lock.Lock()
|
||||
sessions, _ := gs.Sessions[senderKey]
|
||||
defer gs.lock.Unlock()
|
||||
sessions := gs.Sessions[senderKey]
|
||||
gs.Sessions[senderKey] = append(sessions, session)
|
||||
sort.Sort(gs.Sessions[senderKey])
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) UpdateSession(_ context.Context, _ id.SenderKey, _ *OlmSession) error {
|
||||
|
|
@ -242,102 +240,86 @@ func (gs *MemoryStore) UpdateSession(_ context.Context, _ id.SenderKey, _ *OlmSe
|
|||
|
||||
func (gs *MemoryStore) HasSession(_ context.Context, senderKey id.SenderKey) bool {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
sessions, ok := gs.Sessions[senderKey]
|
||||
gs.lock.RUnlock()
|
||||
return ok && len(sessions) > 0 && !sessions[0].Expired()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetLatestSession(_ context.Context, senderKey id.SenderKey) (*OlmSession, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
sessions, ok := gs.Sessions[senderKey]
|
||||
gs.lock.RUnlock()
|
||||
if !ok || len(sessions) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return sessions[0], nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) getGroupSessions(roomID id.RoomID, senderKey id.SenderKey) map[id.SessionID]*InboundGroupSession {
|
||||
func (gs *MemoryStore) getGroupSessions(roomID id.RoomID) map[id.SessionID]*InboundGroupSession {
|
||||
room, ok := gs.GroupSessions[roomID]
|
||||
if !ok {
|
||||
room = make(map[id.SenderKey]map[id.SessionID]*InboundGroupSession)
|
||||
room = make(map[id.SessionID]*InboundGroupSession)
|
||||
gs.GroupSessions[roomID] = room
|
||||
}
|
||||
sender, ok := room[senderKey]
|
||||
if !ok {
|
||||
sender = make(map[id.SessionID]*InboundGroupSession)
|
||||
room[senderKey] = sender
|
||||
}
|
||||
return sender
|
||||
return room
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) PutGroupSession(_ context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, igs *InboundGroupSession) error {
|
||||
func (gs *MemoryStore) PutGroupSession(_ context.Context, igs *InboundGroupSession) error {
|
||||
gs.lock.Lock()
|
||||
gs.getGroupSessions(roomID, senderKey)[sessionID] = igs
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
defer gs.lock.Unlock()
|
||||
gs.getGroupSessions(igs.RoomID)[igs.ID()] = igs
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetGroupSession(_ context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID) (*InboundGroupSession, error) {
|
||||
func (gs *MemoryStore) GetGroupSession(_ context.Context, roomID id.RoomID, sessionID id.SessionID) (*InboundGroupSession, error) {
|
||||
gs.lock.Lock()
|
||||
session, ok := gs.getGroupSessions(roomID, senderKey)[sessionID]
|
||||
defer gs.lock.Unlock()
|
||||
session, ok := gs.getGroupSessions(roomID)[sessionID]
|
||||
if !ok {
|
||||
withheld, ok := gs.getWithheldGroupSessions(roomID, senderKey)[sessionID]
|
||||
gs.lock.Unlock()
|
||||
withheld, ok := gs.getWithheldGroupSessions(roomID)[sessionID]
|
||||
if ok {
|
||||
return nil, fmt.Errorf("%w (%s)", ErrGroupSessionWithheld, withheld.Code)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
gs.lock.Unlock()
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) RedactGroupSession(_ context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID, reason string) error {
|
||||
func (gs *MemoryStore) RedactGroupSession(_ context.Context, roomID id.RoomID, sessionID id.SessionID, reason string) error {
|
||||
gs.lock.Lock()
|
||||
delete(gs.getGroupSessions(roomID, senderKey), sessionID)
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
defer gs.lock.Unlock()
|
||||
delete(gs.getGroupSessions(roomID), sessionID)
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) RedactGroupSessions(_ context.Context, roomID id.RoomID, senderKey id.SenderKey, reason string) ([]id.SessionID, error) {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
var sessionIDs []id.SessionID
|
||||
if roomID != "" && senderKey != "" {
|
||||
sessions := gs.getGroupSessions(roomID, senderKey)
|
||||
for sessionID := range sessions {
|
||||
sessionIDs = append(sessionIDs, sessionID)
|
||||
delete(sessions, sessionID)
|
||||
sessions := gs.getGroupSessions(roomID)
|
||||
for sessionID, session := range sessions {
|
||||
if session.SenderKey == senderKey {
|
||||
sessionIDs = append(sessionIDs, sessionID)
|
||||
delete(sessions, sessionID)
|
||||
}
|
||||
}
|
||||
} else if senderKey != "" {
|
||||
for _, room := range gs.GroupSessions {
|
||||
sessions, ok := room[senderKey]
|
||||
if ok {
|
||||
for sessionID := range sessions {
|
||||
for sessionID, session := range room {
|
||||
if session.SenderKey == senderKey {
|
||||
sessionIDs = append(sessionIDs, sessionID)
|
||||
delete(room, sessionID)
|
||||
}
|
||||
delete(room, senderKey)
|
||||
}
|
||||
}
|
||||
} else if roomID != "" {
|
||||
room, ok := gs.GroupSessions[roomID]
|
||||
if ok {
|
||||
for senderKey := range room {
|
||||
sessions := room[senderKey]
|
||||
for sessionID := range sessions {
|
||||
sessionIDs = append(sessionIDs, sessionID)
|
||||
}
|
||||
}
|
||||
delete(gs.GroupSessions, roomID)
|
||||
}
|
||||
sessionIDs = maps.Keys(gs.GroupSessions[roomID])
|
||||
delete(gs.GroupSessions, roomID)
|
||||
} else {
|
||||
return nil, fmt.Errorf("room ID or sender key must be provided for redacting sessions")
|
||||
}
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return sessionIDs, err
|
||||
return sessionIDs, gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) RedactExpiredGroupSessions(_ context.Context) ([]id.SessionID, error) {
|
||||
|
|
@ -348,32 +330,26 @@ func (gs *MemoryStore) RedactOutdatedGroupSessions(_ context.Context) ([]id.Sess
|
|||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) getWithheldGroupSessions(roomID id.RoomID, senderKey id.SenderKey) map[id.SessionID]*event.RoomKeyWithheldEventContent {
|
||||
func (gs *MemoryStore) getWithheldGroupSessions(roomID id.RoomID) map[id.SessionID]*event.RoomKeyWithheldEventContent {
|
||||
room, ok := gs.WithheldGroupSessions[roomID]
|
||||
if !ok {
|
||||
room = make(map[id.SenderKey]map[id.SessionID]*event.RoomKeyWithheldEventContent)
|
||||
room = make(map[id.SessionID]*event.RoomKeyWithheldEventContent)
|
||||
gs.WithheldGroupSessions[roomID] = room
|
||||
}
|
||||
sender, ok := room[senderKey]
|
||||
if !ok {
|
||||
sender = make(map[id.SessionID]*event.RoomKeyWithheldEventContent)
|
||||
room[senderKey] = sender
|
||||
}
|
||||
return sender
|
||||
return room
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) PutWithheldGroupSession(_ context.Context, content event.RoomKeyWithheldEventContent) error {
|
||||
gs.lock.Lock()
|
||||
gs.getWithheldGroupSessions(content.RoomID, content.SenderKey)[content.SessionID] = &content
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
defer gs.lock.Unlock()
|
||||
gs.getWithheldGroupSessions(content.RoomID)[content.SessionID] = &content
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetWithheldGroupSession(_ context.Context, roomID id.RoomID, senderKey id.SenderKey, sessionID id.SessionID) (*event.RoomKeyWithheldEventContent, error) {
|
||||
func (gs *MemoryStore) GetWithheldGroupSession(_ context.Context, roomID id.RoomID, sessionID id.SessionID) (*event.RoomKeyWithheldEventContent, error) {
|
||||
gs.lock.Lock()
|
||||
session, ok := gs.getWithheldGroupSessions(roomID, senderKey)[sessionID]
|
||||
gs.lock.Unlock()
|
||||
defer gs.lock.Unlock()
|
||||
session, ok := gs.getWithheldGroupSessions(roomID)[sessionID]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -387,51 +363,38 @@ func (gs *MemoryStore) GetGroupSessionsForRoom(_ context.Context, roomID id.Room
|
|||
if !ok {
|
||||
return nil
|
||||
}
|
||||
var result []*InboundGroupSession
|
||||
for _, sessions := range room {
|
||||
for _, session := range sessions {
|
||||
result = append(result, session)
|
||||
}
|
||||
}
|
||||
return dbutil.NewSliceIter[*InboundGroupSession](result)
|
||||
return dbutil.NewSliceIter(maps.Values(room))
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetAllGroupSessions(_ context.Context) dbutil.RowIter[*InboundGroupSession] {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
var result []*InboundGroupSession
|
||||
for _, room := range gs.GroupSessions {
|
||||
for _, sessions := range room {
|
||||
for _, session := range sessions {
|
||||
result = append(result, session)
|
||||
}
|
||||
}
|
||||
result = append(result, maps.Values(room)...)
|
||||
}
|
||||
gs.lock.Unlock()
|
||||
return dbutil.NewSliceIter[*InboundGroupSession](result)
|
||||
return dbutil.NewSliceIter(result)
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetGroupSessionsWithoutKeyBackupVersion(_ context.Context, version id.KeyBackupVersion) dbutil.RowIter[*InboundGroupSession] {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
var result []*InboundGroupSession
|
||||
for _, room := range gs.GroupSessions {
|
||||
for _, sessions := range room {
|
||||
for _, session := range sessions {
|
||||
if session.KeyBackupVersion != version {
|
||||
result = append(result, session)
|
||||
}
|
||||
for _, session := range room {
|
||||
if session.KeyBackupVersion != version {
|
||||
result = append(result, session)
|
||||
}
|
||||
}
|
||||
}
|
||||
gs.lock.Unlock()
|
||||
return dbutil.NewSliceIter[*InboundGroupSession](result)
|
||||
return dbutil.NewSliceIter(result)
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) AddOutboundGroupSession(_ context.Context, session *OutboundGroupSession) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
gs.OutGroupSessions[session.RoomID] = session
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) UpdateOutboundGroupSession(_ context.Context, _ *OutboundGroupSession) error {
|
||||
|
|
@ -441,8 +404,8 @@ func (gs *MemoryStore) UpdateOutboundGroupSession(_ context.Context, _ *Outbound
|
|||
|
||||
func (gs *MemoryStore) GetOutboundGroupSession(_ context.Context, roomID id.RoomID) (*OutboundGroupSession, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
session, ok := gs.OutGroupSessions[roomID]
|
||||
gs.lock.RUnlock()
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -451,18 +414,18 @@ func (gs *MemoryStore) GetOutboundGroupSession(_ context.Context, roomID id.Room
|
|||
|
||||
func (gs *MemoryStore) RemoveOutboundGroupSession(_ context.Context, roomID id.RoomID) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
session, ok := gs.OutGroupSessions[roomID]
|
||||
if !ok || session == nil {
|
||||
gs.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
delete(gs.OutGroupSessions, roomID)
|
||||
gs.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) MarkOutboundGroupSessionShared(_ context.Context, userID id.UserID, identityKey id.IdentityKey, sessionID id.SessionID) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
|
||||
if _, ok := gs.SharedGroupSessions[userID]; !ok {
|
||||
gs.SharedGroupSessions[userID] = make(map[id.IdentityKey]map[id.SessionID]struct{})
|
||||
|
|
@ -475,7 +438,6 @@ func (gs *MemoryStore) MarkOutboundGroupSessionShared(_ context.Context, userID
|
|||
|
||||
identities[identityKey][sessionID] = struct{}{}
|
||||
|
||||
gs.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -521,11 +483,11 @@ func (gs *MemoryStore) ValidateMessageIndex(_ context.Context, senderKey id.Send
|
|||
|
||||
func (gs *MemoryStore) GetDevices(_ context.Context, userID id.UserID) (map[id.DeviceID]*id.Device, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
devices, ok := gs.Devices[userID]
|
||||
if !ok {
|
||||
devices = nil
|
||||
}
|
||||
gs.lock.RUnlock()
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
|
|
@ -560,30 +522,30 @@ func (gs *MemoryStore) FindDeviceByKey(_ context.Context, userID id.UserID, iden
|
|||
|
||||
func (gs *MemoryStore) PutDevice(_ context.Context, userID id.UserID, device *id.Device) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
devices, ok := gs.Devices[userID]
|
||||
if !ok {
|
||||
devices = make(map[id.DeviceID]*id.Device)
|
||||
gs.Devices[userID] = devices
|
||||
}
|
||||
devices[device.DeviceID] = device
|
||||
err := gs.save()
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) PutDevices(_ context.Context, userID id.UserID, devices map[id.DeviceID]*id.Device) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
gs.Devices[userID] = devices
|
||||
err := gs.save()
|
||||
if err == nil {
|
||||
delete(gs.OutdatedUsers, userID)
|
||||
}
|
||||
gs.lock.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) FilterTrackedUsers(_ context.Context, users []id.UserID) ([]id.UserID, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
var ptr int
|
||||
for _, userID := range users {
|
||||
_, ok := gs.Devices[userID]
|
||||
|
|
@ -592,33 +554,33 @@ func (gs *MemoryStore) FilterTrackedUsers(_ context.Context, users []id.UserID)
|
|||
ptr++
|
||||
}
|
||||
}
|
||||
gs.lock.RUnlock()
|
||||
return users[:ptr], nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) MarkTrackedUsersOutdated(_ context.Context, users []id.UserID) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
for _, userID := range users {
|
||||
if _, ok := gs.Devices[userID]; ok {
|
||||
gs.OutdatedUsers[userID] = struct{}{}
|
||||
}
|
||||
}
|
||||
gs.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetOutdatedTrackedUsers(_ context.Context) ([]id.UserID, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
users := make([]id.UserID, 0, len(gs.OutdatedUsers))
|
||||
for userID := range gs.OutdatedUsers {
|
||||
users = append(users, userID)
|
||||
}
|
||||
gs.lock.RUnlock()
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) PutCrossSigningKey(_ context.Context, userID id.UserID, usage id.CrossSigningUsage, key id.Ed25519) error {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
userKeys, ok := gs.CrossSigningKeys[userID]
|
||||
if !ok {
|
||||
userKeys = make(map[id.CrossSigningUsage]id.CrossSigningKey)
|
||||
|
|
@ -635,7 +597,6 @@ func (gs *MemoryStore) PutCrossSigningKey(_ context.Context, userID id.UserID, u
|
|||
}
|
||||
}
|
||||
err := gs.save()
|
||||
gs.lock.RUnlock()
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -651,6 +612,7 @@ func (gs *MemoryStore) GetCrossSigningKeys(_ context.Context, userID id.UserID)
|
|||
|
||||
func (gs *MemoryStore) PutSignature(_ context.Context, signedUserID id.UserID, signedKey id.Ed25519, signerUserID id.UserID, signerKey id.Ed25519, signature string) error {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
signedUserSigs, ok := gs.KeySignatures[signedUserID]
|
||||
if !ok {
|
||||
signedUserSigs = make(map[id.Ed25519]map[id.UserID]map[id.Ed25519]string)
|
||||
|
|
@ -667,9 +629,7 @@ func (gs *MemoryStore) PutSignature(_ context.Context, signedUserID id.UserID, s
|
|||
signaturesForKey[signerUserID] = signedByUser
|
||||
}
|
||||
signedByUser[signerKey] = signature
|
||||
err := gs.save()
|
||||
gs.lock.RUnlock()
|
||||
return err
|
||||
return gs.save()
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetSignaturesForKeyBy(_ context.Context, userID id.UserID, key id.Ed25519, signerID id.UserID) (map[id.Ed25519]string, error) {
|
||||
|
|
@ -700,8 +660,9 @@ func (gs *MemoryStore) IsKeySignedBy(ctx context.Context, userID id.UserID, key
|
|||
}
|
||||
|
||||
func (gs *MemoryStore) DropSignaturesByKey(_ context.Context, userID id.UserID, key id.Ed25519) (int64, error) {
|
||||
var count int64
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
var count int64
|
||||
for _, userSigs := range gs.KeySignatures {
|
||||
for _, keySigs := range userSigs {
|
||||
if signedBySigner, ok := keySigs[userID]; ok {
|
||||
|
|
@ -712,27 +673,25 @@ func (gs *MemoryStore) DropSignaturesByKey(_ context.Context, userID id.UserID,
|
|||
}
|
||||
}
|
||||
}
|
||||
gs.lock.RUnlock()
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) PutSecret(_ context.Context, name id.Secret, value string) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
gs.Secrets[name] = value
|
||||
gs.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) GetSecret(_ context.Context, name id.Secret) (value string, _ error) {
|
||||
func (gs *MemoryStore) GetSecret(_ context.Context, name id.Secret) (string, error) {
|
||||
gs.lock.RLock()
|
||||
value = gs.Secrets[name]
|
||||
gs.lock.RUnlock()
|
||||
return
|
||||
defer gs.lock.RUnlock()
|
||||
return gs.Secrets[name], nil
|
||||
}
|
||||
|
||||
func (gs *MemoryStore) DeleteSecret(_ context.Context, name id.Secret) error {
|
||||
gs.lock.Lock()
|
||||
defer gs.lock.Unlock()
|
||||
delete(gs.Secrets, name)
|
||||
gs.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
46
vendor/maunium.net/go/mautrix/event/accountdata.go
generated
vendored
46
vendor/maunium.net/go/mautrix/event/accountdata.go
generated
vendored
|
|
@ -8,6 +8,7 @@ package event
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
|
@ -18,10 +19,47 @@ type TagEventContent struct {
|
|||
Tags Tags `json:"tags"`
|
||||
}
|
||||
|
||||
type Tags map[string]Tag
|
||||
type Tags map[RoomTag]TagMetadata
|
||||
|
||||
type Tag struct {
|
||||
type RoomTag string
|
||||
|
||||
const (
|
||||
RoomTagFavourite RoomTag = "m.favourite"
|
||||
RoomTagLowPriority RoomTag = "m.lowpriority"
|
||||
RoomTagServerNotice RoomTag = "m.server_notice"
|
||||
)
|
||||
|
||||
func (rt RoomTag) IsUserDefined() bool {
|
||||
return strings.HasPrefix(string(rt), "u.")
|
||||
}
|
||||
|
||||
func (rt RoomTag) String() string {
|
||||
return string(rt)
|
||||
}
|
||||
|
||||
func (rt RoomTag) Name() string {
|
||||
if rt.IsUserDefined() {
|
||||
return string(rt[2:])
|
||||
}
|
||||
switch rt {
|
||||
case RoomTagFavourite:
|
||||
return "Favourite"
|
||||
case RoomTagLowPriority:
|
||||
return "Low priority"
|
||||
case RoomTagServerNotice:
|
||||
return "Server notice"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: type alias
|
||||
type Tag = TagMetadata
|
||||
|
||||
type TagMetadata struct {
|
||||
Order json.Number `json:"order,omitempty"`
|
||||
|
||||
MauDoublePuppetSource string `json:"fi.mau.double_puppet_source,omitempty"`
|
||||
}
|
||||
|
||||
// DirectChatsEventContent represents the content of a m.direct account data event.
|
||||
|
|
@ -43,3 +81,7 @@ type IgnoredUserListEventContent struct {
|
|||
type IgnoredUser struct {
|
||||
// This is an empty object
|
||||
}
|
||||
|
||||
type MarkedUnreadEventContent struct {
|
||||
Unread bool `json:"unread"`
|
||||
}
|
||||
|
|
|
|||
8
vendor/maunium.net/go/mautrix/event/audio.go
generated
vendored
Normal file
8
vendor/maunium.net/go/mautrix/event/audio.go
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package event
|
||||
|
||||
type MSC1767Audio struct {
|
||||
Duration int `json:"duration,omitempty"`
|
||||
Waveform []int `json:"waveform,omitempty"`
|
||||
}
|
||||
|
||||
type MSC3245Voice struct{}
|
||||
18
vendor/maunium.net/go/mautrix/event/beeper.go
generated
vendored
18
vendor/maunium.net/go/mautrix/event/beeper.go
generated
vendored
|
|
@ -32,12 +32,15 @@ const (
|
|||
)
|
||||
|
||||
type BeeperMessageStatusEventContent struct {
|
||||
Network string `json:"network"`
|
||||
Network string `json:"network,omitempty"`
|
||||
RelatesTo RelatesTo `json:"m.relates_to"`
|
||||
Status MessageStatus `json:"status"`
|
||||
Reason MessageStatusReason `json:"reason,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
// Deprecated: clients were showing this to users even though they aren't supposed to.
|
||||
// Use InternalError for error messages that should be included in bug reports, but not shown in the UI.
|
||||
Error string `json:"error,omitempty"`
|
||||
InternalError string `json:"internal_error,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
LastRetry id.EventID `json:"last_retry,omitempty"`
|
||||
|
||||
|
|
@ -85,3 +88,12 @@ type BeeperLinkPreview struct {
|
|||
MatchedURL string `json:"matched_url,omitempty"`
|
||||
ImageEncryption *EncryptedFileInfo `json:"beeper:image:encryption,omitempty"`
|
||||
}
|
||||
|
||||
type BeeperProfileExtra struct {
|
||||
RemoteID string `json:"com.beeper.bridge.remote_id,omitempty"`
|
||||
Identifiers []string `json:"com.beeper.bridge.identifiers,omitempty"`
|
||||
Service string `json:"com.beeper.bridge.service,omitempty"`
|
||||
Network string `json:"com.beeper.bridge.network,omitempty"`
|
||||
IsBridgeBot bool `json:"com.beeper.bridge.is_bridge_bot,omitempty"`
|
||||
IsNetworkBot bool `json:"com.beeper.bridge.is_network_bot,omitempty"`
|
||||
}
|
||||
|
|
|
|||
18
vendor/maunium.net/go/mautrix/event/content.go
generated
vendored
18
vendor/maunium.net/go/mautrix/event/content.go
generated
vendored
|
|
@ -40,6 +40,8 @@ var TypeMap = map[Type]reflect.Type{
|
|||
StateSpaceChild: reflect.TypeOf(SpaceChildEventContent{}),
|
||||
StateInsertionMarker: reflect.TypeOf(InsertionMarkerContent{}),
|
||||
|
||||
StateElementFunctionalMembers: reflect.TypeOf(ElementFunctionalMembersContent{}),
|
||||
|
||||
EventMessage: reflect.TypeOf(MessageEventContent{}),
|
||||
EventSticker: reflect.TypeOf(MessageEventContent{}),
|
||||
EventEncrypted: reflect.TypeOf(EncryptedEventContent{}),
|
||||
|
|
@ -52,6 +54,7 @@ var TypeMap = map[Type]reflect.Type{
|
|||
AccountDataDirectChats: reflect.TypeOf(DirectChatsEventContent{}),
|
||||
AccountDataFullyRead: reflect.TypeOf(FullyReadEventContent{}),
|
||||
AccountDataIgnoredUserList: reflect.TypeOf(IgnoredUserListEventContent{}),
|
||||
AccountDataMarkedUnread: reflect.TypeOf(MarkedUnreadEventContent{}),
|
||||
|
||||
EphemeralEventTyping: reflect.TypeOf(TypingEventContent{}),
|
||||
EphemeralEventReceipt: reflect.TypeOf(ReceiptEventContent{}),
|
||||
|
|
@ -211,6 +214,7 @@ func init() {
|
|||
gob.Register(&BridgeEventContent{})
|
||||
gob.Register(&SpaceChildEventContent{})
|
||||
gob.Register(&SpaceParentEventContent{})
|
||||
gob.Register(&ElementFunctionalMembersContent{})
|
||||
gob.Register(&RoomNameEventContent{})
|
||||
gob.Register(&RoomAvatarEventContent{})
|
||||
gob.Register(&TopicEventContent{})
|
||||
|
|
@ -352,6 +356,13 @@ func (content *Content) AsSpaceParent() *SpaceParentEventContent {
|
|||
}
|
||||
return casted
|
||||
}
|
||||
func (content *Content) AsElementFunctionalMembers() *ElementFunctionalMembersContent {
|
||||
casted, ok := content.Parsed.(*ElementFunctionalMembersContent)
|
||||
if !ok {
|
||||
return &ElementFunctionalMembersContent{}
|
||||
}
|
||||
return casted
|
||||
}
|
||||
func (content *Content) AsMessage() *MessageEventContent {
|
||||
casted, ok := content.Parsed.(*MessageEventContent)
|
||||
if !ok {
|
||||
|
|
@ -408,6 +419,13 @@ func (content *Content) AsIgnoredUserList() *IgnoredUserListEventContent {
|
|||
}
|
||||
return casted
|
||||
}
|
||||
func (content *Content) AsMarkedUnread() *MarkedUnreadEventContent {
|
||||
casted, ok := content.Parsed.(*MarkedUnreadEventContent)
|
||||
if !ok {
|
||||
return &MarkedUnreadEventContent{}
|
||||
}
|
||||
return casted
|
||||
}
|
||||
func (content *Content) AsTyping() *TypingEventContent {
|
||||
casted, ok := content.Parsed.(*TypingEventContent)
|
||||
if !ok {
|
||||
|
|
|
|||
28
vendor/maunium.net/go/mautrix/event/message.go
generated
vendored
28
vendor/maunium.net/go/mautrix/event/message.go
generated
vendored
|
|
@ -8,6 +8,7 @@ package event
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
|
@ -21,6 +22,24 @@ import (
|
|||
// https://spec.matrix.org/v1.2/client-server-api/#mroommessage-msgtypes
|
||||
type MessageType string
|
||||
|
||||
func (mt MessageType) IsText() bool {
|
||||
switch mt {
|
||||
case MsgText, MsgNotice, MsgEmote:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (mt MessageType) IsMedia() bool {
|
||||
switch mt {
|
||||
case MsgImage, MsgVideo, MsgAudio, MsgFile, MessageType(EventSticker.Type):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Msgtypes
|
||||
const (
|
||||
MsgText MessageType = "m.text"
|
||||
|
|
@ -118,6 +137,9 @@ type MessageEventContent struct {
|
|||
BeeperGalleryCaptionHTML string `json:"com.beeper.gallery.caption_html,omitempty"`
|
||||
|
||||
BeeperLinkPreviews []*BeeperLinkPreview `json:"com.beeper.linkpreviews,omitempty"`
|
||||
|
||||
MSC1767Audio *MSC1767Audio `json:"org.matrix.msc1767.audio,omitempty"`
|
||||
MSC3245Voice *MSC3245Voice `json:"org.matrix.msc3245.voice,omitempty"`
|
||||
}
|
||||
|
||||
func (content *MessageEventContent) GetRelatesTo() *RelatesTo {
|
||||
|
|
@ -191,6 +213,12 @@ type Mentions struct {
|
|||
Room bool `json:"room,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Mentions) Add(userID id.UserID) {
|
||||
if userID != "" && !slices.Contains(m.UserIDs, userID) {
|
||||
m.UserIDs = append(m.UserIDs, userID)
|
||||
}
|
||||
}
|
||||
|
||||
type EncryptedFileInfo struct {
|
||||
attachment.EncryptedFile
|
||||
URL id.ContentURIString `json:"url"`
|
||||
|
|
|
|||
46
vendor/maunium.net/go/mautrix/event/powerlevels.go
generated
vendored
46
vendor/maunium.net/go/mautrix/event/powerlevels.go
generated
vendored
|
|
@ -9,6 +9,9 @@ package event
|
|||
import (
|
||||
"sync"
|
||||
|
||||
"go.mau.fi/util/ptr"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
|
|
@ -33,42 +36,23 @@ type PowerLevelsEventContent struct {
|
|||
RedactPtr *int `json:"redact,omitempty"`
|
||||
}
|
||||
|
||||
func copyPtr(ptr *int) *int {
|
||||
if ptr == nil {
|
||||
return nil
|
||||
}
|
||||
val := *ptr
|
||||
return &val
|
||||
}
|
||||
|
||||
func copyMap[Key comparable](m map[Key]int) map[Key]int {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
copied := make(map[Key]int, len(m))
|
||||
for k, v := range m {
|
||||
copied[k] = v
|
||||
}
|
||||
return copied
|
||||
}
|
||||
|
||||
func (pl *PowerLevelsEventContent) Clone() *PowerLevelsEventContent {
|
||||
if pl == nil {
|
||||
return nil
|
||||
}
|
||||
return &PowerLevelsEventContent{
|
||||
Users: copyMap(pl.Users),
|
||||
Users: maps.Clone(pl.Users),
|
||||
UsersDefault: pl.UsersDefault,
|
||||
Events: copyMap(pl.Events),
|
||||
Events: maps.Clone(pl.Events),
|
||||
EventsDefault: pl.EventsDefault,
|
||||
StateDefaultPtr: copyPtr(pl.StateDefaultPtr),
|
||||
StateDefaultPtr: ptr.Clone(pl.StateDefaultPtr),
|
||||
|
||||
Notifications: pl.Notifications.Clone(),
|
||||
|
||||
InvitePtr: copyPtr(pl.InvitePtr),
|
||||
KickPtr: copyPtr(pl.KickPtr),
|
||||
BanPtr: copyPtr(pl.BanPtr),
|
||||
RedactPtr: copyPtr(pl.RedactPtr),
|
||||
InvitePtr: ptr.Clone(pl.InvitePtr),
|
||||
KickPtr: ptr.Clone(pl.KickPtr),
|
||||
BanPtr: ptr.Clone(pl.BanPtr),
|
||||
RedactPtr: ptr.Clone(pl.RedactPtr),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +65,7 @@ func (npl *NotificationPowerLevels) Clone() *NotificationPowerLevels {
|
|||
return nil
|
||||
}
|
||||
return &NotificationPowerLevels{
|
||||
RoomPtr: copyPtr(npl.RoomPtr),
|
||||
RoomPtr: ptr.Clone(npl.RoomPtr),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +80,7 @@ func (pl *PowerLevelsEventContent) Invite() int {
|
|||
if pl.InvitePtr != nil {
|
||||
return *pl.InvitePtr
|
||||
}
|
||||
return 50
|
||||
return 0
|
||||
}
|
||||
|
||||
func (pl *PowerLevelsEventContent) Kick() int {
|
||||
|
|
@ -143,6 +127,9 @@ func (pl *PowerLevelsEventContent) SetUserLevel(userID id.UserID, level int) {
|
|||
if level == pl.UsersDefault {
|
||||
delete(pl.Users, userID)
|
||||
} else {
|
||||
if pl.Users == nil {
|
||||
pl.Users = make(map[id.UserID]int)
|
||||
}
|
||||
pl.Users[userID] = level
|
||||
}
|
||||
}
|
||||
|
|
@ -175,6 +162,9 @@ func (pl *PowerLevelsEventContent) SetEventLevel(eventType Type, level int) {
|
|||
if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) {
|
||||
delete(pl.Events, eventType.String())
|
||||
} else {
|
||||
if pl.Events == nil {
|
||||
pl.Events = make(map[string]int)
|
||||
}
|
||||
pl.Events[eventType.String()] = level
|
||||
}
|
||||
}
|
||||
|
|
|
|||
39
vendor/maunium.net/go/mautrix/event/state.go
generated
vendored
39
vendor/maunium.net/go/mautrix/event/state.go
generated
vendored
|
|
@ -26,8 +26,8 @@ type RoomNameEventContent struct {
|
|||
// RoomAvatarEventContent represents the content of a m.room.avatar state event.
|
||||
// https://spec.matrix.org/v1.2/client-server-api/#mroomavatar
|
||||
type RoomAvatarEventContent struct {
|
||||
URL id.ContentURI `json:"url"`
|
||||
Info *FileInfo `json:"info,omitempty"`
|
||||
URL id.ContentURIString `json:"url"`
|
||||
Info *FileInfo `json:"info,omitempty"`
|
||||
}
|
||||
|
||||
// ServerACLEventContent represents the content of a m.room.server_acl state event.
|
||||
|
|
@ -56,13 +56,29 @@ type Predecessor struct {
|
|||
EventID id.EventID `json:"event_id"`
|
||||
}
|
||||
|
||||
type RoomVersion string
|
||||
|
||||
const (
|
||||
RoomV1 RoomVersion = "1"
|
||||
RoomV2 RoomVersion = "2"
|
||||
RoomV3 RoomVersion = "3"
|
||||
RoomV4 RoomVersion = "4"
|
||||
RoomV5 RoomVersion = "5"
|
||||
RoomV6 RoomVersion = "6"
|
||||
RoomV7 RoomVersion = "7"
|
||||
RoomV8 RoomVersion = "8"
|
||||
RoomV9 RoomVersion = "9"
|
||||
RoomV10 RoomVersion = "10"
|
||||
RoomV11 RoomVersion = "11"
|
||||
)
|
||||
|
||||
// CreateEventContent represents the content of a m.room.create state event.
|
||||
// https://spec.matrix.org/v1.2/client-server-api/#mroomcreate
|
||||
type CreateEventContent struct {
|
||||
Type RoomType `json:"type,omitempty"`
|
||||
Creator id.UserID `json:"creator,omitempty"`
|
||||
Federate bool `json:"m.federate,omitempty"`
|
||||
RoomVersion string `json:"room_version,omitempty"`
|
||||
RoomVersion RoomVersion `json:"room_version,omitempty"`
|
||||
Predecessor *Predecessor `json:"predecessor,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -71,11 +87,12 @@ type CreateEventContent struct {
|
|||
type JoinRule string
|
||||
|
||||
const (
|
||||
JoinRulePublic JoinRule = "public"
|
||||
JoinRuleKnock JoinRule = "knock"
|
||||
JoinRuleInvite JoinRule = "invite"
|
||||
JoinRuleRestricted JoinRule = "restricted"
|
||||
JoinRulePrivate JoinRule = "private"
|
||||
JoinRulePublic JoinRule = "public"
|
||||
JoinRuleKnock JoinRule = "knock"
|
||||
JoinRuleInvite JoinRule = "invite"
|
||||
JoinRuleRestricted JoinRule = "restricted"
|
||||
JoinRuleKnockRestricted JoinRule = "knock_restricted"
|
||||
JoinRulePrivate JoinRule = "private"
|
||||
)
|
||||
|
||||
// JoinRulesEventContent represents the content of a m.room.join_rules state event.
|
||||
|
|
@ -149,6 +166,8 @@ type BridgeEventContent struct {
|
|||
Protocol BridgeInfoSection `json:"protocol"`
|
||||
Network *BridgeInfoSection `json:"network,omitempty"`
|
||||
Channel BridgeInfoSection `json:"channel"`
|
||||
|
||||
BeeperRoomType string `json:"com.beeper.room_type,omitempty"`
|
||||
}
|
||||
|
||||
type SpaceChildEventContent struct {
|
||||
|
|
@ -175,3 +194,7 @@ type InsertionMarkerContent struct {
|
|||
InsertionID id.EventID `json:"org.matrix.msc2716.marker.insertion"`
|
||||
Timestamp int64 `json:"com.beeper.timestamp,omitempty"`
|
||||
}
|
||||
|
||||
type ElementFunctionalMembersContent struct {
|
||||
ServiceMembers []id.UserID `json:"service_members"`
|
||||
}
|
||||
|
|
|
|||
8
vendor/maunium.net/go/mautrix/event/type.go
generated
vendored
8
vendor/maunium.net/go/mautrix/event/type.go
generated
vendored
|
|
@ -112,11 +112,12 @@ func (et *Type) GuessClass() TypeClass {
|
|||
StatePowerLevels.Type, StateRoomName.Type, StateRoomAvatar.Type, StateServerACL.Type, StateTopic.Type,
|
||||
StatePinnedEvents.Type, StateTombstone.Type, StateEncryption.Type, StateBridge.Type, StateHalfShotBridge.Type,
|
||||
StateSpaceParent.Type, StateSpaceChild.Type, StatePolicyRoom.Type, StatePolicyServer.Type, StatePolicyUser.Type,
|
||||
StateInsertionMarker.Type:
|
||||
StateInsertionMarker.Type, StateElementFunctionalMembers.Type:
|
||||
return StateEventType
|
||||
case EphemeralEventReceipt.Type, EphemeralEventTyping.Type, EphemeralEventPresence.Type:
|
||||
return EphemeralEventType
|
||||
case AccountDataDirectChats.Type, AccountDataPushRules.Type, AccountDataRoomTags.Type,
|
||||
AccountDataFullyRead.Type, AccountDataIgnoredUserList.Type, AccountDataMarkedUnread.Type,
|
||||
AccountDataSecretStorageKey.Type, AccountDataSecretStorageDefaultKey.Type,
|
||||
AccountDataCrossSigningMaster.Type, AccountDataCrossSigningSelf.Type, AccountDataCrossSigningUser.Type,
|
||||
AccountDataFullyRead.Type, AccountDataMegolmBackupKey.Type:
|
||||
|
|
@ -193,6 +194,8 @@ var (
|
|||
|
||||
// Deprecated: MSC2716 has been abandoned
|
||||
StateInsertionMarker = Type{"org.matrix.msc2716.marker", StateEventType}
|
||||
|
||||
StateElementFunctionalMembers = Type{"io.element.functional_members", StateEventType}
|
||||
)
|
||||
|
||||
// Message events
|
||||
|
|
@ -238,13 +241,14 @@ var (
|
|||
AccountDataRoomTags = Type{"m.tag", AccountDataEventType}
|
||||
AccountDataFullyRead = Type{"m.fully_read", AccountDataEventType}
|
||||
AccountDataIgnoredUserList = Type{"m.ignored_user_list", AccountDataEventType}
|
||||
AccountDataMarkedUnread = Type{"m.marked_unread", AccountDataEventType}
|
||||
|
||||
AccountDataSecretStorageDefaultKey = Type{"m.secret_storage.default_key", AccountDataEventType}
|
||||
AccountDataSecretStorageKey = Type{"m.secret_storage.key", AccountDataEventType}
|
||||
AccountDataCrossSigningMaster = Type{string(id.SecretXSMaster), AccountDataEventType}
|
||||
AccountDataCrossSigningUser = Type{string(id.SecretXSUserSigning), AccountDataEventType}
|
||||
AccountDataCrossSigningSelf = Type{string(id.SecretXSSelfSigning), AccountDataEventType}
|
||||
AccountDataMegolmBackupKey = Type{"m.megolm_backup.v1", AccountDataEventType}
|
||||
AccountDataMegolmBackupKey = Type{string(id.SecretMegolmBackupV1), AccountDataEventType}
|
||||
)
|
||||
|
||||
// Device-to-device events
|
||||
|
|
|
|||
4
vendor/maunium.net/go/mautrix/event/verification.go
generated
vendored
4
vendor/maunium.net/go/mautrix/event/verification.go
generated
vendored
|
|
@ -220,6 +220,10 @@ const (
|
|||
VerificationCancelCodeAccepted VerificationCancelCode = "m.accepted"
|
||||
VerificationCancelCodeSASMismatch VerificationCancelCode = "m.mismatched_sas"
|
||||
VerificationCancelCodeCommitmentMismatch VerificationCancelCode = "m.mismatched_commitment"
|
||||
|
||||
// Non-spec codes
|
||||
VerificationCancelCodeInternalError VerificationCancelCode = "com.beeper.internal_error"
|
||||
VerificationCancelCodeMasterKeyNotTrusted VerificationCancelCode = "com.beeper.master_key_not_trusted" // the master key is not trusted by this device, but the QR code that was scanned was from a device that doesn't trust the master key
|
||||
)
|
||||
|
||||
// VerificationCancelEventContent represents the content of an
|
||||
|
|
|
|||
6
vendor/maunium.net/go/mautrix/requests.go
generated
vendored
6
vendor/maunium.net/go/mautrix/requests.go
generated
vendored
|
|
@ -118,8 +118,10 @@ type ReqCreateRoom struct {
|
|||
|
||||
PowerLevelOverride *event.PowerLevelsEventContent `json:"power_level_content_override,omitempty"`
|
||||
|
||||
MeowRoomID id.RoomID `json:"fi.mau.room_id,omitempty"`
|
||||
BeeperAutoJoinInvites bool `json:"com.beeper.auto_join_invites,omitempty"`
|
||||
MeowRoomID id.RoomID `json:"fi.mau.room_id,omitempty"`
|
||||
BeeperInitialMembers []id.UserID `json:"com.beeper.initial_members,omitempty"`
|
||||
BeeperAutoJoinInvites bool `json:"com.beeper.auto_join_invites,omitempty"`
|
||||
BeeperLocalRoomID id.RoomID `json:"com.beeper.local_room_id,omitempty"`
|
||||
}
|
||||
|
||||
// ReqRedact is the JSON request for https://spec.matrix.org/v1.2/client-server-api/#put_matrixclientv3roomsroomidredacteventidtxnid
|
||||
|
|
|
|||
2
vendor/maunium.net/go/mautrix/sqlstatestore/v05-mark-encryption-state-resync.go
generated
vendored
2
vendor/maunium.net/go/mautrix/sqlstatestore/v05-mark-encryption-state-resync.go
generated
vendored
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
UpgradeTable.Register(-1, 5, 0, "Mark rooms that need crypto state event resynced", true, func(ctx context.Context, db *dbutil.Database) error {
|
||||
UpgradeTable.Register(-1, 5, 0, "Mark rooms that need crypto state event resynced", dbutil.TxnModeOn, func(ctx context.Context, db *dbutil.Database) error {
|
||||
portalExists, err := db.TableExists(ctx, "portal")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check if portal table exists")
|
||||
|
|
|
|||
19
vendor/maunium.net/go/mautrix/statestore.go
generated
vendored
19
vendor/maunium.net/go/mautrix/statestore.go
generated
vendored
|
|
@ -37,10 +37,18 @@ type StateStore interface {
|
|||
GetRoomJoinedOrInvitedMembers(ctx context.Context, roomID id.RoomID) ([]id.UserID, error)
|
||||
}
|
||||
|
||||
type StateStoreUpdater interface {
|
||||
UpdateState(ctx context.Context, evt *event.Event)
|
||||
}
|
||||
|
||||
func UpdateStateStore(ctx context.Context, store StateStore, evt *event.Event) {
|
||||
if store == nil || evt == nil || evt.StateKey == nil {
|
||||
return
|
||||
}
|
||||
if directUpdater, ok := store.(StateStoreUpdater); ok {
|
||||
directUpdater.UpdateState(ctx, evt)
|
||||
return
|
||||
}
|
||||
// We only care about events without a state key (power levels, encryption) or member events with state key
|
||||
if evt.Type != event.StateMember && evt.GetStateKey() != "" {
|
||||
return
|
||||
|
|
@ -269,3 +277,14 @@ func (store *MemoryStateStore) IsEncrypted(ctx context.Context, roomID id.RoomID
|
|||
cfg, err := store.GetEncryptionEvent(ctx, roomID)
|
||||
return cfg != nil && cfg.Algorithm == id.AlgorithmMegolmV1, err
|
||||
}
|
||||
|
||||
func (store *MemoryStateStore) FindSharedRooms(ctx context.Context, userID id.UserID) (rooms []id.RoomID, err error) {
|
||||
store.membersLock.RLock()
|
||||
defer store.membersLock.RUnlock()
|
||||
for roomID, members := range store.Members {
|
||||
if _, ok := members[userID]; ok {
|
||||
rooms = append(rooms, roomID)
|
||||
}
|
||||
}
|
||||
return rooms, nil
|
||||
}
|
||||
|
|
|
|||
2
vendor/maunium.net/go/mautrix/version.go
generated
vendored
2
vendor/maunium.net/go/mautrix/version.go
generated
vendored
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const Version = "v0.18.1"
|
||||
const Version = "v0.19.0"
|
||||
|
||||
var GoModVersion = ""
|
||||
var Commit = ""
|
||||
|
|
|
|||
12
vendor/maunium.net/go/mautrix/versions.go
generated
vendored
12
vendor/maunium.net/go/mautrix/versions.go
generated
vendored
|
|
@ -19,6 +19,9 @@ type RespVersions struct {
|
|||
}
|
||||
|
||||
func (versions *RespVersions) ContainsFunc(match func(found SpecVersion) bool) bool {
|
||||
if versions == nil {
|
||||
return false
|
||||
}
|
||||
for _, found := range versions.Versions {
|
||||
if match(found) {
|
||||
return true
|
||||
|
|
@ -40,6 +43,9 @@ func (versions *RespVersions) ContainsGreaterOrEqual(version SpecVersion) bool {
|
|||
}
|
||||
|
||||
func (versions *RespVersions) GetLatest() (latest SpecVersion) {
|
||||
if versions == nil {
|
||||
return
|
||||
}
|
||||
for _, ver := range versions.Versions {
|
||||
if ver.GreaterThan(latest) {
|
||||
latest = ver
|
||||
|
|
@ -54,6 +60,7 @@ type UnstableFeature struct {
|
|||
}
|
||||
|
||||
var (
|
||||
FeatureAsyncUploads = UnstableFeature{UnstableFlag: "fi.mau.msc2246.stable", SpecVersion: SpecV17}
|
||||
FeatureAppservicePing = UnstableFeature{UnstableFlag: "fi.mau.msc2659.stable", SpecVersion: SpecV17}
|
||||
|
||||
BeeperFeatureHungry = UnstableFeature{UnstableFlag: "com.beeper.hungry"}
|
||||
|
|
@ -64,6 +71,9 @@ var (
|
|||
)
|
||||
|
||||
func (versions *RespVersions) Supports(feature UnstableFeature) bool {
|
||||
if versions == nil {
|
||||
return false
|
||||
}
|
||||
return versions.UnstableFeatures[feature.UnstableFlag] ||
|
||||
(!feature.SpecVersion.IsEmpty() && versions.ContainsGreaterOrEqual(feature.SpecVersion))
|
||||
}
|
||||
|
|
@ -95,6 +105,8 @@ var (
|
|||
SpecV17 = MustParseSpecVersion("v1.7")
|
||||
SpecV18 = MustParseSpecVersion("v1.8")
|
||||
SpecV19 = MustParseSpecVersion("v1.9")
|
||||
SpecV110 = MustParseSpecVersion("v1.10")
|
||||
SpecV111 = MustParseSpecVersion("v1.11")
|
||||
)
|
||||
|
||||
func (svf SpecVersionFormat) String() string {
|
||||
|
|
|
|||
565
vendor/modernc.org/libc/Makefile
generated
vendored
565
vendor/modernc.org/libc/Makefile
generated
vendored
|
|
@ -9,9 +9,6 @@ SHELL=/bin/bash -o pipefail
|
|||
DIR = /tmp/libc
|
||||
TAR = musl-7ada6dde6f9dc6a2836c3d92c2f762d35fd229e0.tar.gz
|
||||
URL = https://git.musl-libc.org/cgit/musl/snapshot/$(TAR)
|
||||
UCRT_386 = libc_windows_386.go
|
||||
UCRT_AMD64 = libc_windows_amd64.go
|
||||
UCRT_ARM64 = libc_windows_arm64.go
|
||||
|
||||
all: editor
|
||||
golint 2>&1
|
||||
|
|
@ -36,7 +33,7 @@ download:
|
|||
|
||||
edit:
|
||||
@touch log
|
||||
@if [ -f "Session.vim" ]; then novim -S & else novim -p Makefile all_windows_test.go generator.go libc.go libc_windows*.go & fi
|
||||
@if [ -f "Session.vim" ]; then novim -S & else novim -p Makefile go.mod builder.json & fi
|
||||
|
||||
editor:
|
||||
gofmt -l -s -w *.go 2>&1 | tee log-editor
|
||||
|
|
@ -44,566 +41,6 @@ editor:
|
|||
go install -v 2>&1 | tee -a log-editor
|
||||
go build -o /dev/null generator*.go
|
||||
|
||||
ucrt:
|
||||
make ucrt_amd64 ucrt_arm64 ucrt_386
|
||||
go build -v ./... 2>&1 | tee -a log-generate
|
||||
GOOS=darwin go build -v ./... 2>&1 | tee -a log-generate
|
||||
git status
|
||||
|
||||
ucrt_amd64:
|
||||
echo -n > log-generate
|
||||
( ccgo -v4 \
|
||||
--cpp=$(shell which x86_64-w64-mingw32-gcc) \
|
||||
--goos=windows \
|
||||
--goarch=amd64 \
|
||||
--package-name libc \
|
||||
--prefix-external=X \
|
||||
--prefix-field=F \
|
||||
--prefix-static-internal=_ \
|
||||
--prefix-static-none=_ \
|
||||
--prefix-tagged-struct=T \
|
||||
--prefix-tagged-union=T \
|
||||
--prefix-typename=T \
|
||||
--winapi-test panic \
|
||||
--winapi=ctype.h \
|
||||
--winapi=float.h \
|
||||
--winapi=io.h \
|
||||
--winapi=libucrt.c \
|
||||
--winapi=locale.h \
|
||||
--winapi=malloc.h \
|
||||
--winapi=math.h \
|
||||
--winapi=process.h \
|
||||
--winapi=types.h \
|
||||
--winapi=stat.h \
|
||||
--winapi=stdio.h \
|
||||
--winapi=stdlib.h \
|
||||
--winapi=string.h \
|
||||
--winapi=time.h \
|
||||
--winapi=timeb.h \
|
||||
--winapi=wchar.h \
|
||||
--winapi=winbase.h \
|
||||
-build-lines=" " \
|
||||
-eval-all-macros \
|
||||
-hide __acrt_iob_func \
|
||||
-hide __create_locale \
|
||||
-hide __free_locale \
|
||||
-hide __get_current_locale \
|
||||
-hide __iob_func \
|
||||
-hide __lock_fhandle \
|
||||
-hide __sep__ \
|
||||
-hide __updatetlocinfo \
|
||||
-hide __updatetmbcinfo \
|
||||
-hide _beginthread \
|
||||
-hide _beginthreadex \
|
||||
-hide _endthreadex \
|
||||
-hide _errno \
|
||||
-hide _filbuf \
|
||||
-hide _flsbuf \
|
||||
-hide _get_amblksiz \
|
||||
-hide _get_osplatform \
|
||||
-hide _get_osver \
|
||||
-hide _get_output_format \
|
||||
-hide _get_sbh_threshold \
|
||||
-hide _get_winmajor \
|
||||
-hide _get_winminor \
|
||||
-hide _get_winver \
|
||||
-hide _heapadd \
|
||||
-hide _heapset \
|
||||
-hide _heapused \
|
||||
-hide _matherr \
|
||||
-hide _onexit \
|
||||
-hide _set_amblksiz \
|
||||
-hide _set_malloc_crt_max_wait \
|
||||
-hide _set_output_format \
|
||||
-hide _set_sbh_threshold \
|
||||
-hide _strcmpi \
|
||||
-hide _strnset_l \
|
||||
-hide _strset_l \
|
||||
-hide _unlock_fhandle \
|
||||
-hide _wcsncpy_l \
|
||||
-hide _wctime \
|
||||
-hide _wctime_s \
|
||||
-hide _wgetdcwd_nolock \
|
||||
-hide _wgetenv \
|
||||
-hide _wputenv \
|
||||
-hide access \
|
||||
-hide at_quick_exit \
|
||||
-hide atexit \
|
||||
-hide chdir \
|
||||
-hide exit \
|
||||
-hide lldiv \
|
||||
-hide qsort \
|
||||
-hide chmod \
|
||||
-hide chsize \
|
||||
-hide close \
|
||||
-hide creat \
|
||||
-hide cwait \
|
||||
-hide dup \
|
||||
-hide dup2 \
|
||||
-hide eof \
|
||||
-hide execv \
|
||||
-hide execve \
|
||||
-hide execvp \
|
||||
-hide execvpe \
|
||||
-hide fcloseall \
|
||||
-hide fdopen \
|
||||
-hide fgetchar \
|
||||
-hide fgetpos64 \
|
||||
-hide filelength \
|
||||
-hide fileno \
|
||||
-hide flushall \
|
||||
-hide fopen64 \
|
||||
-hide fpreset \
|
||||
-hide fputchar \
|
||||
-hide fsetpos64 \
|
||||
-hide ftime \
|
||||
-hide fwide \
|
||||
-hide getcwd \
|
||||
-hide getpid \
|
||||
-hide getw \
|
||||
-hide isatty \
|
||||
-hide itoa \
|
||||
-hide lltoa \
|
||||
-hide lltow \
|
||||
-hide locking \
|
||||
-hide lseek \
|
||||
-hide lseek64 \
|
||||
-hide ltoa \
|
||||
-hide memccpy \
|
||||
-hide memicmp \
|
||||
-hide mempcpy \
|
||||
-hide mkdir \
|
||||
-hide mkstemp \
|
||||
-hide mktemp \
|
||||
-hide onexit \
|
||||
-hide putenv \
|
||||
-hide putw \
|
||||
-hide read \
|
||||
-hide rmdir \
|
||||
-hide rmtmp \
|
||||
-hide setmode \
|
||||
-hide spawnv \
|
||||
-hide spawnve \
|
||||
-hide spawnvp \
|
||||
-hide spawnvpe \
|
||||
-hide strcasecmp \
|
||||
-hide strcmpi \
|
||||
-hide strdup \
|
||||
-hide stricmp \
|
||||
-hide strlwr \
|
||||
-hide strlwr_l \
|
||||
-hide strncasecmp \
|
||||
-hide strnicmp \
|
||||
-hide strnset \
|
||||
-hide strrev \
|
||||
-hide strset \
|
||||
-hide strtok_r \
|
||||
-hide strupr \
|
||||
-hide swab \
|
||||
-hide tell \
|
||||
-hide tempnam \
|
||||
-hide tzset \
|
||||
-hide ulltoa \
|
||||
-hide ulltow \
|
||||
-hide ultoa \
|
||||
-hide umask \
|
||||
-hide unlink \
|
||||
-hide wcsdup \
|
||||
-hide wcsicmp \
|
||||
-hide wcsicoll \
|
||||
-hide wcslwr \
|
||||
-hide wcsnicmp \
|
||||
-hide wcsnset \
|
||||
-hide wcsrev \
|
||||
-hide wcsset \
|
||||
-hide wcsupr \
|
||||
-hide wmemchr \
|
||||
-hide wmemcmp \
|
||||
-hide wmemcpy \
|
||||
-hide wmemmove \
|
||||
-hide wmempcpy \
|
||||
-hide wmemset \
|
||||
-hide write \
|
||||
-hide wtoll \
|
||||
-ignore-link-errors \
|
||||
-import syscall \
|
||||
-keep-strings \
|
||||
-o $(UCRT_AMD64) \
|
||||
libucrt.c \
|
||||
|| true ) 2>&1 | tee -a log-generate
|
||||
sed -i '/"modernc.org\/libc"/d' $(UCRT_AMD64)
|
||||
sed -i 's/\<libc\>\.//g' $(UCRT_AMD64)
|
||||
GOOS=windows GOARCH=amd64 go build -v ./... 2>&1 | tee -a log-generate
|
||||
|
||||
ucrt_arm64:
|
||||
echo -n > log-generate
|
||||
( ccgo -v4 \
|
||||
--cpp=$(shell which x86_64-w64-mingw32-gcc) \
|
||||
--goos=windows \
|
||||
--goarch=amd64 \
|
||||
--package-name libc \
|
||||
--prefix-external=X \
|
||||
--prefix-field=F \
|
||||
--prefix-static-internal=_ \
|
||||
--prefix-static-none=_ \
|
||||
--prefix-tagged-struct=T \
|
||||
--prefix-tagged-union=T \
|
||||
--prefix-typename=T \
|
||||
--winapi-test panic \
|
||||
--winapi=ctype.h \
|
||||
--winapi=float.h \
|
||||
--winapi=io.h \
|
||||
--winapi=libucrt.c \
|
||||
--winapi=locale.h \
|
||||
--winapi=malloc.h \
|
||||
--winapi=math.h \
|
||||
--winapi=process.h \
|
||||
--winapi=types.h \
|
||||
--winapi=stat.h \
|
||||
--winapi=stdio.h \
|
||||
--winapi=stdlib.h \
|
||||
--winapi=string.h \
|
||||
--winapi=time.h \
|
||||
--winapi=timeb.h \
|
||||
--winapi=wchar.h \
|
||||
--winapi=winbase.h \
|
||||
-build-lines=" " \
|
||||
-eval-all-macros \
|
||||
-hide __acrt_iob_func \
|
||||
-hide _errno \
|
||||
-hide _wgetenv \
|
||||
-hide _wputenv \
|
||||
-hide exit \
|
||||
-hide lldiv \
|
||||
-hide qsort \
|
||||
-hide __sep__ \
|
||||
-hide __create_locale \
|
||||
-hide __free_locale \
|
||||
-hide __get_current_locale \
|
||||
-hide __iob_func \
|
||||
-hide __lock_fhandle \
|
||||
-hide __updatetlocinfo \
|
||||
-hide __updatetmbcinfo \
|
||||
-hide _beginthread \
|
||||
-hide _beginthreadex \
|
||||
-hide _endthreadex \
|
||||
-hide _filbuf \
|
||||
-hide _flsbuf \
|
||||
-hide _get_amblksiz \
|
||||
-hide _get_osplatform \
|
||||
-hide _get_osver \
|
||||
-hide _get_output_format \
|
||||
-hide _get_sbh_threshold \
|
||||
-hide _get_winmajor \
|
||||
-hide _get_winminor \
|
||||
-hide _get_winver \
|
||||
-hide _heapadd \
|
||||
-hide _heapset \
|
||||
-hide _heapused \
|
||||
-hide _matherr \
|
||||
-hide _onexit \
|
||||
-hide _set_amblksiz \
|
||||
-hide _set_malloc_crt_max_wait \
|
||||
-hide _set_output_format \
|
||||
-hide _set_sbh_threshold \
|
||||
-hide _strcmpi \
|
||||
-hide _strnset_l \
|
||||
-hide _strset_l \
|
||||
-hide _unlock_fhandle \
|
||||
-hide _wcsncpy_l \
|
||||
-hide _wctime \
|
||||
-hide _wctime_s \
|
||||
-hide _wgetdcwd_nolock \
|
||||
-hide access \
|
||||
-hide at_quick_exit \
|
||||
-hide atexit \
|
||||
-hide chdir \
|
||||
-hide chmod \
|
||||
-hide chsize \
|
||||
-hide close \
|
||||
-hide creat \
|
||||
-hide cwait \
|
||||
-hide dup \
|
||||
-hide dup2 \
|
||||
-hide eof \
|
||||
-hide execv \
|
||||
-hide execve \
|
||||
-hide execvp \
|
||||
-hide execvpe \
|
||||
-hide fcloseall \
|
||||
-hide fdopen \
|
||||
-hide fgetchar \
|
||||
-hide fgetpos64 \
|
||||
-hide filelength \
|
||||
-hide fileno \
|
||||
-hide flushall \
|
||||
-hide fopen64 \
|
||||
-hide fpreset \
|
||||
-hide fputchar \
|
||||
-hide fsetpos64 \
|
||||
-hide ftime \
|
||||
-hide fwide \
|
||||
-hide getcwd \
|
||||
-hide getpid \
|
||||
-hide getw \
|
||||
-hide isatty \
|
||||
-hide itoa \
|
||||
-hide lltoa \
|
||||
-hide lltow \
|
||||
-hide locking \
|
||||
-hide lseek \
|
||||
-hide lseek64 \
|
||||
-hide ltoa \
|
||||
-hide memccpy \
|
||||
-hide memicmp \
|
||||
-hide mempcpy \
|
||||
-hide mkdir \
|
||||
-hide mkstemp \
|
||||
-hide mktemp \
|
||||
-hide onexit \
|
||||
-hide putenv \
|
||||
-hide putw \
|
||||
-hide read \
|
||||
-hide rmdir \
|
||||
-hide rmtmp \
|
||||
-hide setmode \
|
||||
-hide spawnv \
|
||||
-hide spawnve \
|
||||
-hide spawnvp \
|
||||
-hide spawnvpe \
|
||||
-hide strcasecmp \
|
||||
-hide strcmpi \
|
||||
-hide strdup \
|
||||
-hide stricmp \
|
||||
-hide strlwr \
|
||||
-hide strlwr_l \
|
||||
-hide strncasecmp \
|
||||
-hide strnicmp \
|
||||
-hide strnset \
|
||||
-hide strrev \
|
||||
-hide strset \
|
||||
-hide strtok_r \
|
||||
-hide strupr \
|
||||
-hide swab \
|
||||
-hide tell \
|
||||
-hide tempnam \
|
||||
-hide tzset \
|
||||
-hide ulltoa \
|
||||
-hide ulltow \
|
||||
-hide ultoa \
|
||||
-hide umask \
|
||||
-hide unlink \
|
||||
-hide wcsdup \
|
||||
-hide wcsicmp \
|
||||
-hide wcsicoll \
|
||||
-hide wcslwr \
|
||||
-hide wcsnicmp \
|
||||
-hide wcsnset \
|
||||
-hide wcsrev \
|
||||
-hide wcsset \
|
||||
-hide wcsupr \
|
||||
-hide wmemchr \
|
||||
-hide wmemcmp \
|
||||
-hide wmemcpy \
|
||||
-hide wmemmove \
|
||||
-hide wmempcpy \
|
||||
-hide wmemset \
|
||||
-hide write \
|
||||
-hide wtoll \
|
||||
-ignore-link-errors \
|
||||
-import syscall \
|
||||
-keep-strings \
|
||||
-o $(UCRT_ARM64) \
|
||||
libucrt.c \
|
||||
|| true ) 2>&1 | tee -a log-generate
|
||||
sed -i '/"modernc.org\/libc"/d' $(UCRT_ARM64)
|
||||
sed -i 's/\<libc\>\.//g' $(UCRT_ARM64)
|
||||
GOOS=windows GOARCH=arm64 go build -v ./... 2>&1 | tee -a log-generate
|
||||
|
||||
ucrt_386:
|
||||
echo -n > log-generate
|
||||
( ccgo -v4 \
|
||||
--cpp=$(shell which i686-w64-mingw32-gcc) \
|
||||
--goos=windows \
|
||||
--goarch=386 \
|
||||
--package-name libc \
|
||||
--prefix-external=X \
|
||||
--prefix-field=F \
|
||||
--prefix-static-internal=_ \
|
||||
--prefix-static-none=_ \
|
||||
--prefix-tagged-struct=T \
|
||||
--prefix-tagged-union=T \
|
||||
--prefix-typename=T \
|
||||
--winapi-test panic \
|
||||
--winapi=ctype.h \
|
||||
--winapi=float.h \
|
||||
--winapi=io.h \
|
||||
--winapi=libucrt.c \
|
||||
--winapi=locale.h \
|
||||
--winapi=malloc.h \
|
||||
--winapi=math.h \
|
||||
--winapi=process.h \
|
||||
--winapi=types.h \
|
||||
--winapi=stat.h \
|
||||
--winapi=stdio.h \
|
||||
--winapi=stdlib.h \
|
||||
--winapi=string.h \
|
||||
--winapi=time.h \
|
||||
--winapi=timeb.h \
|
||||
--winapi=wchar.h \
|
||||
--winapi=winbase.h \
|
||||
-build-lines=" " \
|
||||
-eval-all-macros \
|
||||
-hide __acrt_iob_func \
|
||||
-hide _errno \
|
||||
-hide _wgetenv \
|
||||
-hide _wputenv \
|
||||
-hide exit \
|
||||
-hide lldiv \
|
||||
-hide qsort \
|
||||
-hide __sep__ \
|
||||
-hide __create_locale \
|
||||
-hide __free_locale \
|
||||
-hide __get_current_locale \
|
||||
-hide __lock_fhandle \
|
||||
-hide __updatetlocinfo \
|
||||
-hide __updatetmbcinfo \
|
||||
-hide _beginthread \
|
||||
-hide _beginthreadex \
|
||||
-hide _endthreadex \
|
||||
-hide _filbuf \
|
||||
-hide _flsbuf \
|
||||
-hide _get_amblksiz \
|
||||
-hide _get_osplatform \
|
||||
-hide _get_osver \
|
||||
-hide _get_output_format \
|
||||
-hide _get_sbh_threshold \
|
||||
-hide _get_winmajor \
|
||||
-hide _get_winminor \
|
||||
-hide _get_winver \
|
||||
-hide _heapadd \
|
||||
-hide _heapset \
|
||||
-hide _heapused \
|
||||
-hide _matherr \
|
||||
-hide _onexit \
|
||||
-hide _set_amblksiz \
|
||||
-hide _set_malloc_crt_max_wait \
|
||||
-hide _set_output_format \
|
||||
-hide _set_sbh_threshold \
|
||||
-hide _strcmpi \
|
||||
-hide _strnset_l \
|
||||
-hide _strset_l \
|
||||
-hide _unlock_fhandle \
|
||||
-hide _wcsncpy_l \
|
||||
-hide _wctime \
|
||||
-hide _wctime_s \
|
||||
-hide _wgetdcwd_nolock \
|
||||
-hide access \
|
||||
-hide at_quick_exit \
|
||||
-hide atexit \
|
||||
-hide chdir \
|
||||
-hide chmod \
|
||||
-hide chsize \
|
||||
-hide close \
|
||||
-hide creat \
|
||||
-hide cwait \
|
||||
-hide dup \
|
||||
-hide dup2 \
|
||||
-hide eof \
|
||||
-hide execv \
|
||||
-hide execve \
|
||||
-hide execvp \
|
||||
-hide execvpe \
|
||||
-hide fcloseall \
|
||||
-hide fdopen \
|
||||
-hide fgetchar \
|
||||
-hide fgetpos64 \
|
||||
-hide filelength \
|
||||
-hide fileno \
|
||||
-hide flushall \
|
||||
-hide fopen64 \
|
||||
-hide fpreset \
|
||||
-hide fputchar \
|
||||
-hide fsetpos64 \
|
||||
-hide ftime \
|
||||
-hide fwide \
|
||||
-hide getcwd \
|
||||
-hide getpid \
|
||||
-hide getw \
|
||||
-hide isatty \
|
||||
-hide itoa \
|
||||
-hide lltoa \
|
||||
-hide lltow \
|
||||
-hide locking \
|
||||
-hide lseek \
|
||||
-hide lseek64 \
|
||||
-hide ltoa \
|
||||
-hide memccpy \
|
||||
-hide memicmp \
|
||||
-hide mempcpy \
|
||||
-hide mkdir \
|
||||
-hide mkstemp \
|
||||
-hide mktemp \
|
||||
-hide onexit \
|
||||
-hide putenv \
|
||||
-hide putw \
|
||||
-hide read \
|
||||
-hide rmdir \
|
||||
-hide rmtmp \
|
||||
-hide setmode \
|
||||
-hide spawnv \
|
||||
-hide spawnve \
|
||||
-hide spawnvp \
|
||||
-hide spawnvpe \
|
||||
-hide strcasecmp \
|
||||
-hide strcmpi \
|
||||
-hide strdup \
|
||||
-hide stricmp \
|
||||
-hide strlwr \
|
||||
-hide strlwr_l \
|
||||
-hide strncasecmp \
|
||||
-hide strnicmp \
|
||||
-hide strnset \
|
||||
-hide strrev \
|
||||
-hide strset \
|
||||
-hide strtok_r \
|
||||
-hide strupr \
|
||||
-hide swab \
|
||||
-hide tell \
|
||||
-hide tempnam \
|
||||
-hide tzset \
|
||||
-hide ulltoa \
|
||||
-hide ulltow \
|
||||
-hide ultoa \
|
||||
-hide umask \
|
||||
-hide unlink \
|
||||
-hide wcsdup \
|
||||
-hide wcsicmp \
|
||||
-hide wcsicoll \
|
||||
-hide wcslwr \
|
||||
-hide wcsnicmp \
|
||||
-hide wcsnset \
|
||||
-hide wcsrev \
|
||||
-hide wcsset \
|
||||
-hide wcsupr \
|
||||
-hide wmemchr \
|
||||
-hide wmemcmp \
|
||||
-hide wmemcpy \
|
||||
-hide wmemmove \
|
||||
-hide wmempcpy \
|
||||
-hide wmemset \
|
||||
-hide write \
|
||||
-hide wtoll \
|
||||
-ignore-link-errors \
|
||||
-import syscall \
|
||||
-keep-strings \
|
||||
-o $(UCRT_386) \
|
||||
libucrt.c \
|
||||
|| true ) 2>&1 | tee -a log-generate
|
||||
sed -i '/"modernc.org\/libc"/d' $(UCRT_386)
|
||||
sed -i 's/\<libc\>\.//g' $(UCRT_386)
|
||||
GOOS=windows GOARCH=386 go build -v ./... 2>&1 | tee -a log-generate
|
||||
|
||||
generate: download
|
||||
mkdir -p $(DIR) || true
|
||||
rm -rf $(DIR)/*
|
||||
|
|
|
|||
95
vendor/modernc.org/libc/all.go
generated
vendored
95
vendor/modernc.org/libc/all.go
generated
vendored
|
|
@ -1,95 +0,0 @@
|
|||
// Copyright 202 The Libc Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package libc // import "modernc.org/libc"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
heapAlign = 16
|
||||
heapGuard = 16
|
||||
)
|
||||
|
||||
const FALSE = 0
|
||||
const TRUE = 1
|
||||
|
||||
var (
|
||||
pid = fmt.Sprintf("[%v %v] ", os.Getpid(), filepath.Base(os.Args[0]))
|
||||
)
|
||||
|
||||
func origin(skip int) string {
|
||||
pc, fn, fl, _ := runtime.Caller(skip)
|
||||
f := runtime.FuncForPC(pc)
|
||||
var fns string
|
||||
if f != nil {
|
||||
fns = f.Name()
|
||||
if x := strings.LastIndex(fns, "."); x > 0 {
|
||||
fns = fns[x+1:]
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%s:%d:%s", filepath.Base(fn), fl, fns)
|
||||
}
|
||||
|
||||
func trc(s string, args ...interface{}) string { //TODO-
|
||||
switch {
|
||||
case s == "":
|
||||
s = fmt.Sprintf(strings.Repeat("%v ", len(args)), args...)
|
||||
default:
|
||||
s = fmt.Sprintf(s, args...)
|
||||
}
|
||||
r := fmt.Sprintf("%s: TRC %s (%v:)", origin(2), s, origin(3))
|
||||
fmt.Fprintf(os.Stdout, "%s %s\n", pid, r)
|
||||
os.Stdout.Sync()
|
||||
return r
|
||||
}
|
||||
|
||||
func todo(s string, args ...interface{}) string { //TODO-
|
||||
switch {
|
||||
case s == "":
|
||||
s = fmt.Sprintf(strings.Repeat("%v ", len(args)), args...)
|
||||
default:
|
||||
s = fmt.Sprintf(s, args...)
|
||||
}
|
||||
r := fmt.Sprintf("%s %s: TODOTODO %s (%v:)", pid, origin(2), s, origin(3)) //TODOOK
|
||||
if dmesgs {
|
||||
dmesg("%s", r)
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "%s\n", r)
|
||||
fmt.Fprintf(os.Stdout, "%s\n", debug.Stack()) //TODO-
|
||||
os.Stdout.Sync()
|
||||
os.Exit(1)
|
||||
panic("unrechable")
|
||||
}
|
||||
|
||||
type sorter struct {
|
||||
len int
|
||||
base uintptr
|
||||
sz uintptr
|
||||
f func(*TLS, uintptr, uintptr) int32
|
||||
t *TLS
|
||||
}
|
||||
|
||||
func (s *sorter) Len() int { return s.len }
|
||||
|
||||
func (s *sorter) Less(i, j int) bool {
|
||||
return s.f(s.t, s.base+uintptr(i)*s.sz, s.base+uintptr(j)*s.sz) < 0
|
||||
}
|
||||
|
||||
func (s *sorter) Swap(i, j int) {
|
||||
p := s.base + uintptr(i)*s.sz
|
||||
q := s.base + uintptr(j)*s.sz
|
||||
for i := 0; i < int(s.sz); i++ {
|
||||
*(*byte)(unsafe.Pointer(p)), *(*byte)(unsafe.Pointer(q)) = *(*byte)(unsafe.Pointer(q)), *(*byte)(unsafe.Pointer(p))
|
||||
p++
|
||||
q++
|
||||
}
|
||||
}
|
||||
2
vendor/modernc.org/libc/builder.json
generated
vendored
2
vendor/modernc.org/libc/builder.json
generated
vendored
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"autogen": "linux/(amd64|arm64|loong64)",
|
||||
"autoupdate": "",
|
||||
"autoupdate": "linux/amd64",
|
||||
"autotag": "darwin/(amd64|arm64)|freebsd/(amd64|arm64)|linux/(386|amd64|arm|arm64|loong64|ppc64le|riscv64|s390x)|openbsd/(386|amd64|arm64)|windows/(amd64|arm64|386)",
|
||||
"download": [
|
||||
{"re": "linux/(amd64|arm64|loong64)", "files": ["https://git.musl-libc.org/cgit/musl/snapshot/musl-7ada6dde6f9dc6a2836c3d92c2f762d35fd229e0.tar.gz"]}
|
||||
|
|
|
|||
24
vendor/modernc.org/libc/ccgo_linux_loong64.go
generated
vendored
24
vendor/modernc.org/libc/ccgo_linux_loong64.go
generated
vendored
|
|
@ -143,16 +143,14 @@ const WINT_MAX = 4294967295
|
|||
const WINT_MIN = 0
|
||||
const _ABILP64 = 3
|
||||
const _Complex_I = 0
|
||||
const _LOONGARCH_ARCH = "loongarch64"
|
||||
const _LOONGARCH_ARCH_LOONGARCH64 = 1
|
||||
const _LOONGARCH_ARCH = "la64v1.0"
|
||||
const _LOONGARCH_FPSET = 32
|
||||
const _LOONGARCH_SIM = 3
|
||||
const _LOONGARCH_SPFPSET = 32
|
||||
const _LOONGARCH_SZINT = 32
|
||||
const _LOONGARCH_SZLONG = 64
|
||||
const _LOONGARCH_SZPTR = 64
|
||||
const _LOONGARCH_TUNE = "loongarch64"
|
||||
const _LOONGARCH_TUNE_LOONGARCH64 = 1
|
||||
const _LOONGARCH_TUNE = "generic"
|
||||
const _LP64 = 1
|
||||
const _XOPEN_SOURCE = 700
|
||||
const __ACCUM_EPSILON__ = 0
|
||||
|
|
@ -322,9 +320,8 @@ const __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 = 1
|
|||
const __GCC_IEC_559 = 2
|
||||
const __GCC_IEC_559_COMPLEX = 2
|
||||
const __GNUC_EXECUTION_CHARSET_NAME = "UTF-8"
|
||||
const __GNUC_MINOR__ = 0
|
||||
const __GNUC_PATCHLEVEL__ = 1
|
||||
const __GNUC_RH_RELEASE__ = 0
|
||||
const __GNUC_MINOR__ = 1
|
||||
const __GNUC_PATCHLEVEL__ = 0
|
||||
const __GNUC_STDC_INLINE__ = 1
|
||||
const __GNUC_WIDE_EXECUTION_CHARSET_NAME = "UTF-32LE"
|
||||
const __GNUC__ = 14
|
||||
|
|
@ -404,8 +401,6 @@ const __LONG_LONG_WIDTH__ = 64
|
|||
const __LONG_MAX = 9223372036854775807
|
||||
const __LONG_MAX__ = 9223372036854775807
|
||||
const __LONG_WIDTH__ = 64
|
||||
const __LOONGARCH_ARCH_LOONGARCH64 = 1
|
||||
const __LOONGARCH_TUNE_LOONGARCH64 = 1
|
||||
const __LP64__ = 1
|
||||
const __NO_INLINE__ = 1
|
||||
const __ORDER_BIG_ENDIAN__ = 4321
|
||||
|
|
@ -537,7 +532,7 @@ const __UTA_FBIT__ = 64
|
|||
const __UTA_IBIT__ = 64
|
||||
const __UTQ_FBIT__ = 128
|
||||
const __UTQ_IBIT__ = 0
|
||||
const __VERSION__ = "14.0.1 20240411 (Red Hat 14.0.1-0)"
|
||||
const __VERSION__ = "14.1.0 20240507 (Red Hat 14.1.0-1)"
|
||||
const __WCHAR_MAX__ = 2147483647
|
||||
const __WCHAR_MIN__ = -2147483648
|
||||
const __WCHAR_TYPE__ = 0
|
||||
|
|
@ -557,13 +552,18 @@ const __linux = 1
|
|||
const __linux__ = 1
|
||||
const __loongarch64 = 1
|
||||
const __loongarch__ = 1
|
||||
const __loongarch_arch = "loongarch64"
|
||||
const __loongarch_arch = "la64v1.0"
|
||||
const __loongarch_double_float = 1
|
||||
const __loongarch_frlen = 64
|
||||
const __loongarch_grlen = 64
|
||||
const __loongarch_hard_float = 1
|
||||
const __loongarch_lp64 = 1
|
||||
const __loongarch_tune = "loongarch64"
|
||||
const __loongarch_simd = 1
|
||||
const __loongarch_simd_width = 128
|
||||
const __loongarch_sx = 1
|
||||
const __loongarch_tune = "generic"
|
||||
const __loongarch_version_major = 1
|
||||
const __loongarch_version_minor = 0
|
||||
const __restrict = 0
|
||||
const __restrict_arr = 0
|
||||
const __unix = 1
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue