@@ -91,6 +91,22 @@ const COMMANDS: {[command: string]: Command|Heading} = {
9191 example : `!username [irc.example.net] username` ,
9292 summary : "Store a username to use for future connections." ,
9393 } ,
94+ "!storecert" : {
95+ example : `!storecert irc.example.net] -----BEGIN CERTIFICATE-----[...]` ,
96+ summary : `Store a SASL certificate for CertFP` ,
97+ } ,
98+ "!storekey" : {
99+ example : `!storekey [irc.example.net] -----BEGIN PRIVATE KEY-----[...]` ,
100+ summary : `Store a SASL private key for CertFP` ,
101+ } ,
102+ "!removecert" : {
103+ example : `!removecert [irc.example.net]` ,
104+ summary : `Remove a previously stored SASL certificate` ,
105+ } ,
106+ "!removekey" : {
107+ example : `!removekey [irc.example.net]` ,
108+ summary : `Remove a previously stored SASL private key` ,
109+ } ,
94110 'Info' : { heading : true } ,
95111 "!bridgeversion" : {
96112 example : `!bridgeversion` ,
@@ -176,6 +192,14 @@ export class AdminRoomHandler {
176192 return await this . handleStorePass ( req , args , event . sender ) ;
177193 case "!removepass" :
178194 return await this . handleRemovePass ( args , event . sender ) ;
195+ case "!storekey" :
196+ return await this . handleStoreKey ( req , args , event . sender ) ;
197+ case "!storecert" :
198+ return await this . handleStoreCert ( req , args , event . sender ) ;
199+ case "!removekey" :
200+ return await this . handleRemoveKey ( args , event . sender ) ;
201+ case "!removecert" :
202+ return await this . handleRemoveCert ( args , event . sender ) ;
179203 case "!listrooms" :
180204 return await this . handleListRooms ( args , event . sender ) ;
181205 case "!quit" :
@@ -469,7 +493,7 @@ export class AdminRoomHandler {
469493 let notice ;
470494
471495 try {
472- // Allow passwords with spaces
496+ // Allow usernames with spaces
473497 const username = args [ 0 ] ?. trim ( ) ;
474498 if ( ! username ) {
475499 notice = new MatrixAction (
@@ -563,6 +587,103 @@ export class AdminRoomHandler {
563587 }
564588 }
565589
590+ private async handleStoreKey ( req : BridgeRequest , args : string [ ] , userId : string ) {
591+ const server = this . extractServerFromArgs ( args ) ;
592+ const domain = server . domain ;
593+ let notice ;
594+
595+ try {
596+ const key = args . join ( ' ' ) . replace ( / ( - - - - - ( [ A - Z ] * ) - - - - - ) \s * / g, '\n$1\n' ) . trim ( ) . replace ( '\n\n' , '\n' ) ;
597+ if ( key . length === 0 ) {
598+ notice = new MatrixAction (
599+ "notice" ,
600+ "Format: '!storekey key' or '!storepass irc.server.name key'\n"
601+ ) ;
602+ }
603+ else {
604+ await this . ircBridge . getStore ( ) . storeKey ( userId , domain , key ) ;
605+ notice = new MatrixAction (
606+ "notice" , `Successfully stored SASL key for ${ domain } . Use !reconnect to reauthenticate.`
607+ ) ;
608+ }
609+ }
610+ catch ( err ) {
611+ req . log . error ( err . stack ) ;
612+ return new MatrixAction (
613+ "notice" , `Failed to store SASL key: ${ err . message } `
614+ ) ;
615+ }
616+ return notice ;
617+ }
618+
619+ private async handleRemoveKey ( args : string [ ] , userId : string ) {
620+ const server = this . extractServerFromArgs ( args ) ;
621+
622+ try {
623+ await this . ircBridge . getStore ( ) . removeKey ( userId , server . domain ) ;
624+ return new MatrixAction (
625+ "notice" , `Successfully removed SASL key.`
626+ ) ;
627+ }
628+ catch ( err ) {
629+ return new MatrixAction (
630+ "notice" , `Failed to remove SASL key: ${ err . message } `
631+ ) ;
632+ }
633+ }
634+
635+ private async handleStoreCert ( req : BridgeRequest , args : string [ ] , userId : string ) {
636+ const server = this . extractServerFromArgs ( args ) ;
637+ const domain = server . domain ;
638+ let notice ;
639+
640+ try {
641+ const cert = args . join ( ' ' ) . replace ( / ( - - - - - ( [ A - Z ] * ) - - - - - ) \s * / g, '\n$1\n' ) . trim ( ) . replace ( '\n\n' , '\n' ) ;
642+ if ( cert . length === 0 ) {
643+ notice = new MatrixAction (
644+ "notice" ,
645+ "Format: '!storecert cert' or '!storecert irc.server.name cert'\n"
646+ ) ;
647+ }
648+ else {
649+ let config = await this . ircBridge . getStore ( ) . getIrcClientConfig ( userId , server . domain ) ;
650+ if ( ! config ) {
651+ config = IrcClientConfig . newConfig (
652+ new MatrixUser ( userId ) , server . domain
653+ ) ;
654+ }
655+ config . setSASLCert ( cert ) ;
656+ await this . ircBridge . getStore ( ) . storeIrcClientConfig ( config ) ;
657+ notice = new MatrixAction (
658+ "notice" , `Successfully stored SASL cert for ${ domain } . Use !reconnect to reauthenticate.`
659+ ) ;
660+ }
661+ }
662+ catch ( err ) {
663+ req . log . error ( err . stack ) ;
664+ return new MatrixAction (
665+ "notice" , `Failed to store SASL cert: ${ err . message } `
666+ ) ;
667+ }
668+ return notice ;
669+ }
670+
671+ private async handleRemoveCert ( args : string [ ] , userId : string ) {
672+ const server = this . extractServerFromArgs ( args ) ;
673+
674+ try {
675+ await this . ircBridge . getStore ( ) . removeCert ( userId , server . domain ) ;
676+ return new MatrixAction (
677+ "notice" , `Successfully removed SASL cert.`
678+ ) ;
679+ }
680+ catch ( err ) {
681+ return new MatrixAction (
682+ "notice" , `Failed to remove SASL cert: ${ err . message } `
683+ ) ;
684+ }
685+ }
686+
566687 private async handleListRooms ( args : string [ ] , sender : string ) {
567688 const server = this . extractServerFromArgs ( args ) ;
568689
0 commit comments