@@ -10,6 +10,7 @@ import (
1010 "time"
1111
1212 "github.com/btcsuite/btcd/btcec/v2"
13+ "github.com/btcsuite/btcd/btcec/v2/ecdsa"
1314 "github.com/lightninglabs/lightning-node-connect/mailbox"
1415 "github.com/lightninglabs/lightning-terminal/accounts"
1516 "github.com/lightninglabs/lightning-terminal/autopilotserver"
@@ -1008,14 +1009,50 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context,
10081009 caveats = append (caveats , firewall .MetaPrivacyCaveat )
10091010 }
10101011
1012+ // If a previous session ID has been set to link this new one to, we
1013+ // first check if we have the referenced session, and we make sure it
1014+ // has been revoked.
1015+ var prevSess * session.Session
1016+ if len (req .PrevLocalPub ) != 0 {
1017+ prevPub , err := btcec .ParsePubKey (req .PrevLocalPub )
1018+ if err != nil {
1019+ return nil , err
1020+ }
1021+
1022+ prevSess , err = s .db .GetSession (prevPub )
1023+ if errors .Is (err , session .ErrSessionNotFound ) {
1024+ return nil , fmt .Errorf ("linked session(%x) not found" ,
1025+ req .PrevLocalPub )
1026+ } else if err != nil {
1027+ return nil , err
1028+ }
1029+
1030+ if prevSess .State != session .StateRevoked &&
1031+ prevSess .State != session .StateExpired {
1032+
1033+ return nil , fmt .Errorf ("linked session(%x) still " +
1034+ "active" , req .PrevLocalPub )
1035+ }
1036+ }
1037+
10111038 sess , err := session .NewSession (
10121039 req .Label , session .TypeAutopilot , expiry , req .MailboxServerAddr ,
1013- req .DevServer , perms , caveats , featureConfig , privacy , nil ,
1040+ req .DevServer , perms , caveats , featureConfig , privacy , prevSess ,
10141041 )
10151042 if err != nil {
10161043 return nil , fmt .Errorf ("error creating new session: %v" , err )
10171044 }
10181045
1046+ // If this session is being linked to a previous one, then we need to
1047+ // use the previous session's local private key to sign the new
1048+ // session's public key in order to prove to the Autopilot server that
1049+ // the two session's belong to the same owner.
1050+ var linkSig []byte
1051+ if prevSess != nil {
1052+ msg := sess .LocalPublicKey .SerializeCompressed ()
1053+ linkSig = ecdsa .Sign (prevSess .LocalPrivateKey , msg ).Serialize ()
1054+ }
1055+
10191056 // Ensure that the session ID to group ID index is updated with the
10201057 // new pair before storing the session or writing any values to the
10211058 // privacy mapper.
@@ -1025,7 +1062,7 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context,
10251062 }
10261063
10271064 // Register all the privacy map pairs for this session ID.
1028- privDB := s .cfg .privMap (sess .ID )
1065+ privDB := s .cfg .privMap (sess .GroupID )
10291066 err = privDB .Update (func (tx firewalldb.PrivacyMapTx ) error {
10301067 for r , p := range privacyMapPairs {
10311068 err := tx .NewPair (r , p )
@@ -1042,7 +1079,7 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context,
10421079 // Attempt to register the session with the Autopilot server.
10431080 remoteKey , err := s .cfg .autopilot .RegisterSession (
10441081 ctx , sess .LocalPublicKey , sess .ServerAddr , sess .DevServer ,
1045- featureConfig , nil , nil ,
1082+ featureConfig , sess . PrevLocalPub , linkSig ,
10461083 )
10471084 if err != nil {
10481085 return nil , fmt .Errorf ("error registering session with " +
0 commit comments