From 8c2b95261675325d906da33cee2de264b9599cc5 Mon Sep 17 00:00:00 2001 From: eyedeekay Date: Fri, 8 Nov 2024 15:01:05 -0500 Subject: [PATCH 1/4] setup auto-assign workflow --- .github/workflows/auto-assign.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/auto-assign.yml diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml new file mode 100644 index 00000000..e527ce03 --- /dev/null +++ b/.github/workflows/auto-assign.yml @@ -0,0 +1,20 @@ +name: Auto Assign +on: + issues: + types: [opened] + pull_request: + types: [opened] +jobs: + run: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: 'Auto-assign issue' + uses: pozil/auto-assign-issue@v1 + with: + repo-token:${{ secrets.GITHUB_TOKEN }} + assignees: eyedeekay + numOfAssignee: 1 + From b36ef65a10619445181e1c5ca12ddc58fe0c096d Mon Sep 17 00:00:00 2001 From: satk0 Date: Mon, 11 Nov 2024 23:04:21 +0100 Subject: [PATCH 2/4] Fix test when data is too small --- lib/common/key_certificate/key_certificate.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/common/key_certificate/key_certificate.go b/lib/common/key_certificate/key_certificate.go index c52089e6..2d987abb 100644 --- a/lib/common/key_certificate/key_certificate.go +++ b/lib/common/key_certificate/key_certificate.go @@ -303,7 +303,6 @@ func NewKeyCertificate(bytes []byte) (key_certificate *KeyCertificate, remainder } if len(bytes) < KEYCERT_MIN_SIZE { err = errors.New("error parsing key certificate: not enough data") - remainder = bytes[KEYCERT_MIN_SIZE:] log.WithError(err).Error("KeyCertificate data too short") } key_certificate = &KeyCertificate{ From f6894e90642ab8124c40198bcc53faf5d8a0fe0a Mon Sep 17 00:00:00 2001 From: satk0 Date: Tue, 12 Nov 2024 23:54:50 +0100 Subject: [PATCH 3/4] Fix PubKeyWithP521 test --- lib/common/key_certificate/key_certificate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/key_certificate/key_certificate_test.go b/lib/common/key_certificate/key_certificate_test.go index 73ca2833..b723abcb 100644 --- a/lib/common/key_certificate/key_certificate_test.go +++ b/lib/common/key_certificate/key_certificate_test.go @@ -123,7 +123,7 @@ func TestConstructSigningPublicKeyWithP521(t *testing.T) { assert := assert.New(t) key_cert, _, err := NewKeyCertificate([]byte{0x05, 0x00, 0x08, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}) - data := make([]byte, 128) + data := make([]byte, 132) spk, err := key_cert.ConstructSigningPublicKey(data) assert.Nil(err, "ConstructSigningPublicKey() with P521 returned err on valid data") From 4ad0f97bfe9a0edf6f1db83e0801c9b4f6710178 Mon Sep 17 00:00:00 2001 From: eyedeekay Date: Sat, 16 Nov 2024 13:15:33 -0500 Subject: [PATCH 4/4] Fail-fast switch for logging Logging, format --- README.md | 15 +++- lib/common/certificate/certificate.go | 56 +++++++------- lib/common/keys_and_cert/keys_and_cert.go | 1 - lib/transport/noise/session.go | 10 +-- lib/util/logger/log.go | 92 +++++++++++++++++++++-- 5 files changed, 131 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index ee8e5f40..0fac9962 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ please keep up with these changes, as they will not be backward compatible and r - [ ] Elligator2 - [ ] HKDF - [ ] HMAC - - [/] Noise subsystem + - [X] Noise subsystem - End-to-End Crypto - [ ] Garlic messages - [ ] ElGamal/AES+SessionTag @@ -94,7 +94,7 @@ please keep up with these changes, as they will not be backward compatible and r - [X] Session Tag ## Verbosity ## -Logging can be enabled and configured using the DEBUG_I2P environment variable. By default, logging is disabled. +Logging can be enabled and configured using the `DEBUG_I2P` environment variable. By default, logging is disabled. There are three available log levels: @@ -113,6 +113,17 @@ export DEBUG_I2P=error If DEBUG_I2P is set to an unrecognized variable, it will fall back to "debug". +## Fast-Fail mode ## + +Fast-Fail mode can be activated by setting `WARNFAIL_I2P` to any non-empty value. When set, every warning or error is Fatal. +It is unsafe for production use, and intended only for debugging and testing purposes. + +```shell +export WARNFAIL_I2P=true +``` + +If `WARNFAIL_I2P` is set and `DEBUG_I2P` is unset, `DEBUG_I2P` will be set to `debug`. + ## Contributing See CONTRIBUTING.md for more information. diff --git a/lib/common/certificate/certificate.go b/lib/common/certificate/certificate.go index d50a85fa..4f7e7e8f 100644 --- a/lib/common/certificate/certificate.go +++ b/lib/common/certificate/certificate.go @@ -212,39 +212,39 @@ func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, er // NewCertificate creates a new Certificate with default NULL type func NewCertificate() *Certificate { - return &Certificate{ - kind: Integer([]byte{CERT_NULL}), - len: Integer([]byte{0}), - payload: make([]byte, 0), - } + return &Certificate{ + kind: Integer([]byte{CERT_NULL}), + len: Integer([]byte{0}), + payload: make([]byte, 0), + } } // NewCertificateWithType creates a new Certificate with specified type and payload func NewCertificateWithType(certType uint8, payload []byte) (*Certificate, error) { - // Validate certificate type - switch certType { - case CERT_NULL, CERT_HASHCASH, CERT_HIDDEN, CERT_SIGNED, CERT_MULTIPLE, CERT_KEY: - // Valid type - default: - return nil, fmt.Errorf("invalid certificate type: %d", certType) - } + // Validate certificate type + switch certType { + case CERT_NULL, CERT_HASHCASH, CERT_HIDDEN, CERT_SIGNED, CERT_MULTIPLE, CERT_KEY: + // Valid type + default: + return nil, fmt.Errorf("invalid certificate type: %d", certType) + } - // For NULL certificates, payload should be empty - if certType == CERT_NULL && len(payload) > 0 { - return nil, errors.New("NULL certificates must have empty payload") - } + // For NULL certificates, payload should be empty + if certType == CERT_NULL && len(payload) > 0 { + return nil, errors.New("NULL certificates must have empty payload") + } length, _ := NewIntegerFromInt(len(payload), 2) - - cert := &Certificate{ - kind: Integer([]byte{certType}), - len: *length, - payload: make([]byte, len(payload)), - } - // Copy payload if present - if len(payload) > 0 { - copy(cert.payload, payload) - } + cert := &Certificate{ + kind: Integer([]byte{certType}), + len: *length, + payload: make([]byte, len(payload)), + } - return cert, nil -} \ No newline at end of file + // Copy payload if present + if len(payload) > 0 { + copy(cert.payload, payload) + } + + return cert, nil +} diff --git a/lib/common/keys_and_cert/keys_and_cert.go b/lib/common/keys_and_cert/keys_and_cert.go index 3f5e4eb9..25e09ce8 100644 --- a/lib/common/keys_and_cert/keys_and_cert.go +++ b/lib/common/keys_and_cert/keys_and_cert.go @@ -165,4 +165,3 @@ func ReadKeysAndCert(data []byte) (keys_and_cert KeysAndCert, remainder []byte, return } - diff --git a/lib/transport/noise/session.go b/lib/transport/noise/session.go index bb5c3f60..990a70d1 100644 --- a/lib/transport/noise/session.go +++ b/lib/transport/noise/session.go @@ -21,11 +21,11 @@ type NoiseSession struct { *sync.Cond *NoiseTransport // The parent transport, which "Dialed" the connection to the peer whith whom we established the session *HandshakeState - RecvQueue *cb.Queue - SendQueue *cb.Queue - VerifyCallback VerifyCallbackFunc - activeCall int32 - Conn net.Conn + RecvQueue *cb.Queue + SendQueue *cb.Queue + VerifyCallback VerifyCallbackFunc + activeCall int32 + Conn net.Conn } // RemoteAddr implements net.Conn diff --git a/lib/util/logger/log.go b/lib/util/logger/log.go index 16f62158..329f966f 100644 --- a/lib/util/logger/log.go +++ b/lib/util/logger/log.go @@ -1,7 +1,7 @@ package logger import ( - "io/ioutil" + "io" "os" "strings" "sync" @@ -10,18 +10,96 @@ import ( ) var ( - log *logrus.Logger - once sync.Once + log *Logger + once sync.Once + failFast string ) +// Logger wraps logrus.Logger and adds the ability to make all warnings fatal +type Logger struct { + *logrus.Logger +} + +// Entry wraps logrus.Entry and enables it to use our Logger +type Entry struct { + Logger + entry *logrus.Entry +} + +// Warn wraps logrus.Warn and logs a fatal error if failFast is set +func (l *Logger) Warn(args ...interface{}) { + warnFatal(args) + l.Logger.Warn(args...) +} + +// Warnf wraps logrus.Warnf and logs a fatal error if failFast is set +func (l *Logger) Warnf(format string, args ...interface{}) { + warnFatalf(format, args...) + l.Logger.Warnf(format, args...) +} + +// Error wraps logrus.Error and logs a fatal error if failFast is set +func (l *Logger) Error(args ...interface{}) { + warnFatal(args) + l.Logger.Error(args...) +} + +// Errorf wraps logrus.Errorf and logs a fatal error if failFast is set +func (l *Logger) Errorf(format string, args ...interface{}) { + warnFatalf(format, args...) + l.Logger.Errorf(format, args...) +} + +// WithField wraps logrus.WithField and returns an Entry +func (l *Logger) WithField(key string, value interface{}) *Entry { + entry := l.Logger.WithField(key, value) + return &Entry{*l, entry} +} + +// WithFields wraps logrus.WithFields and returns an Entry +func (l *Logger) WithFields(fields logrus.Fields) *Entry { + entry := l.Logger.WithFields(fields) + return &Entry{*l, entry} +} + +// WithError wraps logrus.WithError and returns an Entry +func (l *Logger) WithError(err error) *Entry { + entry := l.Logger.WithError(err) + return &Entry{*l, entry} +} + +func warnFatal(args ...interface{}) { + if failFast != "" { + log.Fatal(args) + } +} + +func warnFatalf(format string, args ...interface{}) { + if failFast != "" { + log.Fatalf(format, args...) + } +} + +func warnFail() { + if failFast != "" { + log.Error("FATAL ERROR") + } +} + +// InitializeGoI2PLogger sets up all the necessary logging func InitializeGoI2PLogger() { once.Do(func() { - log = logrus.New() + log = &Logger{} + log.Logger = logrus.New() // We do not want to log by default - log.SetOutput(ioutil.Discard) + log.SetOutput(io.Discard) log.SetLevel(logrus.PanicLevel) // Check if DEBUG_I2P is set if logLevel := os.Getenv("DEBUG_I2P"); logLevel != "" { + failFast = os.Getenv("WARNFAIL_I2P") + if failFast != "" && logLevel == "" { + logLevel = "debug" + } log.SetOutput(os.Stdout) switch strings.ToLower(logLevel) { case "debug": @@ -38,8 +116,8 @@ func InitializeGoI2PLogger() { }) } -// GetGoI2PLogger returns the initialized logger -func GetGoI2PLogger() *logrus.Logger { +// GetGoI2PLogger returns the initialized Logger +func GetGoI2PLogger() *Logger { if log == nil { InitializeGoI2PLogger() }