-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
noise: add an option to allow unknown peer ID in SecureOutbound #1823
noise: add an option to allow unknown peer ID in SecureOutbound #1823
Conversation
Can we make this a separate function, that has a very clear warning of the risks. Dialing nodes without a peer ID makes you susceptible to MITM attacks, see discussion in libp2p/specs#458. |
@marten-seemann Could you take another look at this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems quite complicated. Have you considered my suggestion of making this a separate method, as I suggested in my last review?
p2p/security/noise/handshake.go
Outdated
// if (s.initiator && s.remoteID != id) || (!s.initiator && s.remoteID != "" && s.remoteID != id) { | ||
// // use Pretty() as it produces the full b58-encoded string, rather than abbreviated forms. | ||
// return nil, fmt.Errorf("peer id mismatch: expected %s, but remote key matches %s", s.remoteID.Pretty(), id.Pretty()) | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No commented code please.
@marten-seemann I considered it but wanted to adhere strictly to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand why SecureOutboundForAnyPeerID
is needed on the Transport
and on the SessionTransport
.
This PR would also need to be rebased, after recent changes to our Noise transport.
039bd70
to
a2913e6
Compare
@marten-seemann I want to keep the interface consistent between |
Sorry for the long response time here, and for changing my mind. I think we should indeed go with an option, implementing this method on both the |
p2p/security/noise/transport.go
Outdated
func (t *Transport) WithSessionOptions(opts ...SessionOption) (sec.SecureTransport, error) { | ||
st := &SessionTransport{t: t} | ||
func (t *Transport) WithSessionOptions(opts ...SessionOption) (*SessionTransport, error) { | ||
st := &SessionTransport{t: t, disablePeerIdCheck: false} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
st := &SessionTransport{t: t, disablePeerIdCheck: false} | |
st := &SessionTransport{t: t} |
|
||
initiatorEarlyDataHandler, responderEarlyDataHandler EarlyDataHandler | ||
} | ||
|
||
// SecureInbound runs the Noise handshake as the responder. | ||
// If p is empty, connections from any peer are accepted. | ||
func (i *SessionTransport) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { | ||
c, err := newSecureSession(i.t, ctx, insecure, p, i.prologue, i.initiatorEarlyDataHandler, i.responderEarlyDataHandler, false) | ||
c, err := newSecureSession(i.t, ctx, insecure, p, i.prologue, i.initiatorEarlyDataHandler, i.responderEarlyDataHandler, false, p != "" || i.disablePeerIdCheck) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ckousik Why are you setting checkPeerID = true
when i.disalbePeerIdCheck
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to keep behaviour consistent with setting an empty string as peer id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not p != "" || !i.disablePeerIDCheck
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a quick test and the correct conditional here was p != "" && !i.disablePeerIDCheck
, since on the inbound call we will only check the peer ID if the ID provided in the argument is not empty, and the ID check is not disabled.
var _ sec.SecureTransport = &SessionTransport{} | ||
|
||
// SessionTransport can be used | ||
// to provide per-connection options | ||
type SessionTransport struct { | ||
t *Transport | ||
// options | ||
prologue []byte | ||
prologue []byte | ||
disablePeerIdCheck bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
disablePeerIdCheck bool | |
disablePeerIDCheck bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks @ckousik!
Allows the
SecureOutbound
call to be called with an unknown peer ID (empty string). This is required for libp2p/specs#412 (comment)