@@ -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"
@@ -997,16 +998,53 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context,
997998 caveats = append (caveats , firewall .MetaPrivacyCaveat )
998999 }
9991000
1001+ // If a previous session ID has been set to link this new one to, we
1002+ // first check if we have the referenced session, and we make sure it
1003+ // has been revoked.
1004+ var prevSess * session.Session
1005+ if len (req .PrevSessId ) != 0 {
1006+ var prevSessID session.ID
1007+ copy (prevSessID [:], req .PrevSessId )
1008+
1009+ // Make sure that the previous session does actually exist.
1010+ prevSess , err = s .cfg .db .GetSessionByID (prevSessID )
1011+ if errors .Is (err , session .ErrSessionNotFound ) {
1012+ return nil , fmt .Errorf ("linked session(%x) not found" ,
1013+ req .PrevSessId )
1014+ } else if err != nil {
1015+ return nil , err
1016+ }
1017+
1018+ // Now we need to check that the linked session is no longer
1019+ // active.
1020+ if prevSess .State != session .StateRevoked &&
1021+ prevSess .State != session .StateExpired {
1022+
1023+ return nil , fmt .Errorf ("linked session(%x) " +
1024+ "still active" , req .PrevSessId )
1025+ }
1026+ }
1027+
10001028 sess , err := session .NewSession (
10011029 req .Label , session .TypeAutopilot , expiry , req .MailboxServerAddr ,
1002- req .DevServer , perms , caveats , featureConfig , privacy , nil ,
1030+ req .DevServer , perms , caveats , featureConfig , privacy , prevSess ,
10031031 )
10041032 if err != nil {
10051033 return nil , fmt .Errorf ("error creating new session: %v" , err )
10061034 }
10071035
1036+ // If this session is being linked to a previous one, then we need to
1037+ // use the previous session's local private key to sign the new
1038+ // session's public key in order to prove to the Autopilot server that
1039+ // the two session's belong to the same owner.
1040+ var linkSig []byte
1041+ if prevSess != nil {
1042+ msg := sess .LocalPublicKey .SerializeCompressed ()
1043+ linkSig = ecdsa .Sign (prevSess .LocalPrivateKey , msg ).Serialize ()
1044+ }
1045+
10081046 // Register all the privacy map pairs for this session ID.
1009- privDB := s .cfg .privMap (sess .ID )
1047+ privDB := s .cfg .privMap (sess .GroupID )
10101048 err = privDB .Update (func (tx firewalldb.PrivacyMapTx ) error {
10111049 for r , p := range privacyMapPairs {
10121050 err := tx .NewPair (r , p )
@@ -1023,7 +1061,7 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context,
10231061 // Attempt to register the session with the Autopilot server.
10241062 remoteKey , err := s .cfg .autopilot .RegisterSession (
10251063 ctx , sess .LocalPublicKey , sess .ServerAddr , sess .DevServer ,
1026- featureConfig , nil , nil ,
1064+ featureConfig , sess . LocalPublicKey , linkSig ,
10271065 )
10281066 if err != nil {
10291067 return nil , fmt .Errorf ("error registering session with " +
0 commit comments