mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-06-16 20:08:59 -04:00
groupware: port tests to Stalwart 0.16.7
This commit is contained in:
4
go.mod
4
go.mod
@@ -25,7 +25,6 @@ require (
|
||||
github.com/ggwhite/go-masker v1.1.0
|
||||
github.com/go-chi/chi/v5 v5.3.0
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/go-crypt/crypt v0.4.5
|
||||
github.com/go-jose/go-jose/v3 v3.0.5
|
||||
github.com/go-ldap/ldap/v3 v3.4.13
|
||||
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3
|
||||
@@ -62,6 +61,7 @@ require (
|
||||
github.com/microcosm-cc/bluemonday v1.0.27
|
||||
github.com/miekg/dns v1.1.68
|
||||
github.com/mna/pigeon v1.3.0
|
||||
github.com/moby/moby/api v1.54.1
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||
github.com/nats-io/nats-server/v2 v2.14.2
|
||||
github.com/nats-io/nats.go v1.51.0
|
||||
@@ -220,7 +220,6 @@ require (
|
||||
github.com/gdexlab/go-render v1.0.1 // indirect
|
||||
github.com/go-acme/lego/v4 v4.4.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
|
||||
github.com/go-crypt/x v0.4.7 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.9.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.19.1 // indirect
|
||||
@@ -310,7 +309,6 @@ require (
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/go-archive v0.2.0 // indirect
|
||||
github.com/moby/moby/api v1.54.1 // indirect
|
||||
github.com/moby/moby/client v0.4.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.1 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -392,10 +392,6 @@ github.com/go-chi/chi/v5 v5.3.0/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutV
|
||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
|
||||
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
|
||||
github.com/go-crypt/crypt v0.4.5 h1:cCR5vVejGk1kurwoGfkLxGORY+Pc9GiE7xKCpyHZ3n4=
|
||||
github.com/go-crypt/crypt v0.4.5/go.mod h1:cQijpCkqavdF52J1bE0PObWwqKKjQCHASHQ2dtLzOJs=
|
||||
github.com/go-crypt/x v0.4.7 h1:hObjW67nhq/GI1jaD7XCv5RoiVKzF46XIbULgzH71oU=
|
||||
github.com/go-crypt/x v0.4.7/go.mod h1:K3q7VmLC0U1QFAPn0SQvXjkAtu6FJuH0rN9LNqobX6k=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -532,6 +532,7 @@ func (w *HttpWsClientFactory) connect(ctx context.Context, sessionProvider func(
|
||||
|
||||
h := http.Header{}
|
||||
w.auth(ctx, username, logger, h)
|
||||
w.logger.Trace().Str("username", log.SafeString(username)).Str("url", log.SafeString(u.String())).Msgf("connecting")
|
||||
c, res, err := w.dialer.DialContext(ctx, u.String(), h)
|
||||
if err != nil {
|
||||
return nil, "", endpoint, jmapError(err, JmapErrorFailedToEstablishWssConnection)
|
||||
|
||||
@@ -59,8 +59,8 @@ func TestAddressBooks(t *testing.T) {
|
||||
},
|
||||
func(orig AddressBook) AddressBookChange {
|
||||
return AddressBookChange{
|
||||
Description: ptr(orig.Description + " (changed)"),
|
||||
IsSubscribed: ptr(!orig.IsSubscribed),
|
||||
Description: new(orig.Description + " (changed)"),
|
||||
IsSubscribed: new(!orig.IsSubscribed),
|
||||
}
|
||||
},
|
||||
func(t *testing.T, orig AddressBook, _ AddressBookChange, changed AddressBook) {
|
||||
@@ -85,7 +85,7 @@ func TestContacts(t *testing.T) {
|
||||
defer s.Close()
|
||||
|
||||
user := pickUser()
|
||||
session := s.Session(user.name)
|
||||
session := s.Session(user.email)
|
||||
ctx := s.Context(session)
|
||||
|
||||
accountId, addressbookId, expectedContactCardsById, boxes, err := s.fillContacts(t, count, session, ctx, user)
|
||||
@@ -213,8 +213,8 @@ func TestContacts(t *testing.T) {
|
||||
now := time.Now().Truncate(time.Duration(1) * time.Second).UTC()
|
||||
for _, event := range expectedContactCardsById {
|
||||
change := ContactCardChange{
|
||||
Language: ptr("xyz"),
|
||||
Updated: ptr(now),
|
||||
Language: new("xyz"),
|
||||
Updated: new(now),
|
||||
}
|
||||
result, err := s.client.UpdateContactCard(accountId, event.Id, change, ctx)
|
||||
require.NoError(err)
|
||||
@@ -359,7 +359,7 @@ func (s *StalwartTest) fillContacts( //NOSONAR
|
||||
user User,
|
||||
) (AccountId, string, map[string]ContactCard, ContactsBoxes, error) {
|
||||
require := require.New(t)
|
||||
c, err := NewTestJmapClient(session, user.name, user.password, true, true)
|
||||
c, err := NewTestJmapClient(session, user.email, user.password, true, true)
|
||||
require.NoError(err)
|
||||
defer c.Close()
|
||||
|
||||
@@ -401,11 +401,11 @@ func (s *StalwartTest) fillContacts( //NOSONAR
|
||||
|
||||
card := ContactCardChange{
|
||||
Type: jscontact.ContactCardType,
|
||||
Version: ptr(jscontact.JSContactVersion_1_0),
|
||||
Version: new(jscontact.JSContactVersion_1_0),
|
||||
AddressBookIds: toBoolPtrMap([]string{addressbookId}),
|
||||
ProdId: &productName,
|
||||
Language: &language,
|
||||
Kind: ptr(jscontact.ContactCardKindIndividual),
|
||||
Kind: new(jscontact.ContactCardKindIndividual),
|
||||
Name: &nameObj,
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ func TestCalendars(t *testing.T) { //NOSONAR
|
||||
},
|
||||
func(orig Calendar) CalendarChange {
|
||||
return CalendarChange{
|
||||
Description: ptr(orig.Description + " (changed)"),
|
||||
IsSubscribed: ptr(!orig.IsSubscribed),
|
||||
Description: new(orig.Description + " (changed)"),
|
||||
IsSubscribed: new(!orig.IsSubscribed),
|
||||
}
|
||||
},
|
||||
func(t *testing.T, orig Calendar, _ CalendarChange, changed Calendar) {
|
||||
@@ -75,7 +75,7 @@ func TestEvents(t *testing.T) {
|
||||
defer s.Close()
|
||||
|
||||
user := pickUser()
|
||||
session := s.Session(user.name)
|
||||
session := s.Session(user.email)
|
||||
ctx := s.Context(session)
|
||||
|
||||
accountId, calendarId, expectedEventsById, boxes, err := s.fillEvents(t, count, ctx, user)
|
||||
@@ -178,7 +178,7 @@ func TestEvents(t *testing.T) {
|
||||
for _, event := range expectedEventsById {
|
||||
change := CalendarEventChange{
|
||||
EventChange: jscalendar.EventChange{
|
||||
Status: ptr(jscalendar.StatusCancelled),
|
||||
Status: new(jscalendar.StatusCancelled),
|
||||
ObjectChange: jscalendar.ObjectChange{
|
||||
Sequence: uintPtr(99),
|
||||
ShowWithoutTime: truep,
|
||||
@@ -382,7 +382,7 @@ func (s *StalwartTest) fillEvents( //NOSONAR
|
||||
user User,
|
||||
) (AccountId, string, map[string]CalendarEvent, EventsBoxes, error) {
|
||||
require := require.New(t)
|
||||
c, err := NewTestJmapClient(ctx.Session, user.name, user.password, true, true)
|
||||
c, err := NewTestJmapClient(ctx.Session, user.email, user.password, true, true)
|
||||
require.NoError(err)
|
||||
defer c.Close()
|
||||
|
||||
@@ -467,7 +467,7 @@ func (s *StalwartTest) fillEvents( //NOSONAR
|
||||
EventChange: jscalendar.EventChange{
|
||||
Type: jscalendar.EventType,
|
||||
Start: jscalendar.LocalDateTime(start),
|
||||
Duration: ptr(jscalendar.Duration(duration)),
|
||||
Duration: new(jscalendar.Duration(duration)),
|
||||
Status: &status,
|
||||
ObjectChange: jscalendar.ObjectChange{
|
||||
CommonObjectChange: jscalendar.CommonObjectChange{
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestEmails(t *testing.T) {
|
||||
defer s.Close()
|
||||
|
||||
user := pickUser()
|
||||
session := s.Session(user.name)
|
||||
session := s.Session(user.email)
|
||||
ctx := s.Context(session)
|
||||
|
||||
accountId := session.PrimaryAccounts.Mail
|
||||
@@ -59,9 +59,11 @@ func TestEmails(t *testing.T) {
|
||||
result, err := s.client.GetIdentities(accountId, []string{}, ctx)
|
||||
require.NoError(err)
|
||||
require.Equal(session.State, result.GetSessionState())
|
||||
require.Len(result.Payload.List, 1)
|
||||
require.Equal(user.email, result.Payload.List[0].Email)
|
||||
require.Equal(user.description, result.Payload.List[0].Name)
|
||||
require.Len(result.Payload.List, 2)
|
||||
emailMatches := structs.Filter(result.Payload.List, func(i Identity) bool { return i.Email == user.email })
|
||||
require.Len(emailMatches, 1)
|
||||
aliasMatches := structs.Filter(result.Payload.List, func(i Identity) bool { return i.Email == user.alias })
|
||||
require.Len(aliasMatches, 1)
|
||||
}
|
||||
|
||||
{
|
||||
@@ -122,7 +124,7 @@ func TestSendingEmails(t *testing.T) {
|
||||
defer s.Close()
|
||||
|
||||
from := pickUser()
|
||||
session := s.Session(from.name)
|
||||
session := s.Session(from.email)
|
||||
ctx := s.Context(session)
|
||||
accountId := session.PrimaryAccounts.Mail
|
||||
|
||||
@@ -131,7 +133,7 @@ func TestSendingEmails(t *testing.T) {
|
||||
others := structs.Filter(users[:], func(u User) bool { return u.name != from.name })
|
||||
to = others[rand.Intn(len(others))]
|
||||
}
|
||||
toSession := s.Session(to.name)
|
||||
toSession := s.Session(to.email)
|
||||
toAccountId := toSession.PrimaryAccounts.Mail
|
||||
|
||||
var cc User
|
||||
@@ -139,7 +141,7 @@ func TestSendingEmails(t *testing.T) {
|
||||
others := structs.Filter(users[:], func(u User) bool { return u.name != from.name && u.name != to.name })
|
||||
cc = others[rand.Intn(len(others))]
|
||||
}
|
||||
ccSession := s.Session(cc.name)
|
||||
ccSession := s.Session(cc.email)
|
||||
ccAccountId := ccSession.PrimaryAccounts.Mail
|
||||
|
||||
var mailboxPerRole map[string]Mailbox
|
||||
@@ -190,8 +192,10 @@ func TestSendingEmails(t *testing.T) {
|
||||
{
|
||||
result, err := s.client.GetIdentities(accountId, []string{}, ctx)
|
||||
require.NoError(err)
|
||||
require.NotEmpty(result.Payload.List)
|
||||
identity = result.Payload.List[0]
|
||||
require.Len(result.Payload.List, 2)
|
||||
matchesAlias := structs.Filter(result.Payload.List, func(i Identity) bool { return i.Email == from.alias })
|
||||
require.Len(matchesAlias, 1)
|
||||
identity = matchesAlias[0]
|
||||
}
|
||||
|
||||
create := EmailChange{
|
||||
@@ -270,7 +274,7 @@ func TestSendingEmails(t *testing.T) {
|
||||
require.Equal(sub.UndoStatus, UndoStatusPending) // this *might* be fragile: if the server is fast enough, would we get "final" here?
|
||||
require.Empty(sub.DsnBlobIds)
|
||||
require.Empty(sub.MdnBlobIds)
|
||||
require.Equal(from.email, sub.Envelope.MailFrom.Email)
|
||||
require.Equal(from.alias, sub.Envelope.MailFrom.Email)
|
||||
require.Nil(sub.Envelope.MailFrom.Parameters)
|
||||
require.Len(sub.Envelope.RcptTo, 2)
|
||||
require.Contains(sub.Envelope.RcptTo, Address{Email: to.email})
|
||||
@@ -325,7 +329,7 @@ func TestSendingEmails(t *testing.T) {
|
||||
require.Equal(1, mailbox.TotalEmails)
|
||||
}
|
||||
}
|
||||
require.NotEmpty(inboxId, "failed to find the Mailbox with the 'inbox' role for %v", r.user.name)
|
||||
require.NotEmpty(inboxId, "failed to find the Mailbox with the 'inbox' role for %v", r.user.email)
|
||||
}
|
||||
|
||||
result, err := s.client.QueryEmails([]AccountId{r.accountId}, EmailFilterCondition{InMailbox: inboxId}, 0, 0, true, 0, rctx)
|
||||
@@ -538,7 +542,7 @@ func (s *StalwartTest) fillEmailsWithImap(folder string, count int, empty bool,
|
||||
}
|
||||
}(c)
|
||||
|
||||
if err = c.Login(user.name, user.password).Wait(); err != nil {
|
||||
if err = c.Login(user.email, user.password).Wait(); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
@@ -586,7 +590,7 @@ func (s *StalwartTest) fillEmailsWithImap(folder string, count int, empty bool,
|
||||
domain := addressParts[0][2]
|
||||
|
||||
toName := displayName
|
||||
toAddress := fmt.Sprintf("%s@%s", user.name, domain)
|
||||
toAddress := fmt.Sprintf("%s@%s", user.email, domain)
|
||||
ccName1 := "Team Lead"
|
||||
ccAddress1 := fmt.Sprintf("lead@%s", domain)
|
||||
ccName2 := "Coworker"
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestWs(t *testing.T) {
|
||||
defer s.Close()
|
||||
|
||||
user := pickUser()
|
||||
session := s.Session(user.name)
|
||||
session := s.Session(user.email)
|
||||
ctx := s.Context(session)
|
||||
|
||||
mailAccountId := session.PrimaryAccounts.Mail
|
||||
@@ -77,7 +77,7 @@ func TestWs(t *testing.T) {
|
||||
_, inboxFolder = s.findInbox(t, mailAccountId, ctx)
|
||||
}
|
||||
|
||||
l := &testWsPushListener{t: t, username: user.name, logger: s.logger, mailAccountId: mailAccountId}
|
||||
l := &testWsPushListener{t: t, username: user.email, logger: s.logger, mailAccountId: mailAccountId}
|
||||
s.client.AddWsPushListener(l)
|
||||
|
||||
require.Equal(uint32(0), l.calls.Load())
|
||||
|
||||
@@ -575,7 +575,7 @@ func (e Exemplar) MailboxInbox() (Mailbox, string, string) {
|
||||
Id: e.MailboxInboxId,
|
||||
Name: "Inbox",
|
||||
Role: JmapMailboxRoleInbox,
|
||||
SortOrder: ptr(0),
|
||||
SortOrder: new(0),
|
||||
TotalEmails: 1291,
|
||||
UnreadEmails: 82,
|
||||
TotalThreads: 891,
|
||||
@@ -600,7 +600,7 @@ func (e Exemplar) MailboxInboxProjects() (Mailbox, string, string) {
|
||||
Id: e.MailboxProjectId,
|
||||
ParentId: e.MailboxInboxId,
|
||||
Name: "Projects",
|
||||
SortOrder: ptr(0),
|
||||
SortOrder: new(0),
|
||||
TotalEmails: 112,
|
||||
UnreadEmails: 3,
|
||||
TotalThreads: 85,
|
||||
@@ -625,7 +625,7 @@ func (e Exemplar) MailboxDrafts() (Mailbox, string, string) {
|
||||
Id: e.MailboxDraftsId,
|
||||
Name: "Drafts",
|
||||
Role: JmapMailboxRoleDrafts,
|
||||
SortOrder: ptr(0),
|
||||
SortOrder: new(0),
|
||||
TotalEmails: 12,
|
||||
UnreadEmails: 1,
|
||||
TotalThreads: 12,
|
||||
@@ -650,7 +650,7 @@ func (e Exemplar) MailboxSent() (Mailbox, string, string) {
|
||||
Id: e.MailboxSentId,
|
||||
Name: "Sent Items",
|
||||
Role: JmapMailboxRoleSent,
|
||||
SortOrder: ptr(0),
|
||||
SortOrder: new(0),
|
||||
TotalEmails: 1621,
|
||||
UnreadEmails: 0,
|
||||
TotalThreads: 1621,
|
||||
@@ -675,7 +675,7 @@ func (e Exemplar) MailboxJunk() (Mailbox, string, string) {
|
||||
Id: e.MailboxJunkId,
|
||||
Name: "Junk Mail",
|
||||
Role: JmapMailboxRoleJunk,
|
||||
SortOrder: ptr(0),
|
||||
SortOrder: new(0),
|
||||
TotalEmails: 251,
|
||||
UnreadEmails: 0,
|
||||
TotalThreads: 251,
|
||||
@@ -700,7 +700,7 @@ func (e Exemplar) MailboxDeleted() (Mailbox, string, string) {
|
||||
Id: e.MailboxDeletedId,
|
||||
Name: "Deleted Items",
|
||||
Role: JmapMailboxRoleTrash,
|
||||
SortOrder: ptr(0),
|
||||
SortOrder: new(0),
|
||||
TotalEmails: 99,
|
||||
UnreadEmails: 0,
|
||||
TotalThreads: 91,
|
||||
@@ -918,7 +918,7 @@ func (e Exemplar) AddressBook() AddressBook {
|
||||
|
||||
func (e Exemplar) AddressBookChange() AddressBookChange {
|
||||
return AddressBookChange{
|
||||
Description: ptr("A different name"),
|
||||
Description: new("A different name"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2325,9 +2325,9 @@ func (e Exemplar) CalendarEventSearchResults() CalendarEventSearchResults {
|
||||
return CalendarEventSearchResults{
|
||||
Results: []CalendarEvent{ev},
|
||||
CanCalculateChanges: true,
|
||||
Position: ptr(uint(3)),
|
||||
Limit: ptr(uint(10)),
|
||||
Total: ptr(uint(4)),
|
||||
Position: new(uint(3)),
|
||||
Limit: new(uint(10)),
|
||||
Total: new(uint(4)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2337,8 +2337,8 @@ func (e Exemplar) ContactCardSearchResults() ContactCardSearchResults {
|
||||
return ContactCardSearchResults{
|
||||
Results: []ContactCard{c1, c2},
|
||||
CanCalculateChanges: true,
|
||||
Position: ptr(uint(3)),
|
||||
Limit: ptr(uint(10)),
|
||||
Total: ptr(uint(4)),
|
||||
Position: new(uint(3)),
|
||||
Limit: new(uint(10)),
|
||||
Total: new(uint(4)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,14 +394,10 @@ func mapPairs[K comparable, L, R any](left map[K]L, right map[K]R) map[K]pair[L,
|
||||
}
|
||||
|
||||
var (
|
||||
truep = ptr(true)
|
||||
falsep = ptr(false)
|
||||
truep = new(true)
|
||||
falsep = new(false)
|
||||
)
|
||||
|
||||
func ptr[T any | string | int | uint | bool](t T) *T {
|
||||
return &t
|
||||
}
|
||||
|
||||
func identity1[T any](t T) T {
|
||||
return t
|
||||
}
|
||||
@@ -410,7 +406,7 @@ func list[T Foo, GETRESP GetResponse[T]](r GETRESP) []T { return r.GetList() }
|
||||
func getid[T Idable](r T) string { return r.GetId() }
|
||||
|
||||
func uintPtr[T int | uint](i T) *uint {
|
||||
return ptr(uint(i))
|
||||
return new(uint(i))
|
||||
}
|
||||
|
||||
func valueIf[T any | uint | int | bool](value *T, condition bool) *T {
|
||||
|
||||
21
vendor/github.com/go-crypt/crypt/LICENSE
generated
vendored
21
vendor/github.com/go-crypt/crypt/LICENSE
generated
vendored
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 github.com/go-crypt/crypt
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
26
vendor/github.com/go-crypt/crypt/algorithm/const.go
generated
vendored
26
vendor/github.com/go-crypt/crypt/algorithm/const.go
generated
vendored
@@ -1,26 +0,0 @@
|
||||
package algorithm
|
||||
|
||||
const (
|
||||
// DigestSHA1 is te name for SHA1 digests.
|
||||
DigestSHA1 = "sha1"
|
||||
|
||||
// DigestSHA224 is te name for SHA224 digests.
|
||||
DigestSHA224 = "sha224"
|
||||
|
||||
// DigestSHA256 is te name for SHA256 digests.
|
||||
DigestSHA256 = "sha256"
|
||||
|
||||
// DigestSHA384 is te name for SHA384 digests.
|
||||
DigestSHA384 = "sha384"
|
||||
|
||||
// DigestSHA512 is te name for SHA512 digests.
|
||||
DigestSHA512 = "sha512"
|
||||
)
|
||||
|
||||
const (
|
||||
// SaltLengthDefault is the default salt size for most implementations.
|
||||
SaltLengthDefault = 16
|
||||
|
||||
// KeyLengthDefault is the default key size for most implementations.
|
||||
KeyLengthDefault = 32
|
||||
)
|
||||
3
vendor/github.com/go-crypt/crypt/algorithm/doc.go
generated
vendored
3
vendor/github.com/go-crypt/crypt/algorithm/doc.go
generated
vendored
@@ -1,3 +0,0 @@
|
||||
// Package algorithm is a package which contains the individual algorithms and interfaces related to their
|
||||
// implementation.
|
||||
package algorithm
|
||||
66
vendor/github.com/go-crypt/crypt/algorithm/errors.go
generated
vendored
66
vendor/github.com/go-crypt/crypt/algorithm/errors.go
generated
vendored
@@ -1,66 +0,0 @@
|
||||
package algorithm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrEncodedHashInvalidFormat is an error returned when an encoded hash has an invalid format.
|
||||
ErrEncodedHashInvalidFormat = errors.New("provided encoded hash has an invalid format")
|
||||
|
||||
// ErrEncodedHashInvalidIdentifier is an error returned when an encoded hash has an invalid identifier for the
|
||||
// given digest.
|
||||
ErrEncodedHashInvalidIdentifier = errors.New("provided encoded hash has an invalid identifier")
|
||||
|
||||
// ErrEncodedHashInvalidVersion is an error returned when an encoded hash has an unsupported or otherwise invalid
|
||||
// version.
|
||||
ErrEncodedHashInvalidVersion = errors.New("provided encoded hash has an invalid version")
|
||||
|
||||
// ErrEncodedHashInvalidOption is an error returned when an encoded hash has an unsupported or otherwise invalid
|
||||
// option in the option field.
|
||||
ErrEncodedHashInvalidOption = errors.New("provided encoded hash has an invalid option")
|
||||
|
||||
// ErrEncodedHashInvalidOptionKey is an error returned when an encoded hash has an unknown or otherwise invalid
|
||||
// option key in the option field.
|
||||
ErrEncodedHashInvalidOptionKey = errors.New("provided encoded hash has an invalid option key")
|
||||
|
||||
// ErrEncodedHashInvalidOptionValue is an error returned when an encoded hash has an unknown or otherwise invalid
|
||||
// option value in the option field.
|
||||
ErrEncodedHashInvalidOptionValue = errors.New("provided encoded hash has an invalid option value")
|
||||
|
||||
// ErrEncodedHashKeyEncoding is an error returned when an encoded hash has a salt with an invalid or unsupported
|
||||
// encoding.
|
||||
ErrEncodedHashKeyEncoding = errors.New("provided encoded hash has a key value that can't be decoded")
|
||||
|
||||
// ErrEncodedHashSaltEncoding is an error returned when an encoded hash has a salt with an invalid or unsupported
|
||||
// encoding.
|
||||
ErrEncodedHashSaltEncoding = errors.New("provided encoded hash has a salt value that can't be decoded")
|
||||
|
||||
// ErrKeyDerivation is returned when a Key function returns an error.
|
||||
ErrKeyDerivation = errors.New("failed to derive the key with the provided parameters")
|
||||
|
||||
// ErrSaltEncoding is an error returned when a salt has an invalid or unsupported encoding.
|
||||
ErrSaltEncoding = errors.New("provided salt has a value that can't be decoded")
|
||||
|
||||
// ErrPasswordInvalid is an error returned when a password has an invalid or unsupported properties. It is NOT
|
||||
// returned on password mismatches.
|
||||
ErrPasswordInvalid = errors.New("password is invalid")
|
||||
|
||||
// ErrSaltInvalid is an error returned when a salt has an invalid or unsupported properties.
|
||||
ErrSaltInvalid = errors.New("salt is invalid")
|
||||
|
||||
// ErrSaltReadRandomBytes is an error returned when generating the random bytes for salt resulted in an error.
|
||||
ErrSaltReadRandomBytes = errors.New("could not read random bytes for salt")
|
||||
|
||||
// ErrParameterInvalid is an error returned when a parameter has an invalid value.
|
||||
ErrParameterInvalid = errors.New("parameter is invalid")
|
||||
)
|
||||
|
||||
// Error format strings.
|
||||
const (
|
||||
ErrFmtInvalidIntParameter = "%w: parameter '%s' must be between %d%s and %d but is set to '%d'"
|
||||
ErrFmtDigestDecode = "%s decode error: %w"
|
||||
ErrFmtDigestMatch = "%s match error: %w"
|
||||
ErrFmtHasherHash = "%s hashing error: %w"
|
||||
ErrFmtHasherValidation = "%s validation error: %w"
|
||||
)
|
||||
46
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/const.go
generated
vendored
46
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/const.go
generated
vendored
@@ -1,46 +0,0 @@
|
||||
package shacrypt
|
||||
|
||||
const (
|
||||
// EncodingFmt is the encoding format for this algorithm.
|
||||
EncodingFmt = "$%s$rounds=%d$%s$%s"
|
||||
|
||||
// EncodingFmtRoundsOmitted is the encoding format for this algorithm when the rounds can be omitted.
|
||||
EncodingFmtRoundsOmitted = "$%s$%s$%s"
|
||||
|
||||
// AlgName is the name for this algorithm.
|
||||
AlgName = "shacrypt"
|
||||
|
||||
// AlgIdentifierSHA256 is the identifier used in encoded SHA256 variants of this algorithm.
|
||||
AlgIdentifierSHA256 = "5"
|
||||
|
||||
// AlgIdentifierSHA512 is the identifier used in encoded SHA512 variants of this algorithm.
|
||||
AlgIdentifierSHA512 = "6"
|
||||
|
||||
// IterationsMin is the minimum number of iterations accepted.
|
||||
IterationsMin = 1000
|
||||
|
||||
// IterationsMax is the maximum number of iterations accepted.
|
||||
IterationsMax = 999999999
|
||||
|
||||
// IterationsDefaultSHA256 is the default number of iterations for SHA256.
|
||||
IterationsDefaultSHA256 = 1000000
|
||||
|
||||
// IterationsDefaultSHA512 is the default number of iterations for SHA512.
|
||||
IterationsDefaultSHA512 = 500000
|
||||
|
||||
// IterationsDefaultOmitted is the default number of iterations when the rounds are omitted.
|
||||
IterationsDefaultOmitted = 5000
|
||||
|
||||
// SaltLengthMin is the minimum salt length.
|
||||
SaltLengthMin = 1
|
||||
|
||||
// SaltLengthMax is the maximum salt length.
|
||||
SaltLengthMax = 16
|
||||
|
||||
// SaltCharSet are the valid characters for the salt.
|
||||
SaltCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"
|
||||
)
|
||||
|
||||
const (
|
||||
variantDefault = VariantSHA512
|
||||
)
|
||||
136
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/decoder.go
generated
vendored
136
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/decoder.go
generated
vendored
@@ -1,136 +0,0 @@
|
||||
package shacrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-crypt/crypt/algorithm"
|
||||
"github.com/go-crypt/crypt/internal/encoding"
|
||||
)
|
||||
|
||||
// RegisterDecoder the decoder with the algorithm.DecoderRegister.
|
||||
func RegisterDecoder(r algorithm.DecoderRegister) (err error) {
|
||||
if err = RegisterDecoderSHA256(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = RegisterDecoderSHA512(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterDecoderSHA256 registers specifically the sha256 decoder variant with the algorithm.DecoderRegister.
|
||||
func RegisterDecoderSHA256(r algorithm.DecoderRegister) (err error) {
|
||||
if err = r.RegisterDecodeFunc(VariantSHA256.Prefix(), DecodeVariant(VariantSHA256)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterDecoderSHA512 registers specifically the sha512 decoder variant with the algorithm.DecoderRegister.
|
||||
func RegisterDecoderSHA512(r algorithm.DecoderRegister) (err error) {
|
||||
if err = r.RegisterDecodeFunc(VariantSHA512.Prefix(), DecodeVariant(VariantSHA512)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decode the encoded digest into a algorithm.Digest.
|
||||
func Decode(encodedDigest string) (digest algorithm.Digest, err error) {
|
||||
return DecodeVariant(VariantNone)(encodedDigest)
|
||||
}
|
||||
|
||||
// DecodeVariant the encoded digest into a algorithm.Digest provided it matches the provided Variant. If VariantNone is
|
||||
// used all variants can be decoded.
|
||||
func DecodeVariant(v Variant) func(encodedDigest string) (digest algorithm.Digest, err error) {
|
||||
return func(encodedDigest string) (digest algorithm.Digest, err error) {
|
||||
var (
|
||||
parts []string
|
||||
variant Variant
|
||||
)
|
||||
|
||||
if variant, parts, err = decoderParts(encodedDigest); err != nil {
|
||||
return nil, fmt.Errorf(algorithm.ErrFmtDigestDecode, AlgName, err)
|
||||
}
|
||||
|
||||
if v != VariantNone && v != variant {
|
||||
return nil, fmt.Errorf(algorithm.ErrFmtDigestDecode, AlgName, fmt.Errorf("the '%s' variant cannot be decoded only the '%s' variant can be", variant.String(), v.String()))
|
||||
}
|
||||
|
||||
if digest, err = decode(variant, parts); err != nil {
|
||||
return nil, fmt.Errorf(algorithm.ErrFmtDigestDecode, AlgName, err)
|
||||
}
|
||||
|
||||
return digest, nil
|
||||
}
|
||||
}
|
||||
|
||||
func decoderParts(encodedDigest string) (variant Variant, parts []string, err error) {
|
||||
parts = encoding.Split(encodedDigest, -1)
|
||||
|
||||
if n := len(parts); n != 4 && n != 5 {
|
||||
return VariantNone, nil, algorithm.ErrEncodedHashInvalidFormat
|
||||
}
|
||||
|
||||
variant = NewVariant(parts[1])
|
||||
|
||||
if variant == VariantNone {
|
||||
return variant, nil, fmt.Errorf("%w: identifier '%s' is not an encoded %s digest", algorithm.ErrEncodedHashInvalidIdentifier, parts[1], AlgName)
|
||||
}
|
||||
|
||||
return variant, parts[2:], nil
|
||||
}
|
||||
|
||||
func decode(variant Variant, parts []string) (digest algorithm.Digest, err error) {
|
||||
decoded := &Digest{
|
||||
variant: variant,
|
||||
}
|
||||
|
||||
var (
|
||||
ip, is, ik int
|
||||
)
|
||||
|
||||
switch len(parts) {
|
||||
case 2:
|
||||
ip, is, ik = -1, 0, 1
|
||||
case 3:
|
||||
ip, is, ik = 0, 1, 2
|
||||
}
|
||||
|
||||
if len(parts[ik]) == 0 {
|
||||
return nil, fmt.Errorf("%w: key has 0 bytes", algorithm.ErrEncodedHashKeyEncoding)
|
||||
}
|
||||
|
||||
decoded.iterations = IterationsDefaultOmitted
|
||||
|
||||
var params []encoding.Parameter
|
||||
|
||||
if ip >= 0 {
|
||||
if params, err = encoding.DecodeParameterStr(parts[ip]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, param := range params {
|
||||
switch param.Key {
|
||||
case "rounds":
|
||||
var rounds uint64
|
||||
|
||||
if rounds, err = strconv.ParseUint(param.Value, 10, 32); err != nil {
|
||||
return nil, fmt.Errorf("%w: option '%s' has invalid value '%s': %v", algorithm.ErrEncodedHashInvalidOptionValue, param.Key, param.Value, err)
|
||||
}
|
||||
|
||||
decoded.iterations = int(rounds)
|
||||
default:
|
||||
return nil, fmt.Errorf("%w: option '%s' with value '%s' is unknown", algorithm.ErrEncodedHashInvalidOptionKey, param.Key, param.Value)
|
||||
}
|
||||
}
|
||||
|
||||
decoded.salt, decoded.key = []byte(parts[is]), []byte(parts[ik])
|
||||
|
||||
return decoded, nil
|
||||
}
|
||||
83
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/digest.go
generated
vendored
83
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/digest.go
generated
vendored
@@ -1,83 +0,0 @@
|
||||
package shacrypt
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
xcrypt "github.com/go-crypt/x/crypt"
|
||||
|
||||
"github.com/go-crypt/crypt/algorithm"
|
||||
)
|
||||
|
||||
// Digest is a digest which handles SHA-crypt hashes like SHA256 or SHA512.
|
||||
type Digest struct {
|
||||
variant Variant
|
||||
|
||||
iterations int
|
||||
salt, key []byte
|
||||
}
|
||||
|
||||
// Match returns true if the string password matches the current shacrypt.Digest.
|
||||
func (d *Digest) Match(password string) (match bool) {
|
||||
return d.MatchBytes([]byte(password))
|
||||
}
|
||||
|
||||
// MatchBytes returns true if the []byte passwordBytes matches the current shacrypt.Digest.
|
||||
func (d *Digest) MatchBytes(passwordBytes []byte) (match bool) {
|
||||
match, _ = d.MatchBytesAdvanced(passwordBytes)
|
||||
|
||||
return match
|
||||
}
|
||||
|
||||
// MatchAdvanced is the same as Match except if there is an error it returns that as well.
|
||||
func (d *Digest) MatchAdvanced(password string) (match bool, err error) {
|
||||
if match, err = d.MatchBytesAdvanced([]byte(password)); err != nil {
|
||||
return match, fmt.Errorf(algorithm.ErrFmtDigestMatch, AlgName, err)
|
||||
}
|
||||
|
||||
return match, nil
|
||||
}
|
||||
|
||||
// MatchBytesAdvanced is the same as MatchBytes except if there is an error it returns that as well.
|
||||
func (d *Digest) MatchBytesAdvanced(passwordBytes []byte) (match bool, err error) {
|
||||
if len(d.key) == 0 {
|
||||
return false, fmt.Errorf("%w: key has 0 bytes", algorithm.ErrPasswordInvalid)
|
||||
}
|
||||
|
||||
return subtle.ConstantTimeCompare(d.key, xcrypt.KeySHACrypt(d.variant.HashFunc(), passwordBytes, d.salt, d.iterations)) == 1, nil
|
||||
}
|
||||
|
||||
// Encode this Digest as a string for storage.
|
||||
func (d *Digest) Encode() (hash string) {
|
||||
switch d.iterations {
|
||||
case IterationsDefaultOmitted:
|
||||
return strings.ReplaceAll(fmt.Sprintf(EncodingFmtRoundsOmitted,
|
||||
d.variant.Prefix(),
|
||||
d.salt, d.key,
|
||||
), "\n", "")
|
||||
default:
|
||||
return strings.ReplaceAll(fmt.Sprintf(EncodingFmt,
|
||||
d.variant.Prefix(), d.iterations,
|
||||
d.salt, d.key,
|
||||
), "\n", "")
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the storable format of the shacrypt.Digest hash utilizing fmt.Sprintf and shacrypt.EncodingFmt.
|
||||
func (d *Digest) String() string {
|
||||
return d.Encode()
|
||||
}
|
||||
|
||||
func (d *Digest) defaults() {
|
||||
switch d.variant {
|
||||
case VariantSHA256, VariantSHA512:
|
||||
break
|
||||
default:
|
||||
d.variant = variantDefault
|
||||
}
|
||||
|
||||
if d.iterations == 0 {
|
||||
d.iterations = d.variant.DefaultIterations()
|
||||
}
|
||||
}
|
||||
7
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/doc.go
generated
vendored
7
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/doc.go
generated
vendored
@@ -1,7 +0,0 @@
|
||||
// Package shacrypt provides helpful abstractions for an implementation of SHA-crypt and implements
|
||||
// github.com/go-crypt/crypt interfaces.
|
||||
//
|
||||
// See https://www.akkadia.org/drepper/SHA-crypt.html for specification details.
|
||||
//
|
||||
// This implementation is loaded by crypt.NewDefaultDecoder and crypt.NewDecoderAll.
|
||||
package shacrypt
|
||||
156
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/hasher.go
generated
vendored
156
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/hasher.go
generated
vendored
@@ -1,156 +0,0 @@
|
||||
package shacrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
xcrypt "github.com/go-crypt/x/crypt"
|
||||
|
||||
"github.com/go-crypt/crypt/algorithm"
|
||||
"github.com/go-crypt/crypt/internal/random"
|
||||
)
|
||||
|
||||
// New returns a *Hasher without any settings configured. This d to a SHA512 hash.Hash
|
||||
// with 1000000 iterations. These settings can be overridden with the methods with the With prefix.
|
||||
func New(opts ...Opt) (hasher *Hasher, err error) {
|
||||
hasher = &Hasher{}
|
||||
|
||||
if err = hasher.WithOptions(opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = hasher.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return hasher, nil
|
||||
}
|
||||
|
||||
// Hasher is a algorithm.Hash for SHA-crypt which can be initialized via shacrypt.New using a functional options pattern.
|
||||
type Hasher struct {
|
||||
variant Variant
|
||||
|
||||
iterations, bytesSalt int
|
||||
|
||||
d bool
|
||||
}
|
||||
|
||||
// NewSHA256 returns a *Hasher with the SHA256 hash.Hash which d to 1000000 iterations. These
|
||||
// settings can be overridden with the methods with the With prefix.
|
||||
func NewSHA256() (hasher *Hasher, err error) {
|
||||
return New(
|
||||
WithVariant(VariantSHA256),
|
||||
WithIterations(VariantSHA256.DefaultIterations()),
|
||||
)
|
||||
}
|
||||
|
||||
// NewSHA512 returns a *Hasher with the SHA512 hash.Hash which d to 1000000 iterations. These
|
||||
// settings can be overridden with the methods with the With prefix.
|
||||
func NewSHA512() (hasher *Hasher, err error) {
|
||||
return New(
|
||||
WithVariant(VariantSHA512),
|
||||
WithIterations(VariantSHA512.DefaultIterations()),
|
||||
)
|
||||
}
|
||||
|
||||
// WithOptions defines the options for this scrypt.Hasher.
|
||||
func (h *Hasher) WithOptions(opts ...Opt) (err error) {
|
||||
for _, opt := range opts {
|
||||
if err = opt(h); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hash performs the hashing operation and returns either a shacrypt.Digest as a algorithm.Digest or an error.
|
||||
func (h *Hasher) Hash(password string) (digest algorithm.Digest, err error) {
|
||||
h.defaults()
|
||||
|
||||
if digest, err = h.hash(password); err != nil {
|
||||
return nil, fmt.Errorf(algorithm.ErrFmtHasherHash, AlgName, err)
|
||||
}
|
||||
|
||||
return digest, nil
|
||||
}
|
||||
|
||||
func (h *Hasher) hash(password string) (digest algorithm.Digest, err error) {
|
||||
var salt []byte
|
||||
|
||||
if salt, err = random.CharSetBytes(h.bytesSalt, SaltCharSet); err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", algorithm.ErrSaltReadRandomBytes, err)
|
||||
}
|
||||
|
||||
return h.hashWithSalt(password, salt)
|
||||
}
|
||||
|
||||
// HashWithSalt overloads the Hash method allowing the user to provide a salt. It's recommended instead to configure the
|
||||
// salt size and let this be a random value generated using crypto/rand.
|
||||
func (h *Hasher) HashWithSalt(password string, salt []byte) (digest algorithm.Digest, err error) {
|
||||
h.defaults()
|
||||
|
||||
if digest, err = h.hashWithSalt(password, salt); err != nil {
|
||||
return nil, fmt.Errorf(algorithm.ErrFmtHasherHash, AlgName, err)
|
||||
}
|
||||
|
||||
return digest, nil
|
||||
}
|
||||
|
||||
func (h *Hasher) hashWithSalt(password string, salt []byte) (digest algorithm.Digest, err error) {
|
||||
if s := len(salt); s > SaltLengthMax || s < SaltLengthMin {
|
||||
return nil, fmt.Errorf("%w: salt bytes must have a length of between %d and %d but has a length of %d", algorithm.ErrSaltInvalid, SaltLengthMin, SaltLengthMax, len(salt))
|
||||
}
|
||||
|
||||
d := &Digest{
|
||||
variant: h.variant,
|
||||
iterations: h.iterations,
|
||||
salt: salt,
|
||||
}
|
||||
|
||||
d.defaults()
|
||||
|
||||
d.key = xcrypt.KeySHACrypt(d.variant.HashFunc(), []byte(password), d.salt, d.iterations)
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// MustHash overloads the Hash method and panics if the error is not nil. It's recommended if you use this option to
|
||||
// utilize the Validate method first or handle the panic appropriately.
|
||||
func (h *Hasher) MustHash(password string) (digest algorithm.Digest) {
|
||||
var err error
|
||||
|
||||
if digest, err = h.Hash(password); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return digest
|
||||
}
|
||||
|
||||
// Validate checks the settings/parameters for this shacrypt.Hasher and returns an error.
|
||||
func (h *Hasher) Validate() (err error) {
|
||||
h.defaults()
|
||||
|
||||
if err = h.validate(); err != nil {
|
||||
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Hasher) validate() (err error) {
|
||||
h.defaults()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Hasher) defaults() {
|
||||
if h.d {
|
||||
return
|
||||
}
|
||||
|
||||
h.d = true
|
||||
|
||||
if h.bytesSalt < SaltLengthMin {
|
||||
h.bytesSalt = algorithm.SaltLengthDefault
|
||||
}
|
||||
}
|
||||
98
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/opts.go
generated
vendored
98
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/opts.go
generated
vendored
@@ -1,98 +0,0 @@
|
||||
package shacrypt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-crypt/crypt/algorithm"
|
||||
)
|
||||
|
||||
// Opt describes the functional option pattern for the shacrypt.Hasher.
|
||||
type Opt func(h *Hasher) (err error)
|
||||
|
||||
// WithVariant configures the shacrypt.Variant of the resulting shacrypt.Digest.
|
||||
// Default is shacrypt.VariantSHA512.
|
||||
func WithVariant(variant Variant) Opt {
|
||||
return func(h *Hasher) (err error) {
|
||||
switch variant {
|
||||
case VariantNone:
|
||||
return nil
|
||||
case VariantSHA256, VariantSHA512:
|
||||
h.variant = variant
|
||||
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf("%w: variant '%d' is invalid", algorithm.ErrParameterInvalid, variant))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithVariantName uses the variant name or identifier to configure the shacrypt.Variant of the resulting shacrypt.Digest.
|
||||
// Default is shacrypt.VariantSHA512.
|
||||
func WithVariantName(identifier string) Opt {
|
||||
return func(h *Hasher) (err error) {
|
||||
if identifier == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
variant := NewVariant(identifier)
|
||||
|
||||
if variant == VariantNone {
|
||||
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf("%w: variant identifier '%s' is invalid", algorithm.ErrParameterInvalid, identifier))
|
||||
}
|
||||
|
||||
h.variant = variant
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSHA256 adjusts this Hasher to utilize the SHA256 hash.Hash.
|
||||
func WithSHA256() Opt {
|
||||
return func(h *Hasher) (err error) {
|
||||
h.variant = VariantSHA256
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithSHA512 adjusts this Hasher to utilize the SHA512 hash.Hash.
|
||||
func WithSHA512() Opt {
|
||||
return func(h *Hasher) (err error) {
|
||||
h.variant = VariantSHA512
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithIterations sets the iterations parameter of the resulting shacrypt.Digest.
|
||||
// Minimum 1000, Maximum 999999999. Default is 1000000.
|
||||
func WithIterations(iterations int) Opt {
|
||||
return func(h *Hasher) (err error) {
|
||||
if iterations < IterationsMin || iterations > IterationsMax {
|
||||
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "iterations", IterationsMin, "", IterationsMax, iterations))
|
||||
}
|
||||
|
||||
h.iterations = iterations
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithRounds is an alias for shacrypt.WithIterations.
|
||||
func WithRounds(rounds int) Opt {
|
||||
return WithIterations(rounds)
|
||||
}
|
||||
|
||||
// WithSaltLength adjusts the salt size (in bytes) of the resulting shacrypt.Digest.
|
||||
// Minimum 1, Maximum 16. Default is 16.
|
||||
func WithSaltLength(bytes int) Opt {
|
||||
return func(h *Hasher) (err error) {
|
||||
if bytes < SaltLengthMin || bytes > SaltLengthMax {
|
||||
return fmt.Errorf(algorithm.ErrFmtHasherValidation, AlgName, fmt.Errorf(algorithm.ErrFmtInvalidIntParameter, algorithm.ErrParameterInvalid, "salt length", SaltLengthMin, "", SaltLengthMax, bytes))
|
||||
}
|
||||
|
||||
h.bytesSalt = bytes
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
92
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/variant.go
generated
vendored
92
vendor/github.com/go-crypt/crypt/algorithm/shacrypt/variant.go
generated
vendored
@@ -1,92 +0,0 @@
|
||||
package shacrypt
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
|
||||
"github.com/go-crypt/crypt/algorithm"
|
||||
)
|
||||
|
||||
// NewVariant converts an identifier string to a shacrypt.Variant.
|
||||
func NewVariant(identifier string) Variant {
|
||||
switch identifier {
|
||||
case AlgIdentifierSHA256, algorithm.DigestSHA256:
|
||||
return VariantSHA256
|
||||
case AlgIdentifierSHA512, algorithm.DigestSHA512:
|
||||
return VariantSHA512
|
||||
default:
|
||||
return VariantSHA512
|
||||
}
|
||||
}
|
||||
|
||||
// Variant is a variant of the shacrypt.Digest.
|
||||
type Variant int
|
||||
|
||||
const (
|
||||
// VariantNone is a variant of the shacrypt.Digest which is unknown.
|
||||
VariantNone Variant = iota
|
||||
|
||||
// VariantSHA256 is a variant of the shacrypt.Digest which uses SHA-256.
|
||||
VariantSHA256
|
||||
|
||||
// VariantSHA512 is a variant of the shacrypt.Digest which uses SHA-512.
|
||||
VariantSHA512
|
||||
)
|
||||
|
||||
// String implements the fmt.Stringer returning a string representation of the shacrypt.Variant.
|
||||
func (v Variant) String() (identifier string) {
|
||||
switch v {
|
||||
case VariantSHA256:
|
||||
return algorithm.DigestSHA256
|
||||
case VariantSHA512:
|
||||
return algorithm.DigestSHA512
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Prefix returns the shacrypt.Variant prefix identifier.
|
||||
func (v Variant) Prefix() (prefix string) {
|
||||
switch v {
|
||||
case VariantSHA256:
|
||||
return AlgIdentifierSHA256
|
||||
case VariantSHA512:
|
||||
return AlgIdentifierSHA512
|
||||
default:
|
||||
return AlgIdentifierSHA512
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the Variant name.
|
||||
func (v Variant) Name() (s string) {
|
||||
switch v {
|
||||
case VariantSHA256:
|
||||
return algorithm.DigestSHA256
|
||||
case VariantSHA512:
|
||||
return algorithm.DigestSHA512
|
||||
default:
|
||||
return algorithm.DigestSHA512
|
||||
}
|
||||
}
|
||||
|
||||
// HashFunc returns the internal HMAC HashFunc.
|
||||
func (v Variant) HashFunc() algorithm.HashFunc {
|
||||
switch v {
|
||||
case VariantSHA256:
|
||||
return sha256.New
|
||||
case VariantSHA512:
|
||||
return sha512.New
|
||||
default:
|
||||
return sha512.New
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultIterations returns the default iterations for the particular variant.
|
||||
func (v Variant) DefaultIterations() int {
|
||||
switch v {
|
||||
case VariantSHA512:
|
||||
return IterationsDefaultSHA512
|
||||
default:
|
||||
return IterationsDefaultSHA256
|
||||
}
|
||||
}
|
||||
62
vendor/github.com/go-crypt/crypt/algorithm/types.go
generated
vendored
62
vendor/github.com/go-crypt/crypt/algorithm/types.go
generated
vendored
@@ -1,62 +0,0 @@
|
||||
package algorithm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Hash is an interface which implements password hashing.
|
||||
type Hash interface {
|
||||
// Validate checks the hasher configuration to ensure it's valid. This should be used when the Hash is going to be
|
||||
// reused and you should use it in conjunction with MustHash.
|
||||
Validate() (err error)
|
||||
|
||||
// Hash performs the hashing operation on a password and resets any relevant parameters such as a manually set salt.
|
||||
// It then returns a Digest and error.
|
||||
Hash(password string) (hashed Digest, err error)
|
||||
|
||||
// HashWithSalt is an overload of Digest that also accepts a salt.
|
||||
HashWithSalt(password string, salt []byte) (hashed Digest, err error)
|
||||
|
||||
// MustHash overloads the Hash method and panics if the error is not nil. It's recommended if you use this method to
|
||||
// utilize the Validate method first or handle the panic appropriately.
|
||||
MustHash(password string) (hashed Digest)
|
||||
}
|
||||
|
||||
// Matcher is an interface used to match passwords.
|
||||
type Matcher interface {
|
||||
Match(password string) (match bool)
|
||||
MatchBytes(passwordBytes []byte) (match bool)
|
||||
MatchAdvanced(password string) (match bool, err error)
|
||||
MatchBytesAdvanced(passwordBytes []byte) (match bool, err error)
|
||||
}
|
||||
|
||||
// Digest represents a hashed password. It's implemented by all hashed password results so that when we pass a
|
||||
// stored hash into its relevant type we can verify the password against the hash.
|
||||
type Digest interface {
|
||||
fmt.Stringer
|
||||
|
||||
Matcher
|
||||
|
||||
Encode() (hash string)
|
||||
}
|
||||
|
||||
// DecodeFunc describes a function to decode an encoded digest into a algorithm.Digest.
|
||||
type DecodeFunc func(encodedDigest string) (digest Digest, err error)
|
||||
|
||||
// DecoderRegister describes an implementation that allows registering DecodeFunc's.
|
||||
type DecoderRegister interface {
|
||||
RegisterDecodeFunc(prefix string, decoder DecodeFunc) (err error)
|
||||
RegisterDecodePrefix(prefix, identifier string) (err error)
|
||||
|
||||
Decoder
|
||||
}
|
||||
|
||||
// Decoder is a representation of a implementation that performs generic decoding. Currently this is just intended for
|
||||
// use by implementers.
|
||||
type Decoder interface {
|
||||
Decode(encodedDigest string) (digest Digest, err error)
|
||||
}
|
||||
|
||||
// HashFunc is a function which returns a hash.Hash.
|
||||
type HashFunc func() hash.Hash
|
||||
14
vendor/github.com/go-crypt/crypt/internal/encoding/base64adapted.go
generated
vendored
14
vendor/github.com/go-crypt/crypt/internal/encoding/base64adapted.go
generated
vendored
@@ -1,14 +0,0 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
const (
|
||||
encodeBase64Adapted = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"
|
||||
)
|
||||
|
||||
var (
|
||||
// Base64RawAdaptedEncoding is the adapted encoding for crypt purposes without padding.
|
||||
Base64RawAdaptedEncoding = base64.NewEncoding(encodeBase64Adapted).WithPadding(base64.NoPadding)
|
||||
)
|
||||
9
vendor/github.com/go-crypt/crypt/internal/encoding/const.go
generated
vendored
9
vendor/github.com/go-crypt/crypt/internal/encoding/const.go
generated
vendored
@@ -1,9 +0,0 @@
|
||||
package encoding
|
||||
|
||||
const (
|
||||
// Delimiter rune for all encodings.
|
||||
Delimiter = rune('$')
|
||||
|
||||
// DelimiterStr is the string variation of Delimiter.
|
||||
DelimiterStr = string(Delimiter)
|
||||
)
|
||||
10
vendor/github.com/go-crypt/crypt/internal/encoding/digest.go
generated
vendored
10
vendor/github.com/go-crypt/crypt/internal/encoding/digest.go
generated
vendored
@@ -1,10 +0,0 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Split an encoded digest by the encoding.Delimiter.
|
||||
func Split(encodedDigest string, n int) (parts []string) {
|
||||
return strings.SplitN(encodedDigest, DelimiterStr, n)
|
||||
}
|
||||
2
vendor/github.com/go-crypt/crypt/internal/encoding/doc.go
generated
vendored
2
vendor/github.com/go-crypt/crypt/internal/encoding/doc.go
generated
vendored
@@ -1,2 +0,0 @@
|
||||
// Package encoding is an internal encoding helper package.
|
||||
package encoding
|
||||
54
vendor/github.com/go-crypt/crypt/internal/encoding/parameters.go
generated
vendored
54
vendor/github.com/go-crypt/crypt/internal/encoding/parameters.go
generated
vendored
@@ -1,54 +0,0 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Parameter is a key value pair.
|
||||
type Parameter struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
// Int converts the Value to an int using strconv.Atoi.
|
||||
func (p Parameter) Int() (int, error) {
|
||||
return strconv.Atoi(p.Value)
|
||||
}
|
||||
|
||||
const (
|
||||
// ParameterDefaultItemSeparator is the default item separator.
|
||||
ParameterDefaultItemSeparator = ","
|
||||
|
||||
// ParameterDefaultKeyValueSeparator is the default key value separator.
|
||||
ParameterDefaultKeyValueSeparator = "="
|
||||
)
|
||||
|
||||
// DecodeParameterStr is an alias for DecodeParameterStrAdvanced using item separator and key value separator
|
||||
// of ',' and '=' respectively.
|
||||
func DecodeParameterStr(input string) (opts []Parameter, err error) {
|
||||
return DecodeParameterStrAdvanced(input, ParameterDefaultItemSeparator, ParameterDefaultKeyValueSeparator)
|
||||
}
|
||||
|
||||
// DecodeParameterStrAdvanced decodes parameter strings into a []Parameter where sepItem separates each parameter, and sepKV separates the key and value.
|
||||
func DecodeParameterStrAdvanced(input string, sepItem, sepKV string) (opts []Parameter, err error) {
|
||||
if input == "" {
|
||||
return nil, fmt.Errorf("empty strings can't be decoded to parameters")
|
||||
}
|
||||
|
||||
o := strings.Split(input, sepItem)
|
||||
|
||||
opts = make([]Parameter, len(o))
|
||||
|
||||
for i, joined := range o {
|
||||
kv := strings.SplitN(joined, sepKV, 2)
|
||||
if len(kv) != 2 {
|
||||
return nil, fmt.Errorf("parameter pair '%s' is not properly encoded: does not contain kv separator '%s'", joined, sepKV)
|
||||
}
|
||||
|
||||
opts[i] = Parameter{Key: kv[0], Value: kv[1]}
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
||||
32
vendor/github.com/go-crypt/crypt/internal/random/bytes.go
generated
vendored
32
vendor/github.com/go-crypt/crypt/internal/random/bytes.go
generated
vendored
@@ -1,32 +0,0 @@
|
||||
package random
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Bytes returns random arbitrary bytes with a length of n.
|
||||
func Bytes(n int) (bytes []byte, err error) {
|
||||
bytes = make([]byte, n)
|
||||
|
||||
if _, err = io.ReadFull(rand.Reader, bytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes, nil
|
||||
}
|
||||
|
||||
// CharSetBytes returns random bytes with a length of n from the characters in the charset.
|
||||
func CharSetBytes(n int, charset string) (bytes []byte, err error) {
|
||||
bytes = make([]byte, n)
|
||||
|
||||
if _, err = rand.Read(bytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, b := range bytes {
|
||||
bytes[i] = charset[b%byte(len(charset))]
|
||||
}
|
||||
|
||||
return bytes, nil
|
||||
}
|
||||
2
vendor/github.com/go-crypt/crypt/internal/random/doc.go
generated
vendored
2
vendor/github.com/go-crypt/crypt/internal/random/doc.go
generated
vendored
@@ -1,2 +0,0 @@
|
||||
// Package random is an internal helper package.
|
||||
package random
|
||||
27
vendor/github.com/go-crypt/x/LICENSE
generated
vendored
27
vendor/github.com/go-crypt/x/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
51
vendor/github.com/go-crypt/x/base64/base64.go
generated
vendored
51
vendor/github.com/go-crypt/x/base64/base64.go
generated
vendored
@@ -1,51 +0,0 @@
|
||||
package base64
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
var AdaptedEncoding = base64.NewEncoding(encodeAdapted)
|
||||
|
||||
// BcryptEncoding is the Bcrypt Base64 Alternative encoding.
|
||||
var BcryptEncoding = base64.NewEncoding(bcryptB64Alphabet)
|
||||
|
||||
// EncodeCrypt implements the linux crypt lib's B64 encoding.
|
||||
func EncodeCrypt(src []byte) (dst []byte) {
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
dst = make([]byte, (len(src)*8+5)/6)
|
||||
|
||||
idst, isrc := 0, 0
|
||||
|
||||
for isrc < len(src)/3*3 {
|
||||
v := uint(src[isrc+2])<<16 | uint(src[isrc+1])<<8 | uint(src[isrc])
|
||||
dst[idst+0] = cryptB64Alphabet[v&0x3f]
|
||||
dst[idst+1] = cryptB64Alphabet[v>>6&0x3f]
|
||||
dst[idst+2] = cryptB64Alphabet[v>>12&0x3f]
|
||||
dst[idst+3] = cryptB64Alphabet[v>>18]
|
||||
idst += 4
|
||||
isrc += 3
|
||||
}
|
||||
|
||||
remainder := len(src) - isrc
|
||||
|
||||
if remainder == 0 {
|
||||
return dst
|
||||
}
|
||||
|
||||
v := uint(src[isrc+0])
|
||||
if remainder == 2 {
|
||||
v |= uint(src[isrc+1]) << 8
|
||||
}
|
||||
|
||||
dst[idst+0] = cryptB64Alphabet[v&0x3f]
|
||||
dst[idst+1] = cryptB64Alphabet[v>>6&0x3f]
|
||||
|
||||
if remainder == 2 {
|
||||
dst[idst+2] = cryptB64Alphabet[v>>12]
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
7
vendor/github.com/go-crypt/x/base64/const.go
generated
vendored
7
vendor/github.com/go-crypt/x/base64/const.go
generated
vendored
@@ -1,7 +0,0 @@
|
||||
package base64
|
||||
|
||||
const (
|
||||
cryptB64Alphabet = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
bcryptB64Alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
encodeAdapted = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"
|
||||
)
|
||||
223
vendor/github.com/go-crypt/x/crypt/const.go
generated
vendored
223
vendor/github.com/go-crypt/x/crypt/const.go
generated
vendored
@@ -1,223 +0,0 @@
|
||||
package crypt
|
||||
|
||||
var permuteTableMD5Crypt = [16]byte{
|
||||
12, 6, 0,
|
||||
13, 7, 1,
|
||||
14, 8, 2,
|
||||
15, 9, 3,
|
||||
5, 10, 4,
|
||||
11,
|
||||
}
|
||||
|
||||
var permuteTableSHA1Crypt = [21]byte{
|
||||
2, 1, 0,
|
||||
5, 4, 3,
|
||||
8, 7, 6,
|
||||
11, 10, 9,
|
||||
14, 13, 12,
|
||||
17, 16, 15,
|
||||
0, 19, 18,
|
||||
}
|
||||
|
||||
var permuteTableSHACryptSHA256 = [32]byte{
|
||||
20, 10, 0,
|
||||
11, 1, 21,
|
||||
2, 22, 12,
|
||||
23, 13, 3,
|
||||
14, 4, 24,
|
||||
5, 25, 15,
|
||||
26, 16, 6,
|
||||
17, 7, 27,
|
||||
8, 28, 18,
|
||||
29, 19, 9,
|
||||
30, 31,
|
||||
}
|
||||
|
||||
var permuteTableSHACryptSHA512 = [64]byte{
|
||||
42, 21, 0,
|
||||
1, 43, 22,
|
||||
23, 2, 44,
|
||||
45, 24, 3,
|
||||
4, 46, 25,
|
||||
26, 5, 47,
|
||||
48, 27, 6,
|
||||
7, 49, 28,
|
||||
29, 8, 50,
|
||||
51, 30, 9,
|
||||
10, 52, 31,
|
||||
32, 11, 53,
|
||||
54, 33, 12,
|
||||
13, 55, 34,
|
||||
35, 14, 56,
|
||||
57, 36, 15,
|
||||
16, 58, 37,
|
||||
38, 17, 59,
|
||||
60, 39, 18,
|
||||
19, 61, 40,
|
||||
41, 20, 62,
|
||||
63,
|
||||
}
|
||||
|
||||
// The following is the 1517 bytes of Hamlet III.ii which is public domain. This is used by Sun's MD5 Crypt function.
|
||||
var magicTableMD5CryptSunHamlet = [1517]byte{
|
||||
84, 111, 32, 98, 101, 44, 32, 111, 114, 32, 110,
|
||||
111, 116, 32, 116, 111, 32, 98, 101, 44, 45,
|
||||
45, 116, 104, 97, 116, 32, 105, 115, 32, 116,
|
||||
104, 101, 32, 113, 117, 101, 115, 116, 105, 111,
|
||||
110, 58, 45, 45, 10, 87, 104, 101, 116, 104,
|
||||
101, 114, 32, 39, 116, 105, 115, 32, 110, 111,
|
||||
98, 108, 101, 114, 32, 105, 110, 32, 116, 104,
|
||||
101, 32, 109, 105, 110, 100, 32, 116, 111, 32,
|
||||
115, 117, 102, 102, 101, 114, 10, 84, 104, 101,
|
||||
32, 115, 108, 105, 110, 103, 115, 32, 97, 110,
|
||||
100, 32, 97, 114, 114, 111, 119, 115, 32, 111,
|
||||
102, 32, 111, 117, 116, 114, 97, 103, 101, 111,
|
||||
117, 115, 32, 102, 111, 114, 116, 117, 110, 101,
|
||||
10, 79, 114, 32, 116, 111, 32, 116, 97, 107,
|
||||
101, 32, 97, 114, 109, 115, 32, 97, 103, 97,
|
||||
105, 110, 115, 116, 32, 97, 32, 115, 101, 97,
|
||||
32, 111, 102, 32, 116, 114, 111, 117, 98, 108,
|
||||
101, 115, 44, 10, 65, 110, 100, 32, 98, 121,
|
||||
32, 111, 112, 112, 111, 115, 105, 110, 103, 32,
|
||||
101, 110, 100, 32, 116, 104, 101, 109, 63, 45,
|
||||
45, 84, 111, 32, 100, 105, 101, 44, 45, 45,
|
||||
116, 111, 32, 115, 108, 101, 101, 112, 44, 45,
|
||||
45, 10, 78, 111, 32, 109, 111, 114, 101, 59,
|
||||
32, 97, 110, 100, 32, 98, 121, 32, 97, 32,
|
||||
115, 108, 101, 101, 112, 32, 116, 111, 32, 115,
|
||||
97, 121, 32, 119, 101, 32, 101, 110, 100, 10,
|
||||
84, 104, 101, 32, 104, 101, 97, 114, 116, 97,
|
||||
99, 104, 101, 44, 32, 97, 110, 100, 32, 116,
|
||||
104, 101, 32, 116, 104, 111, 117, 115, 97, 110,
|
||||
100, 32, 110, 97, 116, 117, 114, 97, 108, 32,
|
||||
115, 104, 111, 99, 107, 115, 10, 84, 104, 97,
|
||||
116, 32, 102, 108, 101, 115, 104, 32, 105, 115,
|
||||
32, 104, 101, 105, 114, 32, 116, 111, 44, 45,
|
||||
45, 39, 116, 105, 115, 32, 97, 32, 99, 111,
|
||||
110, 115, 117, 109, 109, 97, 116, 105, 111, 110,
|
||||
10, 68, 101, 118, 111, 117, 116, 108, 121, 32,
|
||||
116, 111, 32, 98, 101, 32, 119, 105, 115, 104,
|
||||
39, 100, 46, 32, 84, 111, 32, 100, 105, 101,
|
||||
44, 45, 45, 116, 111, 32, 115, 108, 101, 101,
|
||||
112, 59, 45, 45, 10, 84, 111, 32, 115, 108,
|
||||
101, 101, 112, 33, 32, 112, 101, 114, 99, 104,
|
||||
97, 110, 99, 101, 32, 116, 111, 32, 100, 114,
|
||||
101, 97, 109, 58, 45, 45, 97, 121, 44, 32,
|
||||
116, 104, 101, 114, 101, 39, 115, 32, 116, 104,
|
||||
101, 32, 114, 117, 98, 59, 10, 70, 111, 114,
|
||||
32, 105, 110, 32, 116, 104, 97, 116, 32, 115,
|
||||
108, 101, 101, 112, 32, 111, 102, 32, 100, 101,
|
||||
97, 116, 104, 32, 119, 104, 97, 116, 32, 100,
|
||||
114, 101, 97, 109, 115, 32, 109, 97, 121, 32,
|
||||
99, 111, 109, 101, 44, 10, 87, 104, 101, 110,
|
||||
32, 119, 101, 32, 104, 97, 118, 101, 32, 115,
|
||||
104, 117, 102, 102, 108, 101, 100, 32, 111, 102,
|
||||
102, 32, 116, 104, 105, 115, 32, 109, 111, 114,
|
||||
116, 97, 108, 32, 99, 111, 105, 108, 44, 10,
|
||||
77, 117, 115, 116, 32, 103, 105, 118, 101, 32,
|
||||
117, 115, 32, 112, 97, 117, 115, 101, 58, 32,
|
||||
116, 104, 101, 114, 101, 39, 115, 32, 116, 104,
|
||||
101, 32, 114, 101, 115, 112, 101, 99, 116, 10,
|
||||
84, 104, 97, 116, 32, 109, 97, 107, 101, 115,
|
||||
32, 99, 97, 108, 97, 109, 105, 116, 121, 32,
|
||||
111, 102, 32, 115, 111, 32, 108, 111, 110, 103,
|
||||
32, 108, 105, 102, 101, 59, 10, 70, 111, 114,
|
||||
32, 119, 104, 111, 32, 119, 111, 117, 108, 100,
|
||||
32, 98, 101, 97, 114, 32, 116, 104, 101, 32,
|
||||
119, 104, 105, 112, 115, 32, 97, 110, 100, 32,
|
||||
115, 99, 111, 114, 110, 115, 32, 111, 102, 32,
|
||||
116, 105, 109, 101, 44, 10, 84, 104, 101, 32,
|
||||
111, 112, 112, 114, 101, 115, 115, 111, 114, 39,
|
||||
115, 32, 119, 114, 111, 110, 103, 44, 32, 116,
|
||||
104, 101, 32, 112, 114, 111, 117, 100, 32, 109,
|
||||
97, 110, 39, 115, 32, 99, 111, 110, 116, 117,
|
||||
109, 101, 108, 121, 44, 10, 84, 104, 101, 32,
|
||||
112, 97, 110, 103, 115, 32, 111, 102, 32, 100,
|
||||
101, 115, 112, 105, 115, 39, 100, 32, 108, 111,
|
||||
118, 101, 44, 32, 116, 104, 101, 32, 108, 97,
|
||||
119, 39, 115, 32, 100, 101, 108, 97, 121, 44,
|
||||
10, 84, 104, 101, 32, 105, 110, 115, 111, 108,
|
||||
101, 110, 99, 101, 32, 111, 102, 32, 111, 102,
|
||||
102, 105, 99, 101, 44, 32, 97, 110, 100, 32,
|
||||
116, 104, 101, 32, 115, 112, 117, 114, 110, 115,
|
||||
10, 84, 104, 97, 116, 32, 112, 97, 116, 105,
|
||||
101, 110, 116, 32, 109, 101, 114, 105, 116, 32,
|
||||
111, 102, 32, 116, 104, 101, 32, 117, 110, 119,
|
||||
111, 114, 116, 104, 121, 32, 116, 97, 107, 101,
|
||||
115, 44, 10, 87, 104, 101, 110, 32, 104, 101,
|
||||
32, 104, 105, 109, 115, 101, 108, 102, 32, 109,
|
||||
105, 103, 104, 116, 32, 104, 105, 115, 32, 113,
|
||||
117, 105, 101, 116, 117, 115, 32, 109, 97, 107,
|
||||
101, 10, 87, 105, 116, 104, 32, 97, 32, 98,
|
||||
97, 114, 101, 32, 98, 111, 100, 107, 105, 110,
|
||||
63, 32, 119, 104, 111, 32, 119, 111, 117, 108,
|
||||
100, 32, 116, 104, 101, 115, 101, 32, 102, 97,
|
||||
114, 100, 101, 108, 115, 32, 98, 101, 97, 114,
|
||||
44, 10, 84, 111, 32, 103, 114, 117, 110, 116,
|
||||
32, 97, 110, 100, 32, 115, 119, 101, 97, 116,
|
||||
32, 117, 110, 100, 101, 114, 32, 97, 32, 119,
|
||||
101, 97, 114, 121, 32, 108, 105, 102, 101, 44,
|
||||
10, 66, 117, 116, 32, 116, 104, 97, 116, 32,
|
||||
116, 104, 101, 32, 100, 114, 101, 97, 100, 32,
|
||||
111, 102, 32, 115, 111, 109, 101, 116, 104, 105,
|
||||
110, 103, 32, 97, 102, 116, 101, 114, 32, 100,
|
||||
101, 97, 116, 104, 44, 45, 45, 10, 84, 104,
|
||||
101, 32, 117, 110, 100, 105, 115, 99, 111, 118,
|
||||
101, 114, 39, 100, 32, 99, 111, 117, 110, 116,
|
||||
114, 121, 44, 32, 102, 114, 111, 109, 32, 119,
|
||||
104, 111, 115, 101, 32, 98, 111, 117, 114, 110,
|
||||
10, 78, 111, 32, 116, 114, 97, 118, 101, 108,
|
||||
108, 101, 114, 32, 114, 101, 116, 117, 114, 110,
|
||||
115, 44, 45, 45, 112, 117, 122, 122, 108, 101,
|
||||
115, 32, 116, 104, 101, 32, 119, 105, 108, 108,
|
||||
44, 10, 65, 110, 100, 32, 109, 97, 107, 101,
|
||||
115, 32, 117, 115, 32, 114, 97, 116, 104, 101,
|
||||
114, 32, 98, 101, 97, 114, 32, 116, 104, 111,
|
||||
115, 101, 32, 105, 108, 108, 115, 32, 119, 101,
|
||||
32, 104, 97, 118, 101, 10, 84, 104, 97, 110,
|
||||
32, 102, 108, 121, 32, 116, 111, 32, 111, 116,
|
||||
104, 101, 114, 115, 32, 116, 104, 97, 116, 32,
|
||||
119, 101, 32, 107, 110, 111, 119, 32, 110, 111,
|
||||
116, 32, 111, 102, 63, 10, 84, 104, 117, 115,
|
||||
32, 99, 111, 110, 115, 99, 105, 101, 110, 99,
|
||||
101, 32, 100, 111, 101, 115, 32, 109, 97, 107,
|
||||
101, 32, 99, 111, 119, 97, 114, 100, 115, 32,
|
||||
111, 102, 32, 117, 115, 32, 97, 108, 108, 59,
|
||||
10, 65, 110, 100, 32, 116, 104, 117, 115, 32,
|
||||
116, 104, 101, 32, 110, 97, 116, 105, 118, 101,
|
||||
32, 104, 117, 101, 32, 111, 102, 32, 114, 101,
|
||||
115, 111, 108, 117, 116, 105, 111, 110, 10, 73,
|
||||
115, 32, 115, 105, 99, 107, 108, 105, 101, 100,
|
||||
32, 111, 39, 101, 114, 32, 119, 105, 116, 104,
|
||||
32, 116, 104, 101, 32, 112, 97, 108, 101, 32,
|
||||
99, 97, 115, 116, 32, 111, 102, 32, 116, 104,
|
||||
111, 117, 103, 104, 116, 59, 10, 65, 110, 100,
|
||||
32, 101, 110, 116, 101, 114, 112, 114, 105, 115,
|
||||
101, 115, 32, 111, 102, 32, 103, 114, 101, 97,
|
||||
116, 32, 112, 105, 116, 104, 32, 97, 110, 100,
|
||||
32, 109, 111, 109, 101, 110, 116, 44, 10, 87,
|
||||
105, 116, 104, 32, 116, 104, 105, 115, 32, 114,
|
||||
101, 103, 97, 114, 100, 44, 32, 116, 104, 101,
|
||||
105, 114, 32, 99, 117, 114, 114, 101, 110, 116,
|
||||
115, 32, 116, 117, 114, 110, 32, 97, 119, 114,
|
||||
121, 44, 10, 65, 110, 100, 32, 108, 111, 115,
|
||||
101, 32, 116, 104, 101, 32, 110, 97, 109, 101,
|
||||
32, 111, 102, 32, 97, 99, 116, 105, 111, 110,
|
||||
46, 45, 45, 83, 111, 102, 116, 32, 121, 111,
|
||||
117, 32, 110, 111, 119, 33, 10, 84, 104, 101,
|
||||
32, 102, 97, 105, 114, 32, 79, 112, 104, 101,
|
||||
108, 105, 97, 33, 45, 45, 78, 121, 109, 112,
|
||||
104, 44, 32, 105, 110, 32, 116, 104, 121, 32,
|
||||
111, 114, 105, 115, 111, 110, 115, 10, 66, 101,
|
||||
32, 97, 108, 108, 32, 109, 121, 32, 115, 105,
|
||||
110, 115, 32, 114, 101, 109, 101, 109, 98, 101,
|
||||
114, 39, 100, 46, 10, 0,
|
||||
}
|
||||
|
||||
var (
|
||||
prefixMD5Crypt = []byte("$1$")
|
||||
prefixSHA1Crypt = []byte("$sha1$")
|
||||
prefixSunMD5Crypt = []byte("$md5$")
|
||||
prefixSunMD5CryptRounds = []byte("$md5,rounds=")
|
||||
sepCrypt = []byte("$")
|
||||
)
|
||||
300
vendor/github.com/go-crypt/x/crypt/crypt.go
generated
vendored
300
vendor/github.com/go-crypt/x/crypt/crypt.go
generated
vendored
@@ -1,300 +0,0 @@
|
||||
package crypt
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// KeySHACrypt calculates the shacrypt SHA256/SHA512 key given an appropriate hash.Hash, password, salt, and number of rounds.
|
||||
func KeySHACrypt(hashFunc func() hash.Hash, password, salt []byte, rounds int) []byte {
|
||||
// Step 1.
|
||||
digest := hashFunc()
|
||||
|
||||
size := digest.Size()
|
||||
|
||||
switch size {
|
||||
case sha1.Size:
|
||||
return KeySHA1Crypt(password, salt, uint32(rounds))
|
||||
case sha256.Size, sha512.Size:
|
||||
break
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
length := len(password)
|
||||
|
||||
// Step 2.
|
||||
digest.Write(password)
|
||||
|
||||
// Step 3.
|
||||
digest.Write(salt)
|
||||
|
||||
// Step 4.
|
||||
digestB := hashFunc()
|
||||
|
||||
// Step 5.
|
||||
digestB.Write(password)
|
||||
|
||||
// Step 6.
|
||||
digestB.Write(salt)
|
||||
|
||||
// Step 7.
|
||||
digestB.Write(password)
|
||||
|
||||
// Step 8.
|
||||
sumB := digestB.Sum(nil)
|
||||
digestB.Reset()
|
||||
digestB = nil
|
||||
|
||||
// Step 9 and 10:
|
||||
digest.Write(repeat(sumB, length))
|
||||
|
||||
// Step 11.
|
||||
for i := length; i > 0; i >>= 1 {
|
||||
if even(i) {
|
||||
digest.Write(password)
|
||||
} else {
|
||||
digest.Write(sumB)
|
||||
}
|
||||
}
|
||||
|
||||
clean(sumB)
|
||||
sumB = nil
|
||||
|
||||
// Step 12.
|
||||
sumA := digest.Sum(nil)
|
||||
digest.Reset()
|
||||
|
||||
// Step 13-14.
|
||||
for i := 0; i < length; i++ {
|
||||
digest.Write(password)
|
||||
}
|
||||
|
||||
// Step 15.
|
||||
sumDP := digest.Sum(nil)
|
||||
digest.Reset()
|
||||
|
||||
// Step 16.
|
||||
seqP := repeat(sumDP, length)
|
||||
sumDP = nil
|
||||
|
||||
// Step 17-18.
|
||||
for i := 0; i < 16+int(sumA[0]); i++ {
|
||||
digest.Write(salt)
|
||||
}
|
||||
|
||||
// Step 19.
|
||||
sumDS := digest.Sum(nil)
|
||||
digest.Reset()
|
||||
|
||||
// Step 20.
|
||||
seqS := repeat(sumDS, len(salt))
|
||||
|
||||
// Step 21.
|
||||
for i := 0; i < rounds; i++ {
|
||||
digest.Reset()
|
||||
|
||||
// Step 21 Sub-Step B and C.
|
||||
if i&1 != 0 {
|
||||
// Step 21 Sub-Step B.
|
||||
digest.Write(seqP)
|
||||
} else {
|
||||
// Step 21 Sub-Step C.
|
||||
digest.Write(sumA)
|
||||
}
|
||||
|
||||
// Step 21 Sub-Step D.
|
||||
if i%3 != 0 {
|
||||
digest.Write(seqS)
|
||||
}
|
||||
|
||||
// Step 21 Sub-Step E.
|
||||
if i%7 != 0 {
|
||||
digest.Write(seqP)
|
||||
}
|
||||
|
||||
// Step 21 Sub-Step F and G.
|
||||
if i&1 != 0 {
|
||||
// Step 21 Sub-Step F.
|
||||
digest.Write(sumA)
|
||||
} else {
|
||||
// Step 21 Sub-Step G.
|
||||
digest.Write(seqP)
|
||||
}
|
||||
|
||||
// Sub-Step H.
|
||||
copy(sumA, digest.Sum(nil))
|
||||
}
|
||||
|
||||
digest.Reset()
|
||||
digest = nil
|
||||
|
||||
seqP, seqS = nil, nil
|
||||
|
||||
switch size {
|
||||
case sha256.Size:
|
||||
// Step 22 Sub Step E.
|
||||
return permute(sumA, permuteTableSHACryptSHA256[:])
|
||||
case sha512.Size:
|
||||
// Step 22 Sub Step E.
|
||||
return permute(sumA, permuteTableSHACryptSHA512[:])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeySHA1Crypt calculates the sha1crypt key given a password, salt, and number of rounds.
|
||||
func KeySHA1Crypt(password, salt []byte, rounds uint32) []byte {
|
||||
digest := hmac.New(sha1.New, password)
|
||||
digest.Write(salt)
|
||||
digest.Write(prefixSHA1Crypt)
|
||||
digest.Write([]byte(strconv.FormatUint(uint64(rounds), 10)))
|
||||
|
||||
sumA := digest.Sum(nil)
|
||||
|
||||
if rounds == 0 {
|
||||
return permute(sumA, permuteTableSHA1Crypt[:])
|
||||
}
|
||||
|
||||
for rounds--; rounds > 0; rounds-- {
|
||||
digest.Reset()
|
||||
|
||||
digest.Write(sumA)
|
||||
|
||||
copy(sumA, digest.Sum(nil))
|
||||
}
|
||||
|
||||
return permute(sumA, permuteTableSHA1Crypt[:])
|
||||
}
|
||||
|
||||
// KeyMD5Crypt calculates the md5crypt key given a password and salt.
|
||||
func KeyMD5Crypt(password, salt []byte) []byte {
|
||||
length := len(password)
|
||||
|
||||
digest := md5.New()
|
||||
|
||||
digest.Write(password)
|
||||
digest.Write(salt)
|
||||
digest.Write(password)
|
||||
|
||||
sumB := digest.Sum(nil)
|
||||
|
||||
digest.Reset()
|
||||
|
||||
digest.Write(password)
|
||||
digest.Write(prefixMD5Crypt)
|
||||
digest.Write(salt)
|
||||
digest.Write(repeat(sumB, length))
|
||||
|
||||
clean(sumB)
|
||||
|
||||
for i := length; i > 0; i >>= 1 {
|
||||
if even(i) {
|
||||
digest.Write(password[0:1])
|
||||
} else {
|
||||
digest.Write([]byte{0})
|
||||
}
|
||||
}
|
||||
|
||||
sumA := digest.Sum(nil)
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
digest.Reset()
|
||||
|
||||
if even(i) {
|
||||
digest.Write(sumA)
|
||||
} else {
|
||||
digest.Write(password)
|
||||
}
|
||||
|
||||
if i%3 != 0 {
|
||||
digest.Write(salt)
|
||||
}
|
||||
|
||||
if i%7 != 0 {
|
||||
digest.Write(password)
|
||||
}
|
||||
|
||||
if i&1 == 0 {
|
||||
digest.Write(password)
|
||||
} else {
|
||||
digest.Write(sumA)
|
||||
}
|
||||
|
||||
copy(sumA, digest.Sum(nil))
|
||||
}
|
||||
|
||||
return permute(sumA, permuteTableMD5Crypt[:])
|
||||
}
|
||||
|
||||
// KeyMD5CryptSun calculates the md5crypt (Sun Version) key given a password, salt, and number rounds.
|
||||
func KeyMD5CryptSun(password, salt []byte, rounds uint32) []byte {
|
||||
digest := md5.New()
|
||||
|
||||
digest.Write(password)
|
||||
|
||||
if rounds == 0 {
|
||||
digest.Write(prefixSunMD5Crypt)
|
||||
digest.Write(salt)
|
||||
digest.Write(sepCrypt)
|
||||
} else {
|
||||
digest.Write(prefixSunMD5CryptRounds)
|
||||
digest.Write([]byte(strconv.FormatUint(uint64(rounds), 10)))
|
||||
digest.Write(sepCrypt)
|
||||
digest.Write(salt)
|
||||
digest.Write(sepCrypt)
|
||||
}
|
||||
|
||||
sumA := digest.Sum(nil)
|
||||
|
||||
iterations := uint32(rounds + 4096)
|
||||
|
||||
bit := func(off uint32) uint32 {
|
||||
off %= 128
|
||||
if (sumA[off/8] & (0x01 << (off % 8))) != 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
var ind7 [md5.Size]byte
|
||||
|
||||
for i := uint32(0); i < iterations; i++ {
|
||||
digest.Reset()
|
||||
|
||||
digest.Write(sumA)
|
||||
|
||||
for j := 0; j < md5.Size; j++ {
|
||||
off := (j + 3) % 16
|
||||
ind4 := (sumA[j] >> (sumA[off] % 5)) & 0x0F
|
||||
sh7 := (sumA[off] >> (sumA[j] % 8)) & 0x01
|
||||
ind7[j] = (sumA[ind4] >> sh7) & 0x7F
|
||||
}
|
||||
|
||||
var indA, indB uint32
|
||||
|
||||
for j := uint(0); j < 8; j++ {
|
||||
indA |= bit(uint32(ind7[j])) << j
|
||||
indB |= bit(uint32(ind7[j+8])) << j
|
||||
}
|
||||
|
||||
indA = (indA >> bit(i)) & 0x7F
|
||||
indB = (indB >> bit(i+64)) & 0x7F
|
||||
|
||||
if bit(indA)^bit(indB) == 1 {
|
||||
digest.Write(magicTableMD5CryptSunHamlet[:])
|
||||
}
|
||||
|
||||
digest.Write([]byte(strconv.FormatUint(uint64(i), 10)))
|
||||
|
||||
copy(sumA, digest.Sum(nil))
|
||||
}
|
||||
|
||||
return permute(sumA, permuteTableMD5Crypt[:])
|
||||
}
|
||||
54
vendor/github.com/go-crypt/x/crypt/util.go
generated
vendored
54
vendor/github.com/go-crypt/x/crypt/util.go
generated
vendored
@@ -1,54 +0,0 @@
|
||||
package crypt
|
||||
|
||||
import (
|
||||
b64 "github.com/go-crypt/x/base64"
|
||||
)
|
||||
|
||||
func permute(sum, table []byte) []byte {
|
||||
size := len(table)
|
||||
|
||||
key := make([]byte, size)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
key[i] = sum[table[i]]
|
||||
}
|
||||
|
||||
return b64.EncodeCrypt(key)
|
||||
}
|
||||
|
||||
func even(i int) bool {
|
||||
return i%2 == 0
|
||||
}
|
||||
|
||||
var (
|
||||
cleanBytes = make([]byte, 64)
|
||||
)
|
||||
|
||||
func clean(b []byte) {
|
||||
l := len(b)
|
||||
|
||||
for ; l > 64; l -= 64 {
|
||||
copy(b[l-64:l], cleanBytes)
|
||||
}
|
||||
|
||||
if l > 0 {
|
||||
copy(b[0:l], cleanBytes[0:l])
|
||||
}
|
||||
}
|
||||
|
||||
func repeat(input []byte, length int) []byte {
|
||||
var (
|
||||
seq = make([]byte, length)
|
||||
unit = len(input)
|
||||
)
|
||||
|
||||
j := length / unit * unit
|
||||
for i := 0; i < j; i += unit {
|
||||
copy(seq[i:length], input)
|
||||
}
|
||||
if j < length {
|
||||
copy(seq[j:length], input[0:length-j])
|
||||
}
|
||||
|
||||
return seq
|
||||
}
|
||||
196
vendor/github.com/testcontainers/testcontainers-go/network/network.go
generated
vendored
Normal file
196
vendor/github.com/testcontainers/testcontainers-go/network/network.go
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/client"
|
||||
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
)
|
||||
|
||||
// New creates a new network with a random UUID name, calling the already existing GenericNetwork APIs.
|
||||
// Those existing APIs are deprecated and will be removed in the future, so this function will
|
||||
// implement the new network APIs when they will be available.
|
||||
// By default, the network is created with the following options:
|
||||
// - Driver: bridge
|
||||
// - Labels: the Testcontainers for Go generic labels, to be managed by Ryuk. Please see the GenericLabels() function
|
||||
// And those options can be modified by the user, using the CreateModifier function field.
|
||||
func New(ctx context.Context, opts ...NetworkCustomizer) (*testcontainers.DockerNetwork, error) {
|
||||
nc := client.NetworkCreateOptions{
|
||||
Driver: "bridge",
|
||||
Labels: testcontainers.GenericLabels(),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt.Customize(&nc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
netReq := testcontainers.NetworkRequest{
|
||||
Driver: nc.Driver,
|
||||
Internal: nc.Internal,
|
||||
EnableIPv6: nc.EnableIPv6,
|
||||
Name: uuid.NewString(),
|
||||
Labels: nc.Labels,
|
||||
Attachable: nc.Attachable,
|
||||
IPAM: nc.IPAM,
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
n, err := testcontainers.GenericNetwork(ctx, testcontainers.GenericNetworkRequest{
|
||||
NetworkRequest: netReq,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Return a DockerNetwork struct instead of the Network interface,
|
||||
// following the "accept interface, return struct" pattern.
|
||||
return n.(*testcontainers.DockerNetwork), nil
|
||||
}
|
||||
|
||||
// NetworkCustomizer is an interface that can be used to configure the network create request.
|
||||
type NetworkCustomizer interface {
|
||||
Customize(req *client.NetworkCreateOptions) error
|
||||
}
|
||||
|
||||
// CustomizeNetworkOption is a type that can be used to configure the network create request.
|
||||
type CustomizeNetworkOption func(req *client.NetworkCreateOptions) error
|
||||
|
||||
// Customize implements the NetworkCustomizer interface,
|
||||
// applying the option to the network create request.
|
||||
func (opt CustomizeNetworkOption) Customize(req *client.NetworkCreateOptions) error {
|
||||
return opt(req)
|
||||
}
|
||||
|
||||
// WithAttachable allows to set the network as attachable.
|
||||
func WithAttachable() CustomizeNetworkOption {
|
||||
return func(original *client.NetworkCreateOptions) error {
|
||||
original.Attachable = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCheckDuplicate allows to check if a network with the same name already exists.
|
||||
//
|
||||
// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client package to older daemons.
|
||||
func WithCheckDuplicate() CustomizeNetworkOption {
|
||||
return func(_ *client.NetworkCreateOptions) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDriver allows to override the default network driver, which is "bridge".
|
||||
func WithDriver(driver string) CustomizeNetworkOption {
|
||||
return func(original *client.NetworkCreateOptions) error {
|
||||
original.Driver = driver
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithEnableIPv6 allows to set the network as IPv6 enabled.
|
||||
// Please use this option if and only if IPv6 is enabled on the Docker daemon.
|
||||
func WithEnableIPv6() CustomizeNetworkOption {
|
||||
return func(original *client.NetworkCreateOptions) error {
|
||||
enableIPv6 := true
|
||||
original.EnableIPv6 = &enableIPv6
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithInternal allows to set the network as internal.
|
||||
func WithInternal() CustomizeNetworkOption {
|
||||
return func(original *client.NetworkCreateOptions) error {
|
||||
original.Internal = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithLabels allows to set the network labels, adding the new ones
|
||||
// to the default Testcontainers for Go labels.
|
||||
func WithLabels(labels map[string]string) CustomizeNetworkOption {
|
||||
return func(original *client.NetworkCreateOptions) error {
|
||||
maps.Copy(original.Labels, labels)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithIPAM allows to change the default IPAM configuration.
|
||||
func WithIPAM(ipam *network.IPAM) CustomizeNetworkOption {
|
||||
return func(original *client.NetworkCreateOptions) error {
|
||||
original.IPAM = ipam
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithNetwork reuses an already existing network, attaching the container to it.
|
||||
// Finally it sets the network alias on that network to the given alias.
|
||||
func WithNetwork(aliases []string, nw *testcontainers.DockerNetwork) testcontainers.CustomizeRequestOption {
|
||||
return WithNetworkName(aliases, nw.Name)
|
||||
}
|
||||
|
||||
// WithNetworkName attachs a container to an already existing network, by its name.
|
||||
// If the network is not "bridge", it sets the network alias on that network
|
||||
// to the given alias, else, it returns an error. This is because network-scoped alias
|
||||
// is supported only for containers in user defined networks.
|
||||
func WithNetworkName(aliases []string, networkName string) testcontainers.CustomizeRequestOption {
|
||||
return func(req *testcontainers.GenericContainerRequest) error {
|
||||
if networkName == "bridge" {
|
||||
return errors.New("network-scoped aliases are supported only for containers in user defined networks")
|
||||
}
|
||||
|
||||
// attaching to the network because it was created with success or it already existed.
|
||||
req.Networks = append(req.Networks, networkName)
|
||||
|
||||
if req.NetworkAliases == nil {
|
||||
req.NetworkAliases = make(map[string][]string)
|
||||
}
|
||||
req.NetworkAliases[networkName] = aliases
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithBridgeNetwork attachs a container to the "bridge" network.
|
||||
// There is no need to set the network alias, as it is not supported for the "bridge" network.
|
||||
func WithBridgeNetwork() testcontainers.CustomizeRequestOption {
|
||||
return func(req *testcontainers.GenericContainerRequest) error {
|
||||
req.Networks = append(req.Networks, "bridge")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithNewNetwork creates a new network with random name and customizers, and attaches the container to it.
|
||||
// Finally it sets the network alias on that network to the given alias.
|
||||
func WithNewNetwork(ctx context.Context, aliases []string, opts ...NetworkCustomizer) testcontainers.CustomizeRequestOption {
|
||||
return func(req *testcontainers.GenericContainerRequest) error {
|
||||
newNetwork, err := New(ctx, opts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("new network: %w", err)
|
||||
}
|
||||
|
||||
networkName := newNetwork.Name
|
||||
|
||||
// attaching to the network because it was created with success or it already existed.
|
||||
req.Networks = append(req.Networks, networkName)
|
||||
|
||||
if req.NetworkAliases == nil {
|
||||
req.NetworkAliases = make(map[string][]string)
|
||||
}
|
||||
req.NetworkAliases[networkName] = aliases
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
11
vendor/modules.txt
vendored
11
vendor/modules.txt
vendored
@@ -487,16 +487,6 @@ github.com/go-chi/chi/v5/middleware
|
||||
# github.com/go-chi/render v1.0.3
|
||||
## explicit; go 1.16
|
||||
github.com/go-chi/render
|
||||
# github.com/go-crypt/crypt v0.4.5
|
||||
## explicit; go 1.23
|
||||
github.com/go-crypt/crypt/algorithm
|
||||
github.com/go-crypt/crypt/algorithm/shacrypt
|
||||
github.com/go-crypt/crypt/internal/encoding
|
||||
github.com/go-crypt/crypt/internal/random
|
||||
# github.com/go-crypt/x v0.4.7
|
||||
## explicit; go 1.23.0
|
||||
github.com/go-crypt/x/base64
|
||||
github.com/go-crypt/x/crypt
|
||||
# github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376
|
||||
## explicit; go 1.13
|
||||
github.com/go-git/gcfg
|
||||
@@ -2141,6 +2131,7 @@ github.com/testcontainers/testcontainers-go/internal/config
|
||||
github.com/testcontainers/testcontainers-go/internal/core
|
||||
github.com/testcontainers/testcontainers-go/internal/core/network
|
||||
github.com/testcontainers/testcontainers-go/log
|
||||
github.com/testcontainers/testcontainers-go/network
|
||||
github.com/testcontainers/testcontainers-go/wait
|
||||
# github.com/testcontainers/testcontainers-go/modules/opensearch v0.42.0
|
||||
## explicit; go 1.25.0
|
||||
|
||||
Reference in New Issue
Block a user