[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#883124: stretch-pu: package golang-github-go-ldap-ldap/2.4.1-1



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


Reply to: