Skip to content

Commit 1918fbf

Browse files
committed
multi: allow client to link autopilot sessions
1 parent 6086086 commit 1918fbf

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

cmd/litcli/autopilot.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ var addAutopilotSessionCmd = cli.Command{
6565
"perform actions on. In the " +
6666
"form of: peerID1,peerID2,...",
6767
},
68+
cli.StringFlag{
69+
Name: "prev-local-pub",
70+
Usage: "The local pubkey of a previous session to " +
71+
"link this one to",
72+
},
6873
},
6974
}
7075

@@ -224,13 +229,24 @@ func initAutopilotSession(ctx *cli.Context) error {
224229
}
225230
}
226231

232+
var prevLocalPub []byte
233+
if ctx.IsSet("prev-local-pub") {
234+
prevLocalPub, err = hex.DecodeString(
235+
ctx.String("prev-local-pub"),
236+
)
237+
if err != nil {
238+
return err
239+
}
240+
}
241+
227242
resp, err := client.AddAutopilotSession(
228243
ctxb, &litrpc.AddAutopilotSessionRequest{
229244
Label: ctx.String("label"),
230245
ExpiryTimestampSeconds: uint64(sessionExpiry),
231246
MailboxServerAddr: ctx.String("mailboxserveraddr"),
232247
DevServer: ctx.Bool("devserver"),
233248
Features: featureMap,
249+
PrevLocalPub: prevLocalPub,
234250
},
235251
)
236252
if err != nil {

session_rpcserver.go

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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,73 @@ 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.PrevLocalPub) != 0 {
1006+
prevPub, err := btcec.ParsePubKey(req.PrevLocalPub)
1007+
if err != nil {
1008+
return nil, err
1009+
}
1010+
1011+
// Make sure that the previous session does actually exist.
1012+
prevSess, err = s.cfg.db.GetSession(prevPub)
1013+
if errors.Is(err, session.ErrSessionNotFound) {
1014+
return nil, fmt.Errorf("linked session(%x) not found",
1015+
req.PrevLocalPub)
1016+
} else if err != nil {
1017+
return nil, err
1018+
}
1019+
1020+
// Now we need to check that all the other sessions in the
1021+
// linked group are no longer active.
1022+
1023+
// First we use the session ID index to get the set of session
1024+
// IDs in this group.
1025+
prevSessionIDs, err := s.cfg.db.GetSessionIDs(
1026+
prevSess.GroupID,
1027+
)
1028+
if err != nil {
1029+
return nil, err
1030+
}
1031+
1032+
// Now, check that they are all revoked or expired.
1033+
for _, id := range prevSessionIDs {
1034+
prevSess, err := s.cfg.db.GetSessionByID(id)
1035+
if err != nil {
1036+
return nil, err
1037+
}
1038+
1039+
if prevSess.State != session.StateRevoked &&
1040+
prevSess.State != session.StateExpired {
1041+
1042+
return nil, fmt.Errorf("linked session(%x) "+
1043+
"still active", req.PrevLocalPub)
1044+
}
1045+
}
1046+
}
1047+
10001048
sess, err := session.NewSession(
10011049
req.Label, session.TypeAutopilot, expiry, req.MailboxServerAddr,
1002-
req.DevServer, perms, caveats, featureConfig, privacy, nil,
1050+
req.DevServer, perms, caveats, featureConfig, privacy, prevSess,
10031051
)
10041052
if err != nil {
10051053
return nil, fmt.Errorf("error creating new session: %v", err)
10061054
}
10071055

1056+
// If this session is being linked to a previous one, then we need to
1057+
// use the previous session's local private key to sign the new
1058+
// session's public key in order to prove to the Autopilot server that
1059+
// the two session's belong to the same owner.
1060+
var linkSig []byte
1061+
if prevSess != nil {
1062+
msg := sess.LocalPublicKey.SerializeCompressed()
1063+
linkSig = ecdsa.Sign(prevSess.LocalPrivateKey, msg).Serialize()
1064+
}
1065+
10081066
// Register all the privacy map pairs for this session ID.
1009-
privDB := s.cfg.privMap(sess.ID)
1067+
privDB := s.cfg.privMap(sess.GroupID)
10101068
err = privDB.Update(func(tx firewalldb.PrivacyMapTx) error {
10111069
for r, p := range privacyMapPairs {
10121070
err := tx.NewPair(r, p)
@@ -1023,7 +1081,7 @@ func (s *sessionRpcServer) AddAutopilotSession(ctx context.Context,
10231081
// Attempt to register the session with the Autopilot server.
10241082
remoteKey, err := s.cfg.autopilot.RegisterSession(
10251083
ctx, sess.LocalPublicKey, sess.ServerAddr, sess.DevServer,
1026-
featureConfig, nil, nil,
1084+
featureConfig, sess.PrevLocalPub, linkSig,
10271085
)
10281086
if err != nil {
10291087
return nil, fmt.Errorf("error registering session with "+

0 commit comments

Comments
 (0)