{"record":{"id":"893790f0fedc6d45","repo":"txthinking/brook","slug":"password-is-wrong-893790","errorCode":null,"errorMessage":"Password is wrong","messagePattern":"Password is wrong","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"simplestreamserver.go","lineNumber":54,"sourceCode":"\tdst     string\n}\n\nfunc NewSimpleStreamServer(password []byte, src string, client net.Conn, timeout, udptimeout int) (Exchanger, error) {\n\tif timeout != 0 {\n\t\tif err := client.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Second)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\ts := &SimpleStreamServer{Client: client, Timeout: timeout, src: src}\n\tb := x.BP2048.Get().([]byte)\n\tif _, err := io.ReadFull(s.Client, b[:32+2]); err != nil {\n\t\tx.BP2048.Put(b)\n\t\treturn nil, err\n\t}\n\tif bytes.Compare(password, b[:32]) != 0 {\n\t\tx.BP2048.Put(b)\n\t\tWaitReadErr(s.Client)\n\t\treturn nil, errors.New(\"Password is wrong\")\n\t}\n\tl := int(binary.BigEndian.Uint16(b[32:34]))\n\tif l > 2048 {\n\t\tx.BP2048.Put(b)\n\t\treturn nil, errors.New(\"data too long\")\n\t}\n\tif _, err := io.ReadFull(s.Client, b[:l]); err != nil {\n\t\tx.BP2048.Put(b)\n\t\treturn nil, err\n\t}\n\ti := int64(binary.BigEndian.Uint32(b[:4]))\n\tif time.Now().Unix()-i > 60 {\n\t\tx.BP2048.Put(b)\n\t\tWaitReadErr(s.Client)\n\t\treturn nil, errors.New(\"Expired request\")\n\t}\n\tif i%2 == 0 {\n\t\ts.network = \"tcp\"","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/txthinking/brook/blob/5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8/simplestreamserver.go#L36-L72","documentation":"NewSimpleStreamServer compares the first 32 bytes of the client's handshake against the configured password digest; on mismatch it drains the connection and returns 'Password is wrong'. This is the server-side authentication check for the simple stream protocol.","triggerScenarios":"A client connects (via TCPHandle or HTTP ServeHTTP path) and the first 32 bytes of its handshake payload do not equal the SHA-256 digest of the server's configured password — wrong password, different key material, or garbage/noise bytes from a non-protocol client (port scanner, wrong protocol).","commonSituations":"Client and server configured with different passwords; config deployed out of sync after a password rotation; a scanner or health-checker hits the port sending non-protocol bytes; client hashing the password with a different algorithm/encoding.","solutions":["Verify the client's password exactly matches the server's configured password (no trailing whitespace/newline, same encoding)","Re-sync credentials on both ends after any password rotation and restart both sides","Confirm the client hashes the password the same way (SHA-256 of the raw password bytes) before sending","If receiving random probes, ignore the error or firewall the offending source"],"exampleFix":"// before (client)\nconn.Write([]byte(myPassword))\n// after\nsum := sha256.Sum256(password)\nconn.Write(sum[:])","handlingStrategy":"validation","validationCode":"if string(sentHash) != string(sha256.Sum256([]byte(configuredPassword))[0:32]) {\n    return errors.New(\"client password does not match server configuration\")\n}","typeGuard":null,"tryCatchPattern":"_, err := NewSimpleStreamServer(password, s.Client, ...)\nif err != nil && err.Error() == \"Password is wrong\" {\n    log.Printf(\"auth failure from %s\", s.Client.RemoteAddr())\n    s.Client.Close()\n}","preventionTips":["Keep client and server passwords in sync via shared config/secret store","Strip whitespace and use consistent encoding for passwords","After rotation, restart or hot-reload both ends","Treat repeated failures as probing and rate-limit/firewall the source"],"tags":["authentication","password","network","handshake"],"backgroundTag":"authentication-failed","analyzedSha":"5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8","analyzedAt":"2026-09-06T04:35:00.432Z","contentChangedAt":"2026-09-06T04:35:00.432Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}