Skip to content

Commit

Permalink
Merge pull request #71 from gofrs/no_v2
Browse files Browse the repository at this point in the history
Remove support for DCE Security UUID (V2) generation
  • Loading branch information
cameracker committed Dec 30, 2020
2 parents abfe188 + 7589a5d commit 4b36aa0
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 104 deletions.
1 change: 0 additions & 1 deletion README.md
Expand Up @@ -12,7 +12,6 @@ and parsing of UUIDs in different formats.

This package supports the following UUID versions:
* Version 1, based on timestamp and MAC address (RFC-4122)
* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
* Version 3, based on MD5 hashing of a named value (RFC-4122)
* Version 4, based on random numbers (RFC-4122)
* Version 5, based on SHA-1 hashing of a named value (RFC-4122)
Expand Down
36 changes: 1 addition & 35 deletions generator.go
Expand Up @@ -30,7 +30,6 @@ import (
"hash"
"io"
"net"
"os"
"sync"
"time"
)
Expand All @@ -47,21 +46,11 @@ type HWAddrFunc func() (net.HardwareAddr, error)
// DefaultGenerator is the default UUID Generator used by this package.
var DefaultGenerator Generator = NewGen()

var (
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)

// NewV1 returns a UUID based on the current timestamp and MAC address.
func NewV1() (UUID, error) {
return DefaultGenerator.NewV1()
}

// NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
func NewV2(domain byte) (UUID, error) {
return DefaultGenerator.NewV2(domain)
}

// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
return DefaultGenerator.NewV3(ns, name)
Expand All @@ -80,7 +69,6 @@ func NewV5(ns UUID, name string) UUID {
// Generator provides an interface for generating UUIDs.
type Generator interface {
NewV1() (UUID, error)
NewV2(domain byte) (UUID, error)
NewV3(ns UUID, name string) UUID
NewV4() (UUID, error)
NewV5(ns UUID, name string) UUID
Expand Down Expand Up @@ -164,28 +152,6 @@ func (g *Gen) NewV1() (UUID, error) {
return u, nil
}

// NewV2 returns a DCE Security UUID based on the POSIX UID/GID.
func (g *Gen) NewV2(domain byte) (UUID, error) {
u, err := g.NewV1()
if err != nil {
return Nil, err
}

switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[:], posixGID)
}

u[9] = domain

u.SetVersion(V2)
u.SetVariant(VariantRFC4122)

return u, nil
}

// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name.
func (g *Gen) NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
Expand Down Expand Up @@ -216,7 +182,7 @@ func (g *Gen) NewV5(ns UUID, name string) UUID {
return u
}

// Returns the epoch and clock sequence.
// getClockSequence returns the epoch and clock sequence.
func (g *Gen) getClockSequence() (uint64, uint16, error) {
var err error
g.clockSequenceOnce.Do(func() {
Expand Down
63 changes: 0 additions & 63 deletions generator_test.go
Expand Up @@ -32,7 +32,6 @@ import (

func TestGenerator(t *testing.T) {
t.Run("NewV1", testNewV1)
t.Run("NewV2", testNewV2)
t.Run("NewV3", testNewV3)
t.Run("NewV4", testNewV4)
t.Run("NewV5", testNewV5)
Expand Down Expand Up @@ -171,63 +170,6 @@ func testNewV1MissingNetworkFaultyRand(t *testing.T) {
}
}

func testNewV2(t *testing.T) {
t.Run("Basic", testNewV2Basic)
t.Run("DifferentAcrossCalls", testNewV2DifferentAcrossCalls)
t.Run("FaultyRand", testNewV2FaultyRand)
}

func testNewV2Basic(t *testing.T) {
domains := []byte{
DomainPerson,
DomainGroup,
DomainOrg,
}
for _, domain := range domains {
u, err := NewV2(domain)
if err != nil {
t.Errorf("NewV2(%d): %v", domain, err)
}
if got, want := u.Version(), V2; got != want {
t.Errorf("NewV2(%d) generated UUID with version %d, want %d", domain, got, want)
}
if got, want := u.Variant(), VariantRFC4122; got != want {
t.Errorf("NewV2(%d) generated UUID with variant %d, want %d", domain, got, want)
}
}
}

func testNewV2DifferentAcrossCalls(t *testing.T) {
u1, err := NewV2(DomainOrg)
if err != nil {
t.Fatal(err)
}
u2, err := NewV2(DomainOrg)
if err != nil {
t.Fatal(err)
}
if u1 == u2 {
t.Errorf("generated identical UUIDs across calls: %v", u1)
}
}

func testNewV2FaultyRand(t *testing.T) {
g := &Gen{
epochFunc: time.Now,
hwAddrFunc: defaultHWAddrFunc,
rand: &faultyReader{
readToFail: 0, // fail immediately
},
}
u, err := g.NewV2(DomainPerson)
if err == nil {
t.Fatalf("got %v, want error", u)
}
if u != Nil {
t.Fatalf("got %v on error, want Nil", u)
}
}

func testNewV3(t *testing.T) {
t.Run("Basic", testNewV3Basic)
t.Run("EqualNames", testNewV3EqualNames)
Expand Down Expand Up @@ -382,11 +324,6 @@ func BenchmarkGenerator(b *testing.B) {
NewV1()
}
})
b.Run("NewV2", func(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV2(DomainOrg)
}
})
b.Run("NewV3", func(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV3(NamespaceDNS, "www.example.com")
Expand Down
18 changes: 13 additions & 5 deletions uuid.go
Expand Up @@ -19,11 +19,19 @@
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// Package uuid provides implementations of the Universally Unique Identifier (UUID), as specified in RFC-4122 and DCE 1.1.
// Package uuid provides implementations of the Universally Unique Identifier
// (UUID), as specified in RFC-4122,
//
// RFC-4122[1] provides the specification for versions 1, 3, 4, and 5.
//
// DCE 1.1[2] provides the specification for version 2.
// DCE 1.1[2] provides the specification for version 2, but version 2 support
// was removed from this package in v4 due to some concerns with the
// specification itself. Reading the spec, it seems that it would result in
// generating UUIDs that aren't very unique. In having read the spec it seemed
// that our implementation did not meet the spec. It also seems to be at-odds
// with RFC 4122, meaning we would need quite a bit of special code to support
// it. Lastly, there were no Version 2 implementations that we could find to
// ensure we were understanding the specification correctly.
//
// [1] https://tools.ietf.org/html/rfc4122
// [2] http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01
Expand All @@ -48,7 +56,7 @@ type UUID [Size]byte
const (
_ byte = iota
V1 // Version 1 (date-time and MAC address)
V2 // Version 2 (date-time and MAC address, DCE security version)
_ // Version 2 (date-time and MAC address, DCE security version) [removed]
V3 // Version 3 (namespace name-based)
V4 // Version 4 (random)
V5 // Version 5 (namespace name-based)
Expand All @@ -70,8 +78,8 @@ const (
)

// Timestamp is the count of 100-nanosecond intervals since 00:00:00.00,
// 15 October 1582 within a V1 UUID. This type has no meaning for V2-V5
// UUIDs since they don't have an embedded timestamp.
// 15 October 1582 within a V1 UUID. This type has no meaning for other
// UUID versions since they don't have an embedded timestamp.
type Timestamp uint64

const _100nsPerSecond = 10000000
Expand Down

0 comments on commit 4b36aa0

Please sign in to comment.