Package: release.debian.org Severity: normal Tags: stretch User: release.debian.org@packages.debian.org Usertags: pu Dear stable release managers, I've prepared a fix for CVE-2017-14623, Debian BTS #876404. The security team does not intend to publish a DSA for this minor issue, so I'm asking here if you would accept an upload for stable-proposed-updates. The source debdiff is attached. Please tell me if I should upload the package or if you need further changes. Regards, Tobias
diff -Nru golang-github-go-ldap-ldap-2.4.1/debian/changelog golang-github-go-ldap-ldap-2.4.1/debian/changelog --- golang-github-go-ldap-ldap-2.4.1/debian/changelog 2016-08-16 18:19:35.000000000 +0200 +++ golang-github-go-ldap-ldap-2.4.1/debian/changelog 2017-11-29 23:45:26.000000000 +0100 @@ -1,3 +1,17 @@ +golang-github-go-ldap-ldap (2.4.1-1+deb9u1) stretch; urgency=medium + + * Team upload. + * Require explicit intention for empty password. + This is normally used for unauthenticated bind, and + https://tools.ietf.org/html/rfc4513#section-5.1.2 recommends: + "Clients SHOULD disallow an empty password input to a Name/Password + Authentication user interface" + This is (mostly) a cherry-pick of 95ede12 from upstream, except + the bit in ldap_test.go, which is unrelated to the security issue. + This fixes CVE-2017-14623. (Closes: #876404) + + -- Dr. Tobias Quathamer <toddy@debian.org> Wed, 29 Nov 2017 23:45:26 +0100 + golang-github-go-ldap-ldap (2.4.1-1) unstable; urgency=medium * New upstream version. diff -Nru golang-github-go-ldap-ldap-2.4.1/debian/patches/0002-Require-explicit-intention-for-empty-password.patch golang-github-go-ldap-ldap-2.4.1/debian/patches/0002-Require-explicit-intention-for-empty-password.patch --- golang-github-go-ldap-ldap-2.4.1/debian/patches/0002-Require-explicit-intention-for-empty-password.patch 1970-01-01 01:00:00.000000000 +0100 +++ golang-github-go-ldap-ldap-2.4.1/debian/patches/0002-Require-explicit-intention-for-empty-password.patch 2017-11-29 23:02:18.000000000 +0100 @@ -0,0 +1,170 @@ +From: "Dr. Tobias Quathamer" <toddy@debian.org> +Date: Wed, 29 Nov 2017 14:34:16 +0100 +Subject: Require explicit intention for empty password. + +This is normally used for unauthenticated bind, and +https://tools.ietf.org/html/rfc4513#section-5.1.2 recommends: + +> Clients SHOULD disallow an empty password input to a Name/Password +> Authentication user interface + +This is (mostly) a cherry-pick of 95ede12 from upstream. I've removed +the bit in ldap_test.go, which is unrelated to the security issue. + +This fixes CVE-2017-14623. + +https://github.com/go-ldap/ldap/commit/95ede1266b237bf8e9aa5dce0b3250e51bfefe66 +--- + bind.go | 80 ++++++++++++++++++++++++++++-------------------------------- + error.go | 9 +++++++ + ldap_test.go | 64 +++++++++++++++++++++++------------------------- + 3 files changed, 77 insertions(+), 76 deletions(-) + +diff --git a/bind.go b/bind.go +index 26b3cc7..432efa7 100644 +--- a/bind.go ++++ b/bind.go +@@ -7,7 +7,7 @@ package ldap + import ( + "errors" + +- "gopkg.in/asn1-ber.v1" ++ ber "gopkg.in/asn1-ber.v1" + ) + + // SimpleBindRequest represents a username/password bind operation +@@ -18,6 +18,9 @@ type SimpleBindRequest struct { + Password string + // Controls are optional controls to send with the bind request + Controls []Control ++ // AllowEmptyPassword sets whether the client allows binding with an empty password ++ // (normally used for unauthenticated bind). ++ AllowEmptyPassword bool + } + + // SimpleBindResult contains the response from the server +@@ -28,9 +31,10 @@ type SimpleBindResult struct { + // NewSimpleBindRequest returns a bind request + func NewSimpleBindRequest(username string, password string, controls []Control) *SimpleBindRequest { + return &SimpleBindRequest{ +- Username: username, +- Password: password, +- Controls: controls, ++ Username: username, ++ Password: password, ++ Controls: controls, ++ AllowEmptyPassword: false, + } + } + +@@ -47,6 +51,10 @@ func (bindRequest *SimpleBindRequest) encode() *ber.Packet { + + // SimpleBind performs the simple bind operation defined in the given request + func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResult, error) { ++ if simpleBindRequest.Password == "" && !simpleBindRequest.AllowEmptyPassword { ++ return nil, NewError(ErrorEmptyPassword, errors.New("ldap: empty password not allowed by the client")) ++ } ++ + packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") + packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) + encodedBindRequest := simpleBindRequest.encode() +@@ -97,47 +105,33 @@ func (l *Conn) SimpleBind(simpleBindRequest *SimpleBindRequest) (*SimpleBindResu + return result, nil + } + +-// Bind performs a bind with the given username and password ++// Bind performs a bind with the given username and password. ++// ++// It does not allow unauthenticated bind (i.e. empty password). Use the UnauthenticatedBind method ++// for that. + func (l *Conn) Bind(username, password string) error { +- packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") +- packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, l.nextMessageID(), "MessageID")) +- bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") +- bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) +- bindRequest.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, username, "User Name")) +- bindRequest.AppendChild(ber.NewString(ber.ClassContext, ber.TypePrimitive, 0, password, "Password")) +- packet.AppendChild(bindRequest) +- +- if l.Debug { +- ber.PrintPacket(packet) +- } +- +- msgCtx, err := l.sendMessage(packet) +- if err != nil { +- return err +- } +- defer l.finishMessage(msgCtx) +- +- packetResponse, ok := <-msgCtx.responses +- if !ok { +- return NewError(ErrorNetwork, errors.New("ldap: response channel closed")) +- } +- packet, err = packetResponse.ReadPacket() +- l.Debug.Printf("%d: got response %p", msgCtx.id, packet) +- if err != nil { +- return err +- } +- +- if l.Debug { +- if err := addLDAPDescriptions(packet); err != nil { +- return err +- } +- ber.PrintPacket(packet) ++ req := &SimpleBindRequest{ ++ Username: username, ++ Password: password, ++ AllowEmptyPassword: false, + } ++ _, err := l.SimpleBind(req) ++ return err ++} + +- resultCode, resultDescription := getLDAPResultCode(packet) +- if resultCode != 0 { +- return NewError(resultCode, errors.New(resultDescription)) ++// UnauthenticatedBind performs an unauthenticated bind. ++// ++// A username may be provided for trace (e.g. logging) purpose only, but it is normally not ++// authenticated or otherwise validated by the LDAP server. ++// ++// See https://tools.ietf.org/html/rfc4513#section-5.1.2 . ++// See https://tools.ietf.org/html/rfc4513#section-6.3.1 . ++func (l *Conn) UnauthenticatedBind(username string) error { ++ req := &SimpleBindRequest{ ++ Username: username, ++ Password: "", ++ AllowEmptyPassword: true, + } +- +- return nil ++ _, err := l.SimpleBind(req) ++ return err + } +diff --git a/error.go b/error.go +index ff69787..6e1277f 100644 +--- a/error.go ++++ b/error.go +@@ -54,6 +54,7 @@ const ( + ErrorDebugging = 203 + ErrorUnexpectedMessage = 204 + ErrorUnexpectedResponse = 205 ++ ErrorEmptyPassword = 206 + ) + + // LDAPResultCodeMap contains string descriptions for LDAP error codes +@@ -97,6 +98,14 @@ var LDAPResultCodeMap = map[uint8]string{ + LDAPResultObjectClassModsProhibited: "Object Class Mods Prohibited", + LDAPResultAffectsMultipleDSAs: "Affects Multiple DSAs", + LDAPResultOther: "Other", ++ ++ ErrorNetwork: "Network Error", ++ ErrorFilterCompile: "Filter Compile Error", ++ ErrorFilterDecompile: "Filter Decompile Error", ++ ErrorDebugging: "Debugging Error", ++ ErrorUnexpectedMessage: "Unexpected Message", ++ ErrorUnexpectedResponse: "Unexpected Response", ++ ErrorEmptyPassword: "Empty password not allowed by the client", + } + + func getLDAPResultCode(packet *ber.Packet) (code uint8, description string) { diff -Nru golang-github-go-ldap-ldap-2.4.1/debian/patches/series golang-github-go-ldap-ldap-2.4.1/debian/patches/series --- golang-github-go-ldap-ldap-2.4.1/debian/patches/series 2016-08-16 18:19:35.000000000 +0200 +++ golang-github-go-ldap-ldap-2.4.1/debian/patches/series 2017-11-29 14:37:00.000000000 +0100 @@ -1 +1,2 @@ disable-internet-tests.patch +0002-Require-explicit-intention-for-empty-password.patch
Attachment:
signature.asc
Description: OpenPGP digital signature