Extremely WIP cross-signing and SSSS support
This commit is contained in:
parent
5312ce28d0
commit
e7c72dcbbf
3
go.mod
3
go.mod
@ -27,3 +27,6 @@ require (
|
||||
maunium.net/go/mauview v0.1.1
|
||||
maunium.net/go/tcell v0.2.0
|
||||
)
|
||||
|
||||
//replace maunium.net/go/mautrix => ../mautrix-go
|
||||
replace maunium.net/go/mautrix => github.com/nikofil/mautrix-go v0.5.2-0.20200911223256-b40ab761fadc
|
||||
|
50
go.sum
50
go.sum
@ -1,28 +1,42 @@
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
|
||||
github.com/alecthomas/chroma v0.8.0 h1:HS+HE97sgcqjQGu5uVr8jIE55Mmh5UeQ7kckAhHg2pY=
|
||||
github.com/alecthomas/chroma v0.8.0/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
|
||||
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
|
||||
github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
|
||||
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts=
|
||||
github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
|
||||
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gabriel-vasile/mimetype v1.1.1 h1:qbN9MPuRf3bstHu9zkI9jDWNfH//9+9kHxr9oRBBBOA=
|
||||
github.com/gabriel-vasile/mimetype v1.1.1/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/kyokomi/emoji v2.2.2+incompatible h1:gaQFbK2+uSxOR4iGZprJAbpmtqTrHhSdgOyIMD6Oidc=
|
||||
github.com/kyokomi/emoji v2.2.2+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA=
|
||||
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
||||
@ -32,20 +46,21 @@ github.com/lithammer/fuzzysearch v1.1.0/go.mod h1:Bqx4wo8lTOFcJr3ckpY6HA9lEIOO0H
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
|
||||
github.com/nikofil/mautrix-go v0.5.2-0.20200911223256-b40ab761fadc h1:Un166sriSTE07vajPm+iv+oHmBIH3b4PW2LO1fhRyKc=
|
||||
github.com/nikofil/mautrix-go v0.5.2-0.20200911223256-b40ab761fadc/go.mod h1:xd0D0ekVts/UDBbjeDSs4wGlBfcarJDg0MMhVgHbxhs=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@ -53,15 +68,12 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y=
|
||||
github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
|
||||
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
@ -74,25 +86,27 @@ github.com/tidwall/sjson v1.1.1 h1:7h1vk049Jnd5EH9NyzNiEuwYW4b5qgreBbqRC19AS3U=
|
||||
github.com/tidwall/sjson v1.1.1/go.mod h1:yvVuSnpEQv5cYIrO+AT6kw4QVfd5SDZoGIS7/5+fZFs=
|
||||
github.com/zyedidia/clipboard v0.0.0-20200421031010-7c45b8673834 h1:0nOfq3JwYRiY3+nwfWVQYEaXDmGCQgj3RKoqTifLzP4=
|
||||
github.com/zyedidia/clipboard v0.0.0-20200421031010-7c45b8673834/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
|
||||
github.com/zyedidia/poller v1.0.1 h1:Tt9S3AxAjXwWGNiC2TUdRJkQDZSzCBNVQ4xXiQ7440s=
|
||||
github.com/zyedidia/poller v1.0.1/go.mod h1:vZXJOHGDcuK08GXhF6IAY0ZFd2WcgOR5DOTp84Uk5eE=
|
||||
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
|
||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -106,19 +120,17 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 h1:MZF6J7CV6s/h0HBkfqebrYfKCVEo5iN+wzE4QhV3Evo=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2/go.mod h1:s1Sn2yZos05Qfs7NKt867Xe18emOmtsO3eAKbDaon0o=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/vansante/go-ffprobe.v2 v2.0.2 h1:DdxSfFnlqeawPIVbIQEI6LR6OQHQNR7tNgWb2mWuC4w=
|
||||
gopkg.in/vansante/go-ffprobe.v2 v2.0.2/go.mod h1:qF0AlAjk7Nqzqf3y333Ly+KxN3cKF2JqA3JT5ZheUGE=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/maulogger/v2 v2.1.1/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/mautrix v0.7.6 h1:jB9oCimPq0mVyolwQBC/9N1fu21AU+Ryq837cLf4gOo=
|
||||
maunium.net/go/mautrix v0.7.6/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=
|
||||
maunium.net/go/mauview v0.1.1 h1:wfTXyPx3LGAGpTskh+UbBv/QItUWnEpaneHmywoYnfY=
|
||||
maunium.net/go/mauview v0.1.1/go.mod h1:3QBUiuLct9moP1LgDhCGIg0Ovxn38Bd2sGndnUOuj4o=
|
||||
maunium.net/go/tcell v0.2.0 h1:1Q0kN3wCOGAIGu1r3QHADsjSUOPDylKREvCv3EzJpVg=
|
||||
|
@ -51,6 +51,7 @@ type MatrixContainer interface {
|
||||
|
||||
Login(user, password string) error
|
||||
Logout()
|
||||
UIAFallback(authType mautrix.AuthType, sessionID string) error
|
||||
|
||||
SendPreferencesToMatrix()
|
||||
PrepareMarkdownMessage(roomID id.RoomID, msgtype event.MessageType, text, html string, relation *Relation) *muksevt.Event
|
||||
|
@ -429,8 +429,8 @@ func (c *Container) Start() {
|
||||
return
|
||||
default:
|
||||
if err := c.client.Sync(); err != nil {
|
||||
if httpErr, ok := err.(mautrix.HTTPError); ok && httpErr.Code == http.StatusUnauthorized {
|
||||
debug.Print("Sync() errored with ", err, " -> logging out")
|
||||
if errors.Is(err, mautrix.MUnknownToken) {
|
||||
debug.Print("Sync() errored with", err, "-> logging out")
|
||||
c.Logout()
|
||||
} else {
|
||||
debug.Print("Sync() errored", err)
|
||||
|
114
matrix/uia-fallback.go
Normal file
114
matrix/uia-fallback.go
Normal file
@ -0,0 +1,114 @@
|
||||
// gomuks - A terminal Matrix client written in Go.
|
||||
// Copyright (C) 2020 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package matrix
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
|
||||
"maunium.net/go/gomuks/debug"
|
||||
"maunium.net/go/gomuks/lib/open"
|
||||
)
|
||||
|
||||
const uiaFallbackPage = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>gomuks user-interactive auth</title>
|
||||
<meta charset="utf-8"/>
|
||||
<style>
|
||||
body {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Please complete the login in the popup window</h2>
|
||||
<button onclick="openPopup()">Open popup</button>
|
||||
<button onclick="finish(false)">Cancel</button>
|
||||
<script>
|
||||
const url = location.hash.substr(1)
|
||||
let popupWindow
|
||||
|
||||
function finish(success) {
|
||||
if (popupWindow) {
|
||||
popupWindow.close()
|
||||
}
|
||||
fetch("", {method: success ? "POST" : "DELETE"}).then(() => window.close())
|
||||
}
|
||||
|
||||
function openPopup() {
|
||||
popupWindow = window.open(url)
|
||||
}
|
||||
|
||||
window.addEventListener("message", evt => evt.data === "authDone" && finish(true))
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
func (c *Container) UIAFallback(loginType mautrix.AuthType, sessionID string) error {
|
||||
errChan := make(chan error, 1)
|
||||
server := &http.Server{Addr: ":29325"}
|
||||
server.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "GET" {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte(uiaFallbackPage))
|
||||
} else if r.Method == "POST" || r.Method == "DELETE" {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
go func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
err := server.Shutdown(ctx)
|
||||
if err != nil {
|
||||
debug.Printf("Failed to shut down SSO server: %v\n", err)
|
||||
}
|
||||
if r.Method == "DELETE" {
|
||||
errChan <- errors.New("login cancelled")
|
||||
} else {
|
||||
errChan <- nil
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
}
|
||||
})
|
||||
go server.ListenAndServe()
|
||||
defer server.Close()
|
||||
authURL := c.client.BuildURLWithQuery(mautrix.URLPath{"auth", loginType, "fallback", "web"}, map[string]string{
|
||||
"session": sessionID,
|
||||
})
|
||||
link := url.URL{
|
||||
Scheme: "http",
|
||||
Host: "localhost:29325",
|
||||
Path: "/",
|
||||
Fragment: authURL,
|
||||
}
|
||||
err := open.Open(link.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = <-errChan
|
||||
return err
|
||||
}
|
@ -104,6 +104,9 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
|
||||
"e": {"edit"},
|
||||
"dl": {"download"},
|
||||
"o": {"open"},
|
||||
"4s": {"ssss"},
|
||||
"s4": {"ssss"},
|
||||
"cs": {"cross-signing"},
|
||||
},
|
||||
autocompleters: map[string]CommandAutocompleter{
|
||||
"devices": autocompleteDevice,
|
||||
@ -172,6 +175,8 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
|
||||
"import": cmdImportKeys,
|
||||
"export": cmdExportKeys,
|
||||
"export-room": cmdExportRoomKeys,
|
||||
"ssss": cmdSSSS,
|
||||
"cross-signing": cmdCrossSigning,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
@ -26,7 +27,10 @@ import (
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
ifc "maunium.net/go/gomuks/interface"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto"
|
||||
"maunium.net/go/mautrix/crypto/ssss"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
@ -243,7 +247,7 @@ func cmdImportKeys(cmd *Command) {
|
||||
cmd.Reply("Failed to read %s: %v", path, err)
|
||||
return
|
||||
}
|
||||
passphrase, ok := cmd.MainView.AskPassword("Key import", false)
|
||||
passphrase, ok := cmd.MainView.AskPassword("Key import", "passphrase", "", false)
|
||||
if !ok {
|
||||
cmd.Reply("Passphrase entry cancelled")
|
||||
return
|
||||
@ -263,7 +267,7 @@ func exportKeys(cmd *Command, sessions []*crypto.InboundGroupSession) {
|
||||
cmd.Reply("Failed to get absolute path: %v", err)
|
||||
return
|
||||
}
|
||||
passphrase, ok := cmd.MainView.AskPassword("Key export", true)
|
||||
passphrase, ok := cmd.MainView.AskPassword("Key export", "passphrase", "", true)
|
||||
if !ok {
|
||||
cmd.Reply("Passphrase entry cancelled")
|
||||
return
|
||||
@ -299,3 +303,341 @@ func cmdExportRoomKeys(cmd *Command) {
|
||||
}
|
||||
exportKeys(cmd, sessions)
|
||||
}
|
||||
|
||||
const ssssHelp = `Usage: /%s <subcommand> [...]
|
||||
|
||||
Subcommands:
|
||||
* status [key ID] - Check the status of your SSSS.
|
||||
* generate [--set-default] - Generate a SSSS key and optionally set it as the default.
|
||||
* set-default <key ID> - Set a SSSS key as the default.`
|
||||
|
||||
func cmdSSSS(cmd *Command) {
|
||||
if len(cmd.Args) == 0 {
|
||||
cmd.Reply(ssssHelp, cmd.OrigCommand)
|
||||
return
|
||||
}
|
||||
|
||||
mach := cmd.Matrix.Crypto().(*crypto.OlmMachine)
|
||||
|
||||
switch strings.ToLower(cmd.Args[0]) {
|
||||
case "status":
|
||||
keyID := ""
|
||||
if len(cmd.Args) > 1 {
|
||||
keyID = cmd.Args[1]
|
||||
}
|
||||
cmdS4Status(cmd, mach, keyID)
|
||||
case "generate":
|
||||
setDefault := len(cmd.Args) > 1 && strings.ToLower(cmd.Args[1]) == "--set-default"
|
||||
cmdS4Generate(cmd, mach, setDefault)
|
||||
case "set-default":
|
||||
if len(cmd.Args) < 2 {
|
||||
cmd.Reply("Usage: /%s set-default <key ID>", cmd.OrigCommand)
|
||||
return
|
||||
}
|
||||
cmdS4SetDefault(cmd, mach, cmd.Args[1])
|
||||
default:
|
||||
cmd.Reply(ssssHelp, cmd.OrigCommand)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdS4Status(cmd *Command, mach *crypto.OlmMachine, keyID string) {
|
||||
var keyData *ssss.KeyMetadata
|
||||
var err error
|
||||
if len(keyID) == 0 {
|
||||
keyID, keyData, err = mach.SSSS.GetDefaultKeyData()
|
||||
} else {
|
||||
keyData, err = mach.SSSS.GetKeyData(keyID)
|
||||
}
|
||||
if errors.Is(err, ssss.ErrNoDefaultKeyAccountDataEvent) {
|
||||
cmd.Reply("SSSS is not set up: no default key set")
|
||||
} else if err != nil {
|
||||
cmd.Reply("Failed to get key data: %v", err)
|
||||
return
|
||||
}
|
||||
hasPassphrase := "no"
|
||||
if keyData.Passphrase != nil {
|
||||
hasPassphrase = fmt.Sprintf("yes (alg=%s,bits=%d,iter=%d)", keyData.Passphrase.Algorithm, keyData.Passphrase.Bits, keyData.Passphrase.Iterations)
|
||||
}
|
||||
algorithm := keyData.Algorithm
|
||||
if algorithm != ssss.AlgorithmAESHMACSHA2 {
|
||||
algorithm += " (not supported!)"
|
||||
}
|
||||
cmd.Reply("Default key is set.\n Key ID: %s\n Has passphrase: %s\n Algorithm: %s", keyID, hasPassphrase, algorithm)
|
||||
}
|
||||
|
||||
func cmdS4Generate(cmd *Command, mach *crypto.OlmMachine, setDefault bool) {
|
||||
passphrase, ok := cmd.MainView.AskPassword("Passphrase", "", "", false)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
key, err := ssss.NewKey(passphrase)
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to generate new key: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = mach.SSSS.SetKeyData(key.ID, key.Metadata)
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to upload key metadata: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO if we start persisting command replies, the recovery key needs to be moved into a popup
|
||||
cmd.Reply("Successfully generated key %s\nRecovery key: %s", key.ID, key.RecoveryKey())
|
||||
|
||||
if setDefault {
|
||||
err = mach.SSSS.SetDefaultKeyID(key.ID)
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to set key as default: %v", err)
|
||||
}
|
||||
} else {
|
||||
cmd.Reply("You can use `/%s set-default %s` to set it as the default", cmd.OrigCommand, key.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdS4SetDefault(cmd *Command, mach *crypto.OlmMachine, keyID string) {
|
||||
_, err := mach.SSSS.GetKeyData(keyID)
|
||||
if err != nil {
|
||||
if errors.Is(err, mautrix.MNotFound) {
|
||||
cmd.Reply("Couldn't find key data on server")
|
||||
} else {
|
||||
cmd.Reply("Failed to fetch key data: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
err = mach.SSSS.SetDefaultKeyID(keyID)
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to set key as default: %v", err)
|
||||
} else {
|
||||
cmd.Reply("Successfully set key %s as default", keyID)
|
||||
}
|
||||
}
|
||||
|
||||
const crossSigningHelp = `Usage: /%s <subcommand> [...]
|
||||
|
||||
Subcommands:
|
||||
* status
|
||||
Check the status of your own cross-signing keys.
|
||||
* generate [--force]
|
||||
Generate and upload new cross-signing keys.
|
||||
This will prompt you to enter your account password.
|
||||
If you already have existing keys, --force is required.
|
||||
* fetch [--save-to-disk]
|
||||
Fetch your cross-signing keys from SSSS and decrypt them.
|
||||
If --save-to-disk is specified, the keys are saved to disk.
|
||||
* upload
|
||||
Upload your cross-signing keys to SSSS.`
|
||||
|
||||
func cmdCrossSigning(cmd *Command) {
|
||||
if len(cmd.Args) == 0 {
|
||||
cmd.Reply(crossSigningHelp, cmd.OrigCommand)
|
||||
return
|
||||
}
|
||||
|
||||
client := cmd.Matrix.Client()
|
||||
mach := cmd.Matrix.Crypto().(*crypto.OlmMachine)
|
||||
|
||||
switch strings.ToLower(cmd.Args[0]) {
|
||||
case "status":
|
||||
cmdCrossSigningStatus(cmd, mach, client)
|
||||
case "generate":
|
||||
force := len(cmd.Args) > 1 && strings.ToLower(cmd.Args[1]) == "--force"
|
||||
cmdCrossSigningGenerate(cmd, cmd.Matrix, mach, client, force)
|
||||
case "fetch":
|
||||
saveToDisk := len(cmd.Args) > 1 && strings.ToLower(cmd.Args[1]) == "--save-to-disk"
|
||||
cmdCrossSigningFetch(cmd, mach, saveToDisk)
|
||||
case "upload":
|
||||
cmdCrossSigningUpload(cmd, mach)
|
||||
default:
|
||||
cmd.Reply(crossSigningHelp, cmd.OrigCommand)
|
||||
}
|
||||
}
|
||||
|
||||
func parseKeyResp(keys *mautrix.RespQueryKeys, userID id.UserID) (id.Ed25519, id.Ed25519, id.Ed25519, bool) {
|
||||
masterKeys, ok := keys.MasterKeys[userID]
|
||||
if !ok {
|
||||
return "", "", "", false
|
||||
}
|
||||
selfSigningKeys, ok := keys.SelfSigningKeys[userID]
|
||||
if !ok {
|
||||
return "", "", "", false
|
||||
}
|
||||
userSigningKeys, ok := keys.UserSigningKeys[userID]
|
||||
if !ok {
|
||||
return masterKeys.FirstKey(), selfSigningKeys.FirstKey(), "", true
|
||||
}
|
||||
return masterKeys.FirstKey(), userSigningKeys.FirstKey(), selfSigningKeys.FirstKey(), true
|
||||
}
|
||||
|
||||
func cmdCrossSigningStatus(cmd *Command, mach *crypto.OlmMachine, client *mautrix.Client) {
|
||||
if mach.CrossSigningKeys != nil {
|
||||
cmd.Reply("Cross-signing is set up and private keys are cached")
|
||||
cmd.Reply("Master key: %s", mach.CrossSigningKeys.MasterKey.PublicKey)
|
||||
cmd.Reply("User signing key: %s", mach.CrossSigningKeys.UserSigningKey.PublicKey)
|
||||
cmd.Reply("Self-signing key: %s", mach.CrossSigningKeys.SelfSigningKey.PublicKey)
|
||||
return
|
||||
}
|
||||
keys, err := client.QueryKeys(&mautrix.ReqQueryKeys{
|
||||
DeviceKeys: mautrix.DeviceKeysRequest{
|
||||
client.UserID: mautrix.DeviceIDList{client.DeviceID},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to query own keys: %v", err)
|
||||
return
|
||||
}
|
||||
masterKey, selfSigningKey, userSigningKey, ok := parseKeyResp(keys, client.UserID)
|
||||
if !ok {
|
||||
cmd.Reply("Didn't find published cross-signing keys")
|
||||
return
|
||||
}
|
||||
cmd.Reply("Cross-signing is set up, but private keys are not cached")
|
||||
cmd.Reply("Master key: %s", masterKey)
|
||||
cmd.Reply("User signing key: %s", userSigningKey)
|
||||
cmd.Reply("Self-signing key: %s", selfSigningKey)
|
||||
}
|
||||
|
||||
func cmdCrossSigningFetch(cmd *Command, mach *crypto.OlmMachine, saveToDisk bool) {
|
||||
key := getSSSS(cmd, mach)
|
||||
if key == nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := mach.FetchCrossSigningKeysFromSSSS(key)
|
||||
if err != nil {
|
||||
cmd.Reply("Error fetching cross-signing keys: %v", err)
|
||||
return
|
||||
}
|
||||
if saveToDisk {
|
||||
cmd.Reply("Saving keys to disk is not yet implemented")
|
||||
}
|
||||
cmd.Reply("Successfully unlocked cross-signing keys")
|
||||
}
|
||||
|
||||
func cmdCrossSigningGenerate(cmd *Command, container ifc.MatrixContainer, mach *crypto.OlmMachine, client *mautrix.Client, force bool) {
|
||||
if !force {
|
||||
keys, err := client.QueryKeys(&mautrix.ReqQueryKeys{
|
||||
DeviceKeys: mautrix.DeviceKeysRequest{
|
||||
client.UserID: mautrix.DeviceIDList{client.DeviceID},
|
||||
},
|
||||
})
|
||||
if err == nil {
|
||||
_, _, _, ok := parseKeyResp(keys, client.UserID)
|
||||
if ok {
|
||||
cmd.Reply("Found existing cross-signing keys. Use `--force` if you want to overwrite them.")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keys, err := mach.GenerateCrossSigningKeys()
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to generate cross-signing keys: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = mach.PublishCrossSigningKeys(keys, func(uia *mautrix.RespUserInteractive) interface{} {
|
||||
if !uia.HasSingleStageFlow(mautrix.AuthTypePassword) {
|
||||
for _, flow := range uia.Flows {
|
||||
if len(flow.Stages) != 1 {
|
||||
return nil
|
||||
}
|
||||
cmd.Reply("Opening browser for authentication")
|
||||
err := container.UIAFallback(flow.Stages[0], uia.Session)
|
||||
if err != nil {
|
||||
cmd.Reply("Authentication failed: %v", err)
|
||||
return nil
|
||||
}
|
||||
return &mautrix.BaseAuthData{
|
||||
Type: flow.Stages[0],
|
||||
Session: uia.Session,
|
||||
}
|
||||
}
|
||||
cmd.Reply("No supported authentication mechanisms found")
|
||||
return nil
|
||||
}
|
||||
password, ok := cmd.MainView.AskPassword("Account password", "", "correct horse battery staple", false)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &mautrix.ReqUIAuthLogin{
|
||||
BaseAuthData: mautrix.BaseAuthData{
|
||||
Type: mautrix.AuthTypePassword,
|
||||
Session: uia.Session,
|
||||
},
|
||||
User: mach.Client.UserID.String(),
|
||||
Password: password,
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to publish cross-signing keys: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
mach.CrossSigningKeys = keys
|
||||
}
|
||||
|
||||
func getSSSS(cmd *Command, mach *crypto.OlmMachine) *ssss.Key {
|
||||
_, keyData, err := mach.SSSS.GetDefaultKeyData()
|
||||
if err != nil {
|
||||
if errors.Is(err, mautrix.MNotFound) {
|
||||
cmd.Reply("SSSS not set up, use `!ssss generate --set-default` first")
|
||||
} else {
|
||||
cmd.Reply("Failed to fetch default SSSS key data: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var key *ssss.Key
|
||||
if keyData.Passphrase != nil && keyData.Passphrase.Algorithm == ssss.PassphraseAlgorithmPBKDF2 {
|
||||
passphrase, ok := cmd.MainView.AskPassword("Passphrase", "", "correct horse battery staple", false)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
key, err = keyData.VerifyPassphrase(passphrase)
|
||||
if errors.Is(err, ssss.ErrIncorrectSSSSKey) {
|
||||
cmd.Reply("Incorrect passphrase")
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
recoveryKey, ok := cmd.MainView.AskPassword("Recovery key", "", "tDAK LMRH PiYE bdzi maCe xLX5 wV6P Nmfd c5mC wLef 15Fs VVSc", false)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
key, err = keyData.VerifyRecoveryKey(recoveryKey)
|
||||
if errors.Is(err, ssss.ErrInvalidRecoveryKey) {
|
||||
cmd.Reply("Malformed recovery key")
|
||||
return nil
|
||||
} else if errors.Is(err, ssss.ErrIncorrectSSSSKey) {
|
||||
cmd.Reply("Incorrect recovery key")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// All the errors should already be handled above, this is just for backup
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to get SSSS key: %v", err)
|
||||
return nil
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func cmdCrossSigningUpload(cmd *Command, mach *crypto.OlmMachine) {
|
||||
if mach.CrossSigningKeys == nil {
|
||||
cmd.Reply("Cross-signing keys not cached, use `!%s generate` first", cmd.OrigCommand)
|
||||
return
|
||||
}
|
||||
|
||||
key := getSSSS(cmd, mach)
|
||||
if key == nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := mach.UploadCrossSigningKeysToSSSS(key, mach.CrossSigningKeys)
|
||||
if err != nil {
|
||||
cmd.Reply("Failed to upload keys to SSSS: %v", err)
|
||||
} else {
|
||||
cmd.Reply("Successfully uploaded cross-signing keys to SSSS")
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,9 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"maunium.net/go/mauview"
|
||||
"maunium.net/go/tcell"
|
||||
)
|
||||
@ -41,13 +44,20 @@ type PasswordModal struct {
|
||||
parent *MainView
|
||||
}
|
||||
|
||||
func (view *MainView) AskPassword(title string, isNew bool) (string, bool) {
|
||||
pwm := NewPasswordModal(view, title, isNew)
|
||||
func (view *MainView) AskPassword(title, thing, placeholder string, isNew bool) (string, bool) {
|
||||
pwm := NewPasswordModal(view, title, thing, placeholder, isNew)
|
||||
view.ShowModal(pwm)
|
||||
view.parent.Render()
|
||||
return pwm.Wait()
|
||||
}
|
||||
|
||||
func NewPasswordModal(parent *MainView, title string, isNew bool) *PasswordModal {
|
||||
func NewPasswordModal(parent *MainView, title, thing, placeholder string, isNew bool) *PasswordModal {
|
||||
if placeholder == "" {
|
||||
placeholder = "correct horse battery staple"
|
||||
}
|
||||
if thing == "" {
|
||||
thing = strings.ToLower(title)
|
||||
}
|
||||
pwm := &PasswordModal{
|
||||
parent: parent,
|
||||
form: mauview.NewForm(),
|
||||
@ -64,13 +74,13 @@ func NewPasswordModal(parent *MainView, title string, isNew bool) *PasswordModal
|
||||
|
||||
pwm.text = mauview.NewTextField()
|
||||
if isNew {
|
||||
pwm.text.SetText("Create a passphrase")
|
||||
pwm.text.SetText(fmt.Sprintf("Create a %s", thing))
|
||||
} else {
|
||||
pwm.text.SetText("Enter the passphrase")
|
||||
pwm.text.SetText(fmt.Sprintf("Enter the %s", thing))
|
||||
}
|
||||
pwm.input = mauview.NewInputField().
|
||||
SetMaskCharacter('*').
|
||||
SetPlaceholder("correct horse battery staple")
|
||||
SetPlaceholder(placeholder)
|
||||
pwm.form.AddComponent(pwm.text, 1, 1, 3, 1)
|
||||
pwm.form.AddFormItem(pwm.input, 1, 2, 3, 1)
|
||||
|
||||
@ -78,10 +88,10 @@ func NewPasswordModal(parent *MainView, title string, isNew bool) *PasswordModal
|
||||
height += 3
|
||||
pwm.confirmInput = mauview.NewInputField().
|
||||
SetMaskCharacter('*').
|
||||
SetPlaceholder("correct horse battery staple").
|
||||
SetPlaceholder(placeholder).
|
||||
SetChangedFunc(pwm.HandleChange)
|
||||
pwm.input.SetChangedFunc(pwm.HandleChange)
|
||||
pwm.confirmText = mauview.NewTextField().SetText("Confirm passphrase")
|
||||
pwm.confirmText = mauview.NewTextField().SetText(fmt.Sprintf("Confirm %s", thing))
|
||||
|
||||
pwm.form.SetRow(3, 1).SetRow(4, 1).SetRow(5, 1)
|
||||
pwm.form.AddComponent(pwm.confirmText, 1, 4, 3, 1)
|
||||
@ -125,9 +135,9 @@ func (pwm *PasswordModal) ClickSubmit() {
|
||||
|
||||
func (pwm *PasswordModal) Wait() (string, bool) {
|
||||
select {
|
||||
case result := <- pwm.outputChan:
|
||||
case result := <-pwm.outputChan:
|
||||
return result, true
|
||||
case <- pwm.cancelChan:
|
||||
case <-pwm.cancelChan:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user