diff --git a/Gopkg.lock b/Gopkg.lock index 487b3c3..8ad23eb 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -23,7 +23,7 @@ branch = "master" name = "github.com/jmoiron/sqlx" packages = [".","reflectx"] - revision = "99f3ad6d85ae53d0fecf788ab62d0e9734b3c117" + revision = "de8647470aafe4854c976707c431dbe1eb2822c6" [[projects]] name = "github.com/mattn/go-sqlite3" @@ -41,13 +41,13 @@ branch = "master" name = "golang.org/x/crypto" packages = ["sha3"] - revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122" + revision = "d585fd2cc9195196078f516b69daff6744ef5e84" [[projects]] branch = "master" name = "golang.org/x/net" packages = ["context"] - revision = "dc871a5d77e227f5bbf6545176ef3eeebf87e76e" + revision = "d866cfc389cec985d6fda2859936a575a55a3ab6" [[projects]] branch = "v2" diff --git a/entity.go b/entity.go index d003155..12613f6 100644 --- a/entity.go +++ b/entity.go @@ -13,7 +13,7 @@ const ENTITY_STATE_TERMINATING = 0 const ENTITY_STATE_NORMAL = 1 const CLIENT_MODES = "cD" -const CHANNEL_MODES = "cDipstz" +const CHANNEL_MODES = "cDimprstz" const CHANNEL_MODES_ARG = "kl" type Entity struct { diff --git a/main.go b/main.go index 1804ee7..57f24c0 100644 --- a/main.go +++ b/main.go @@ -35,7 +35,7 @@ import ( var prefixAnonIRC = irc.Prefix{Name: "AnonIRC"} var prefixAnonymous = irc.Prefix{Name: "Anonymous", User: "Anon", Host: "IRC"} -const motd = ` +const DEFAULT_MOTD = ` _|_| _|_|_| _|_|_| _|_|_| _| _| _|_|_| _|_| _|_|_| _| _| _| _| _|_|_|_| _| _| _| _| _| _| _| _|_|_| _| diff --git a/server.go b/server.go index 0938423..8ac7c86 100644 --- a/server.go +++ b/server.go @@ -33,6 +33,9 @@ const ( COMMAND_USERNAME = "USERNAME" COMMAND_PASSWORD = "PASSWORD" + // User/channel commands + COMMAND_MODE = "MODE" + // Channel/server commands COMMAND_FOUND = "FOUND" COMMAND_DROP = "DROP" @@ -42,7 +45,7 @@ const ( COMMAND_BAN = "BAN" COMMAND_AUDIT = "AUDIT" - // Server admins only + // Server admin commands COMMAND_KILL = "KILL" COMMAND_STATS = "STATS" COMMAND_REHASH = "REHASH" @@ -51,6 +54,7 @@ const ( var serverCommands = []string{COMMAND_KILL, COMMAND_STATS, COMMAND_REHASH, COMMAND_UPGRADE} +// TODO: Reorder const ( PERMISSION_CLIENT = 0 PERMISSION_REGISTERED = 1 @@ -69,11 +73,11 @@ var permissionLabels = map[int]string{ PERMISSION_SUPERADMIN: "Super Administrator", } -var ALL_PERMISSIONS = "Client, Registered Client, VIP, Moderator, Adminsitrator and Super Administrator" +var ALL_PERMISSIONS = "Client, Registered Client, VIP, Moderator, Administrator and Super Administrator" var commandRestrictions = map[int][]string{ PERMISSION_REGISTERED: {COMMAND_TOKEN, COMMAND_USERNAME, COMMAND_PASSWORD, COMMAND_FOUND}, - PERMISSION_MODERATOR: {COMMAND_REVEAL, COMMAND_KICK, COMMAND_BAN}, + PERMISSION_MODERATOR: {COMMAND_MODE, COMMAND_REVEAL, COMMAND_KICK, COMMAND_BAN}, PERMISSION_ADMIN: {COMMAND_GRANT, COMMAND_AUDIT}, PERMISSION_SUPERADMIN: {COMMAND_DROP, COMMAND_KILL, COMMAND_STATS, COMMAND_REHASH, COMMAND_UPGRADE}} @@ -81,7 +85,7 @@ var helpDuration = "Duration can be 0 to never expire, or e.g. 30m, 1h, 2d, 3w" var commandUsage = map[string][]string{ COMMAND_HELP: {"[command|all]", "Print usage information regarding a specific command or 'all'", - "Without a command or 'all', only commands currently available are printed"}, + "Without a command or 'all', only commands you have permission to use are printed"}, COMMAND_INFO: {"[channel]", "When a channel is specified, prints info including whether it is registered", "Without a channel, server info is printed"}, @@ -135,6 +139,7 @@ var commandUsage = map[string][]string{ } type Config struct { + MOTD string Salt string DBDriver string DBSource string @@ -146,6 +151,7 @@ type Server struct { config *Config configfile string created int64 + motd []string clients *sync.Map channels *sync.Map odyssey *os.File @@ -314,6 +320,54 @@ func (s *Server) inChannel(channel string, client string) bool { return false } +func (s *Server) canAccessChannel(c *Client, channel string) (bool, string) { + dbch, err := db.Channel(channel) + if err != nil || dbch.Channel == "" { + return false, "invalid channel" + } + ch := s.getChannel(channel) + if ch == nil { + return false, "invalid channel" + } else if banned, reason := c.isBanned(channel); banned { + if reason != "" { + reason = fmt.Sprintf(" (%s)", reason) + } + return false, "you are banned" + reason + } else if ch.hasMode("z") && !c.ssl { + return false, "only clients connected via SSL are allowed" + } + + permission := c.globalPermission() + requiredPermission := PERMISSION_CLIENT + reason := "" + + if channel[0] == '&' { + if permission < PERMISSION_VIP { + return false, "restricted channel" + } + } else if channel[0] != '#' { + return false, "invalid channel" + } + + if permission < requiredPermission && c.account > 0 { + chp, err := db.GetPermission(c.account, channel) + if err != nil && chp.Permission > permission { + permission = chp.Permission + } + } + + if ch.hasMode("r") { + requiredPermission = PERMISSION_REGISTERED + reason = "only registered clients are allowed" + } + if ch.hasMode("i") { + requiredPermission = PERMISSION_VIP + reason = "only VIP are allowed" + } + + return permission >= requiredPermission, reason +} + func (s *Server) joinChannel(channel string, client string) { if s.inChannel(channel, client) { return // Already in channel @@ -324,33 +378,14 @@ func (s *Server) joinChannel(channel string, client string) { return } - if len(channel) == 0 { - return - } else if channel[0] == '&' { - if cl.globalPermission() < PERMISSION_VIP { - cl.accessDenied(0) - return - } - } else if channel[0] != '#' { - return - } - ch := s.getChannel(channel) if ch == nil { ch = NewChannel(channel) s.channels.Store(channel, ch) - } else if ch.hasMode("z") && !cl.ssl { - cl.sendNotice("Unable to join " + channel + ": SSL connections only (channel mode +z)") - return - } - - banned, reason := cl.isBanned(channel) - if banned { - ex := "" - if reason != "" { - ex = ". Reason: " + reason - } - cl.sendNotice("Unable to join " + channel + ": You are banned" + ex) + } else if canaccess, reason := s.canAccessChannel(cl, channel); !canaccess { + errmsg := fmt.Sprintf("Cannot join %s: %s", channel, reason) + cl.writeMessage(irc.ERR_INVITEONLYCHAN, []string{channel, errmsg}) + cl.sendNotice(errmsg) return } @@ -391,7 +426,6 @@ func (s *Server) revealChannelLog(channel string, client string, page int, showA return } - // TODO: Check channel permission ch := s.getChannel(channel) if ch == nil { cl.sendError("Unable to reveal, invalid channel specified") @@ -574,125 +608,140 @@ func (s *Server) handleTopic(channel string, client string, topic string) { ch.Log(cl, irc.TOPIC, ch.topic) } -func (s *Server) handleMode(c *Client, params []string) { - if len(params) == 0 || len(params[0]) == 0 { - c.sendNotice("Invalid use of MODE") - return - } - - if len(params) > 1 && params[1] == "b" { - c.writeMessage(irc.RPL_ENDOFBANLIST, []string{params[0], "End of Channel Ban List"}) +func (s *Server) handleChannelMode(c *Client, params []string) { + ch := s.getChannel(params[0]) + if ch == nil || !s.inChannel(params[0], c.identifier) { return } - if validChannelPrefix(params[0]) { - ch := s.getChannel(params[0]) + if len(params) == 1 || params[1] == "" { + c.writeMessage(strings.Join([]string{irc.RPL_CHANNELMODEIS, c.nick, params[0], ch.printModes(ch.getModes(), nil)}, " "), []string{}) - if ch == nil { + // Send channel creation time + c.writeMessage(strings.Join([]string{"329", c.nick, params[0], fmt.Sprintf("%d", int32(ch.created))}, " "), []string{}) + } else if len(params) > 1 && (params[1] == "" || params[1][0] == '+' || params[1][0] == '-') { + if !c.canUse(COMMAND_MODE, params[0]) { + c.accessDenied(c.permissionRequired(COMMAND_MODE)) return } - if len(params) == 1 || params[1] == "" { - c.writeMessage(strings.Join([]string{irc.RPL_CHANNELMODEIS, c.nick, params[0], ch.printModes(ch.getModes(), nil)}, " "), []string{}) - - // Send channel creation time - c.writeMessage(strings.Join([]string{"329", c.nick, params[0], fmt.Sprintf("%d", int32(ch.created))}, " "), []string{}) - } else if len(params) > 1 && len(params[1]) > 0 && params[1][0] == '+' || params[1][0] == '-' { - if !c.canUse(irc.MODE, params[0]) { - c.accessDenied(c.permissionRequired(irc.MODE)) - return - } + lastmodes := make(map[string]string) + for m, mv := range ch.getModes() { + lastmodes[m] = mv + } - lastmodes := make(map[string]string) - for m, mv := range ch.getModes() { - lastmodes[m] = mv - } + if params[1][0] == '+' { + ch.addModes(params[1][1:]) + } else { + ch.removeModes(params[1][1:]) + } + s.enforceModes(params[0]) - if params[1][0] == '+' { - ch.addModes(params[1][1:]) - } else { - ch.removeModes(params[1][1:]) - } - s.enforceModes(params[0]) + if reflect.DeepEqual(ch.getModes(), lastmodes) { + return + } - if !reflect.DeepEqual(ch.getModes(), lastmodes) { - // TODO: Check if local modes were set/unset, only send changes to local client - addedmodes, removedmodes := ch.diffModes(lastmodes) + // TODO: Check if local modes were set/unset, only send changes to local client + addedmodes, removedmodes := ch.diffModes(lastmodes) - resendusercount := false - if _, ok := addedmodes["c"]; ok { - resendusercount = true - } - if _, ok := removedmodes["c"]; ok { - resendusercount = true - } - if _, ok := removedmodes["D"]; ok { - resendusercount = true - } + resendusercount := false + if _, ok := addedmodes["c"]; ok { + resendusercount = true + } + if _, ok := removedmodes["c"]; ok { + resendusercount = true + } + if _, ok := removedmodes["D"]; ok { + resendusercount = true + } - if len(addedmodes) == 0 && len(removedmodes) == 0 { - addedmodes = c.getModes() - } + if len(addedmodes) == 0 && len(removedmodes) == 0 { + addedmodes = c.getModes() + } - ch.clients.Range(func(k, v interface{}) bool { - cl := s.getClient(k.(string)) - if cl != nil { - cl.write(&prefixAnonymous, irc.MODE, []string{params[0], ch.printModes(addedmodes, removedmodes)}) - } + ch.clients.Range(func(k, v interface{}) bool { + cl := s.getClient(k.(string)) + if cl != nil { + cl.write(&prefixAnonymous, irc.MODE, []string{params[0], ch.printModes(addedmodes, removedmodes)}) + } - return true - }) + return true + }) - if resendusercount { - s.updateClientCount(params[0], c.identifier, "Enforcing MODEs") - } - } - } - } else { - if len(params) == 1 || params[1] == "" { - c.writeMessage(strings.Join([]string{irc.RPL_UMODEIS, c.nick, c.printModes(c.getModes(), nil)}, " "), []string{}) - return + if resendusercount { + s.updateClientCount(params[0], c.identifier, "Enforcing MODEs") } + } +} - lastmodes := c.getModes() +func (s *Server) handleUserMode(c *Client, params []string) { + if len(params) == 1 || params[1] == "" { + c.writeMessage(strings.Join([]string{irc.RPL_UMODEIS, c.nick, c.printModes(c.getModes(), nil)}, " "), []string{}) + return + } - if len(params) > 1 && len(params[1]) > 0 && (params[1][0] == '+' || params[1][0] == '-') { - if params[1][0] == '+' { - c.addModes(params[1][1:]) - } else { - c.removeModes(params[1][1:]) - } + lastmodes := c.getModes() + + if len(params) > 1 && len(params[1]) > 0 && (params[1][0] == '+' || params[1][0] == '-') { + if params[1][0] == '+' { + c.addModes(params[1][1:]) + } else { + c.removeModes(params[1][1:]) } + } - if !reflect.DeepEqual(c.modes, lastmodes) { - addedmodes, removedmodes := c.diffModes(lastmodes) + if reflect.DeepEqual(c.modes, lastmodes) { + return + } - resendusercount := false - if _, ok := addedmodes["c"]; ok { - resendusercount = true - } - if _, ok := removedmodes["c"]; ok { - resendusercount = true - } - if _, ok := removedmodes["D"]; ok { - resendusercount = true - } + addedmodes, removedmodes := c.diffModes(lastmodes) - if len(addedmodes) == 0 && len(removedmodes) == 0 { - addedmodes = c.getModes() - } + resendusercount := false + if _, ok := addedmodes["c"]; ok { + resendusercount = true + } + if _, ok := removedmodes["c"]; ok { + resendusercount = true + } + if _, ok := removedmodes["D"]; ok { + resendusercount = true + } - c.writeMessage(strings.Join([]string{irc.MODE, c.nick}, " "), []string{c.printModes(addedmodes, removedmodes)}) + if len(addedmodes) == 0 && len(removedmodes) == 0 { + addedmodes = c.getModes() + } - if resendusercount { - for ch := range s.getChannels(c.identifier) { - s.updateClientCount(ch, c.identifier, "Enforcing MODEs") - } - } + c.writeMessage(strings.Join([]string{irc.MODE, c.nick}, " "), []string{c.printModes(addedmodes, removedmodes)}) + + if resendusercount { + for ch := range s.getChannels(c.identifier) { + s.updateClientCount(ch, c.identifier, "Enforcing MODEs") } } } +func (s *Server) handleMode(c *Client, params []string) { + if c == nil { + return + } + + if len(params) == 0 || len(params[0]) == 0 { + c.sendNotice("Invalid use of MODE") + return + } + + if len(params) > 1 && params[1] == "b" { + c.writeMessage(irc.RPL_ENDOFBANLIST, []string{params[0], "End of Channel Ban List"}) + return + } + + if params[0][0] == '#' || params[0][0] == '&' { + s.handleChannelMode(c, params) + } else { + s.handleUserMode(c, params) + } +} + func (s *Server) sendUsage(cl *Client, command string) { command = strings.ToUpper(command) @@ -776,7 +825,7 @@ func (s *Server) ban(channel string, iphash string, accountid int64, expires int return err } } - + log.Println("B") if accountid > 0 { b = DBBan{Channel: generateHash(channel), Type: BAN_TYPE_ACCOUNT, Target: fmt.Sprintf("%d", accountid), Expires: expires} err := db.AddBan(b) @@ -784,9 +833,8 @@ func (s *Server) ban(channel string, iphash string, accountid int64, expires int return err } } - + log.Println("C") if b.Channel == "" { - log.Println("blank chan") return nil } @@ -796,7 +844,7 @@ func (s *Server) ban(channel string, iphash string, accountid int64, expires int ch = "" rs = formatAction("Killed", reason) } - + log.Println("D") cls := s.getClients(ch) for _, cl := range cls { if cl == nil { @@ -841,8 +889,27 @@ func (s *Server) handleUserCommand(client string, command string, params []strin s.sendUsage(cl, cmd) return case COMMAND_INFO: - // TODO: when channel is supplied, send whether it is registered and show a notice that it is dropping soon if no super admins have logged in in X days - cl.sendMessage("Server info: AnonIRCd https://github.com/sageru-6ch/anonircd") + if len(params) > 0 && len(params[0]) > 0 { + if canaccess, reason := s.canAccessChannel(cl, params[0]); !canaccess { + cl.sendError("Failed to fetch channel INFO, " + reason) + return + } + + dbch, err := db.Channel(params[0]) + if err != nil { + cl.sendError("Failed to fetch channel INFO, " + err.Error()) + return + } + + chst := "Unfounded" + if dbch.Channel != "" { + chst = "Founded" + } + + cl.sendMessage(fmt.Sprintf("%s: %s", params[0], chst)) + } else { + cl.sendMessage("AnonIRCd https://github.com/sageru-6ch/anonircd") + } return case COMMAND_REGISTER: if len(params) == 0 { @@ -945,7 +1012,6 @@ func (s *Server) handleUserCommand(client string, command string, params []strin } cl.sendMessage("Password changed successfully") case COMMAND_REVEAL, COMMAND_AUDIT: - // TODO: &#chan shows moderator audit log, & alone shows server admin audit log if len(params) == 0 { s.sendUsage(cl, command) return @@ -1044,6 +1110,7 @@ func (s *Server) handleUserCommand(client string, command string, params []strin bch = CHANNEL_SERVER } err := s.ban(bch, rcl.iphash, rcl.account, expires, reason) + log.Println("A") if err != nil { cl.sendError(fmt.Sprintf("Unable to %s, %v", strings.ToLower(command), err)) return @@ -1051,7 +1118,6 @@ func (s *Server) handleUserCommand(client string, command string, params []strin cl.sendMessage(fmt.Sprintf("%sed %s %s", strings.ToLower(command), params[0], params[1])) case COMMAND_STATS: - cl.sendMessage(fmt.Sprintf("%d clients in %d channels", s.clientCount(), s.channelCount())) case COMMAND_REHASH: @@ -1066,41 +1132,46 @@ func (s *Server) handleUserCommand(client string, command string, params []strin } } -func (s *Server) handlePrivmsg(channel string, client string, message string) { +func (s *Server) handlePrivmsg(target string, client string, message string) { cl := s.getClient(client) - if cl == nil { + if cl == nil || len(target) == 0 { return } - if strings.ToLower(channel) == "anonirc" { + if strings.ToLower(target) == "anonirc" { params := strings.Split(message, " ") - if len(params) > 0 && len(params[0]) > 0 { - var otherparams []string - if len(params) > 1 { - otherparams = params[1:] - } + if len(params) == 0 || len(params[0]) == 0 { + return + } - s.handleUserCommand(client, params[0], otherparams) + var otherparams []string + if len(params) > 1 { + otherparams = params[1:] } + s.handleUserCommand(client, params[0], otherparams) return - } else if channel == "" || !validChannelPrefix(channel) { + } else if target[0] != '#' && target[0] != '&' { + cl.writeMessage(irc.ERR_NOSUCHNICK, []string{target, "No such nick/channel"}) + return + } else if !s.inChannel(target, client) { + cl.writeMessage(irc.ERR_CANNOTSENDTOCHAN, []string{target, fmt.Sprintf("No external channel messages (%s)", target)}) return - } else if !s.inChannel(channel, client) { - return // Not in channel } - ch := s.getChannel(channel) + ch := s.getChannel(target) if ch == nil { return + } else if ch.hasMode("m") && cl.getPermission(target) < PERMISSION_VIP { + cl.writeMessage(irc.ERR_CANNOTSENDTOCHAN, []string{target, fmt.Sprintf("Channel is moderated, only VIP may speak (%s)", target)}) + return } - s.updateClientCount(channel, "", "") - + s.updateClientCount(target, "", "") ch.clients.Range(func(k, v interface{}) bool { chcl := s.getClient(k.(string)) if chcl != nil && chcl.identifier != client { - chcl.write(&prefixAnonymous, irc.PRIVMSG, []string{channel, message}) + chcl.write(&prefixAnonymous, irc.PRIVMSG, []string{target, message}) } return true @@ -1114,19 +1185,19 @@ func (s *Server) handleRead(c *Client) { return } - c.conn.SetReadDeadline(time.Now().Add(300 * time.Second)) - if _, ok := s.clients.Load(c.identifier); !ok { s.killClient(c, "") return } + c.conn.SetReadDeadline(time.Now().Add(300 * time.Second)) msg, err := c.reader.Decode() if msg == nil || err != nil { // Error decoding message, client probably disconnected s.killClient(c, "") return } + if debugMode && (verbose || len(msg.Command) < 4 || (msg.Command[0:4] != irc.PING && msg.Command[0:4] != irc.PONG)) { log.Printf("%s -> %s", c.identifier, msg) } @@ -1142,12 +1213,11 @@ func (s *Server) handleRead(c *Client) { c.writeMessage(irc.RPL_CREATED, []string{fmt.Sprintf("This server was created %s", time.Unix(s.created, 0).UTC())}) c.writeMessage(strings.Join([]string{irc.RPL_MYINFO, c.nick, "AnonIRC", "AnonIRCd", CLIENT_MODES, CHANNEL_MODES, CHANNEL_MODES_ARG}, " "), []string{}) - motdsplit := strings.Split(motd, "\n") - for i, motdmsg := range motdsplit { + for i, motdmsg := range s.motd { var motdcode string if i == 0 { motdcode = irc.RPL_MOTDSTART - } else if i < len(motdsplit)-1 { + } else if i < len(s.motd)-1 { motdcode = irc.RPL_MOTD } else { motdcode = irc.RPL_ENDOFMOTD @@ -1335,23 +1405,27 @@ func (s *Server) handleConnection(conn net.Conn, ssl bool) { } } - client := NewClient(identifier, conn, ssl) + c := NewClient(identifier, conn, ssl) banned := true reason := "" - if client != nil { - banned, reason = client.isBanned("") - } - if banned { - // TODO: Send banned message - _ = reason - return // Banned + if c != nil { + banned, reason = c.isBanned(CHANNEL_SERVER) } - s.clients.Store(client.identifier, client) - go s.handleWrite(client) - s.handleRead(client) // Block until the connection is closed + go s.handleWrite(c) + if !banned { + s.clients.Store(c.identifier, c) + s.handleRead(c) // Block until the connection is closed + } else { + if reason != "" { + reason = fmt.Sprintf(" (%s)", reason) + } + c.writeMessage(irc.ERR_YOUREBANNEDCREEP, []string{"You are banned from this server" + reason}) + time.Sleep(1 * time.Second) + } - s.killClient(client, "") + s.killClient(c, "") + s.clients.Delete(identifier) } func (s *Server) killClient(c *Client, reason string) { @@ -1493,6 +1567,12 @@ func (s *Server) loadConfig() error { return errors.New(fmt.Sprintf("DBDriver and DBSource must be configured in %s\nExample:\n\nDBDriver=\"sqlite3\"\nDBSource=\"/home/user/anonircd/anonircd.db\"", s.configfile)) } + motd := DEFAULT_MOTD + if s.config.MOTD != "" { + motd = s.config.MOTD + } + s.motd = strings.Split(strings.TrimRight(motd, " \t\r\n"), "\n") + return nil } diff --git a/utilities.go b/utilities.go index f139256..d219835 100644 --- a/utilities.go +++ b/utilities.go @@ -55,10 +55,6 @@ func randomIdentifier() string { return string(b) } -func validChannelPrefix(channel string) bool { - return channel[0] == '&' || channel[0] == '#' -} - func generateHash(s string) string { sha512 := sha3.New512() _, err := sha512.Write([]byte(strings.Join([]string{s, fmt.Sprintf("%x", md5.Sum([]byte(s))), s}, "-"))) diff --git a/vendor/github.com/jmoiron/sqlx/named.go b/vendor/github.com/jmoiron/sqlx/named.go index dd899d3..69eb954 100644 --- a/vendor/github.com/jmoiron/sqlx/named.go +++ b/vendor/github.com/jmoiron/sqlx/named.go @@ -163,16 +163,18 @@ func bindArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{ v = v.Elem() } - fields := m.TraversalsByName(v.Type(), names) - for i, t := range fields { + err := m.TraversalsByNameFunc(v.Type(), names, func(i int, t []int) error { if len(t) == 0 { - return arglist, fmt.Errorf("could not find name %s in %#v", names[i], arg) + return fmt.Errorf("could not find name %s in %#v", names[i], arg) } + val := reflectx.FieldByIndexesReadOnly(v, t) arglist = append(arglist, val.Interface()) - } - return arglist, nil + return nil + }) + + return arglist, err } // like bindArgs, but for maps. diff --git a/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go b/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go index f2802b8..73c21eb 100644 --- a/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go +++ b/vendor/github.com/jmoiron/sqlx/reflectx/reflect.go @@ -166,20 +166,39 @@ func (m *Mapper) FieldsByName(v reflect.Value, names []string) []reflect.Value { // traversals for each mapped name. Panics if t is not a struct or Indirectable // to a struct. Returns empty int slice for each name not found. func (m *Mapper) TraversalsByName(t reflect.Type, names []string) [][]int { + r := make([][]int, 0, len(names)) + m.TraversalsByNameFunc(t, names, func(_ int, i []int) error { + if i == nil { + r = append(r, []int{}) + } else { + r = append(r, i) + } + + return nil + }) + return r +} + +// TraversalsByNameFunc traverses the mapped names and calls fn with the index of +// each name and the struct traversal represented by that name. Panics if t is not +// a struct or Indirectable to a struct. Returns the first error returned by fn or nil. +func (m *Mapper) TraversalsByNameFunc(t reflect.Type, names []string, fn func(int, []int) error) error { t = Deref(t) mustBe(t, reflect.Struct) tm := m.TypeMap(t) - - r := make([][]int, 0, len(names)) - for _, name := range names { + for i, name := range names { fi, ok := tm.Names[name] if !ok { - r = append(r, []int{}) + if err := fn(i, nil); err != nil { + return err + } } else { - r = append(r, fi.Index) + if err := fn(i, fi.Index); err != nil { + return err + } } } - return r + return nil } // FieldByIndexes returns a value for the field given by the struct traversal diff --git a/vendor/github.com/jmoiron/sqlx/reflectx/reflect_test.go b/vendor/github.com/jmoiron/sqlx/reflectx/reflect_test.go index b702f9c..d3879ed 100644 --- a/vendor/github.com/jmoiron/sqlx/reflectx/reflect_test.go +++ b/vendor/github.com/jmoiron/sqlx/reflectx/reflect_test.go @@ -903,3 +903,72 @@ func BenchmarkFieldByIndexL4(b *testing.B) { } } } + +func BenchmarkTraversalsByName(b *testing.B) { + type A struct { + Value int + } + + type B struct { + A A + } + + type C struct { + B B + } + + type D struct { + C C + } + + m := NewMapper("") + t := reflect.TypeOf(D{}) + names := []string{"C", "B", "A", "Value"} + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + if l := len(m.TraversalsByName(t, names)); l != len(names) { + b.Errorf("expected %d values, got %d", len(names), l) + } + } +} + +func BenchmarkTraversalsByNameFunc(b *testing.B) { + type A struct { + Z int + } + + type B struct { + A A + } + + type C struct { + B B + } + + type D struct { + C C + } + + m := NewMapper("") + t := reflect.TypeOf(D{}) + names := []string{"C", "B", "A", "Z", "Y"} + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + var l int + + if err := m.TraversalsByNameFunc(t, names, func(_ int, _ []int) error { + l++ + return nil + }); err != nil { + b.Errorf("unexpected error %s", err) + } + + if l != len(names) { + b.Errorf("expected %d values, got %d", len(names), l) + } + } +} \ No newline at end of file diff --git a/vendor/golang.org/x/crypto/argon2/argon2.go b/vendor/golang.org/x/crypto/argon2/argon2.go new file mode 100644 index 0000000..61216e8 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/argon2.go @@ -0,0 +1,219 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package argon2 implements the key derivation function Argon2. +// Argon2 was selected as the winner of the Password Hashing Competition and can +// be used to derive cryptographic keys from passwords. +// Argon2 is specfifed at https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf +package argon2 + +import ( + "encoding/binary" + "sync" + + "golang.org/x/crypto/blake2b" +) + +// The Argon2 version implemented by this package. +const Version = 0x13 + +const ( + argon2d = iota + argon2i + argon2id +) + +// Key derives a key from the password, salt, and cost parameters using Argon2i +// returning a byte slice of length keyLen that can be used as cryptographic key. +// The CPU cost and parallism degree must be greater than zero. +// +// For example, you can get a derived key for e.g. AES-256 (which needs a 32-byte key) by doing: +// `key := argon2.Key([]byte("some password"), salt, 4, 32*1024, 4, 32)` +// +// The recommended parameters for interactive logins as of 2017 are time=4, memory=32*1024. +// The number of threads can be adjusted to the numbers of available CPUs. +// The time parameter specifies the number of passes over the memory and the memory +// parameter specifies the size of the memory in KiB. For example memory=32*1024 sets the +// memory cost to ~32 MB. +// The cost parameters should be increased as memory latency and CPU parallelism increases. +// Remember to get a good random salt. +func Key(password, salt []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { + return deriveKey(argon2i, password, salt, nil, nil, time, memory, threads, keyLen) +} + +func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint32, threads uint8, keyLen uint32) []byte { + if time < 1 { + panic("argon2: number of rounds too small") + } + if threads < 1 { + panic("argon2: paralisim degree too low") + } + mem := memory / (4 * uint32(threads)) * (4 * uint32(threads)) + if mem < 8*uint32(threads) { + mem = 8 * uint32(threads) + } + B := initBlocks(password, salt, secret, data, time, mem, uint32(threads), keyLen, mode) + processBlocks(B, time, mem, uint32(threads), mode) + return extractKey(B, mem, uint32(threads), keyLen) +} + +const blockLength = 128 + +type block [blockLength]uint64 + +func initBlocks(password, salt, key, data []byte, time, memory, threads, keyLen uint32, mode int) []block { + var ( + block0 [1024]byte + h0 [blake2b.Size + 8]byte + params [24]byte + tmp [4]byte + ) + + b2, _ := blake2b.New512(nil) + binary.LittleEndian.PutUint32(params[0:4], threads) + binary.LittleEndian.PutUint32(params[4:8], keyLen) + binary.LittleEndian.PutUint32(params[8:12], memory) + binary.LittleEndian.PutUint32(params[12:16], time) + binary.LittleEndian.PutUint32(params[16:20], uint32(Version)) + binary.LittleEndian.PutUint32(params[20:24], uint32(mode)) + b2.Write(params[:]) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(password))) + b2.Write(tmp[:]) + b2.Write(password) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(salt))) + b2.Write(tmp[:]) + b2.Write(salt) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(key))) + b2.Write(tmp[:]) + b2.Write(key) + binary.LittleEndian.PutUint32(tmp[:], uint32(len(data))) + b2.Write(tmp[:]) + b2.Write(data) + b2.Sum(h0[:0]) + + B := make([]block, memory) + for lane := uint32(0); lane < threads; lane++ { + j := lane * (memory / threads) + binary.LittleEndian.PutUint32(h0[blake2b.Size+4:], lane) + + binary.LittleEndian.PutUint32(h0[blake2b.Size:], 0) + blake2bHash(block0[:], h0[:]) + for i := range B[0] { + B[j+0][i] = binary.LittleEndian.Uint64(block0[i*8:]) + } + + binary.LittleEndian.PutUint32(h0[blake2b.Size:], 1) + blake2bHash(block0[:], h0[:]) + for i := range B[0] { + B[j+1][i] = binary.LittleEndian.Uint64(block0[i*8:]) + } + } + return B +} + +func processBlocks(B []block, time, memory, threads uint32, mode int) { + const syncPoints = 4 + lanes := memory / threads + segments := lanes / syncPoints + + processSegment := func(n, slice, lane uint32, wg *sync.WaitGroup) { + var addresses, in, zero block + if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) { + in[0] = uint64(n) + in[1] = uint64(lane) + in[2] = uint64(slice) + in[3] = uint64(memory) + in[4] = uint64(time) + in[5] = uint64(mode) + } + + index := uint32(0) + if n == 0 && slice == 0 { + index = 2 // we have already generated the first two blocks + if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) { + in[6]++ + processBlock(&addresses, &in, &zero) + processBlock(&addresses, &addresses, &zero) + } + } + + offset := lane*lanes + slice*segments + index + var random uint64 + for index < segments { + prev := offset - 1 + if index == 0 && slice == 0 { + prev = lane*lanes + lanes - 1 // last block in lane + } + if mode == argon2i || (mode == argon2id && n == 0 && slice < syncPoints/2) { + if index%blockLength == 0 { + in[6]++ + processBlock(&addresses, &in, &zero) + processBlock(&addresses, &addresses, &zero) + } + random = addresses[index%blockLength] + } else { + random = B[prev][0] + } + newOffset := indexAlpha(random, lanes, segments, threads, n, slice, lane, index) + processBlockXOR(&B[offset], &B[prev], &B[newOffset]) + index, offset = index+1, offset+1 + } + wg.Done() + } + + for n := uint32(0); n < time; n++ { + for slice := uint32(0); slice < syncPoints; slice++ { + var wg sync.WaitGroup + for lane := uint32(0); lane < threads; lane++ { + wg.Add(1) + go processSegment(n, slice, lane, &wg) + } + wg.Wait() + } + } + +} + +func extractKey(B []block, memory, threads, keyLen uint32) []byte { + lanes := memory / threads + for lane := uint32(0); lane < threads-1; lane++ { + for i, v := range B[(lane*lanes)+lanes-1] { + B[memory-1][i] ^= v + } + } + + var block [1024]byte + for i, v := range B[memory-1] { + binary.LittleEndian.PutUint64(block[i*8:], v) + } + key := make([]byte, keyLen) + blake2bHash(key, block[:]) + return key +} + +func indexAlpha(rand uint64, lanes, segments, threads, n, slice, lane, index uint32) uint32 { + refLane := uint32(rand>>32) % threads + + m, s := 3*segments, (slice+1)%4*segments + if lane == refLane { + m += index + } + if n == 0 { + m, s = slice*segments, 0 + if slice == 0 || lane == refLane { + m += index + } + } + if index == 0 || lane == refLane { + m-- + } + return phi(rand, uint64(m), uint64(s), refLane, lanes) +} + +func phi(rand, m, s uint64, lane, lanes uint32) uint32 { + p := rand & 0xFFFFFFFF + p = (p * p) >> 32 + p = (p * m) >> 32 + return lane*lanes + uint32((s+m-(p+1))%uint64(lanes)) +} diff --git a/vendor/golang.org/x/crypto/argon2/argon2_test.go b/vendor/golang.org/x/crypto/argon2/argon2_test.go new file mode 100644 index 0000000..3f72c75 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/argon2_test.go @@ -0,0 +1,113 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package argon2 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +var ( + genKatPassword = []byte{ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + } + genKatSalt = []byte{0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} + genKatSecret = []byte{0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03} + genKatAAD = []byte{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04} +) + +func TestArgon2(t *testing.T) { + defer func(sse4 bool) { useSSE4 = sse4 }(useSSE4) + + if useSSE4 { + t.Log("SSE4.1 version") + testArgon2i(t) + testArgon2d(t) + testArgon2id(t) + useSSE4 = false + } + t.Log("generic version") + testArgon2i(t) + testArgon2d(t) + testArgon2id(t) +} + +func testArgon2d(t *testing.T) { + want := []byte{ + 0x51, 0x2b, 0x39, 0x1b, 0x6f, 0x11, 0x62, 0x97, + 0x53, 0x71, 0xd3, 0x09, 0x19, 0x73, 0x42, 0x94, + 0xf8, 0x68, 0xe3, 0xbe, 0x39, 0x84, 0xf3, 0xc1, + 0xa1, 0x3a, 0x4d, 0xb9, 0xfa, 0xbe, 0x4a, 0xcb, + } + hash := deriveKey(argon2d, genKatPassword, genKatSalt, genKatSecret, genKatAAD, 3, 32, 4, 32) + if !bytes.Equal(hash, want) { + t.Errorf("derived key does not match - got: %s , want: %s", hex.EncodeToString(hash), hex.EncodeToString(want)) + } +} + +func testArgon2i(t *testing.T) { + want := []byte{ + 0xc8, 0x14, 0xd9, 0xd1, 0xdc, 0x7f, 0x37, 0xaa, + 0x13, 0xf0, 0xd7, 0x7f, 0x24, 0x94, 0xbd, 0xa1, + 0xc8, 0xde, 0x6b, 0x01, 0x6d, 0xd3, 0x88, 0xd2, + 0x99, 0x52, 0xa4, 0xc4, 0x67, 0x2b, 0x6c, 0xe8, + } + hash := deriveKey(argon2i, genKatPassword, genKatSalt, genKatSecret, genKatAAD, 3, 32, 4, 32) + if !bytes.Equal(hash, want) { + t.Errorf("derived key does not match - got: %s , want: %s", hex.EncodeToString(hash), hex.EncodeToString(want)) + } +} + +func testArgon2id(t *testing.T) { + want := []byte{ + 0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c, + 0x08, 0xc0, 0x37, 0xa3, 0x4a, 0x8b, 0x53, 0xc9, + 0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e, + 0xb5, 0x25, 0x20, 0xe9, 0x6b, 0x01, 0xe6, 0x59, + } + hash := deriveKey(argon2id, genKatPassword, genKatSalt, genKatSecret, genKatAAD, 3, 32, 4, 32) + if !bytes.Equal(hash, want) { + t.Errorf("derived key does not match - got: %s , want: %s", hex.EncodeToString(hash), hex.EncodeToString(want)) + } +} + +func benchmarkArgon2(mode int, time, memory uint32, threads uint8, keyLen uint32, b *testing.B) { + password := []byte("password") + salt := []byte("choosing random salts is hard") + b.ReportAllocs() + for i := 0; i < b.N; i++ { + deriveKey(mode, password, salt, nil, nil, time, memory, threads, keyLen) + } +} + +func BenchmarkArgon2i(b *testing.B) { + b.Run(" Time: 3 Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2i, 3, 32*1024, 1, 32, b) }) + b.Run(" Time: 4 Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2i, 4, 32*1024, 1, 32, b) }) + b.Run(" Time: 5 Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2i, 5, 32*1024, 1, 32, b) }) + b.Run(" Time: 3 Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2i, 3, 64*1024, 4, 32, b) }) + b.Run(" Time: 4 Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2i, 4, 64*1024, 4, 32, b) }) + b.Run(" Time: 5 Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2i, 5, 64*1024, 4, 32, b) }) +} + +func BenchmarkArgon2d(b *testing.B) { + b.Run(" Time: 3, Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2d, 3, 32*1024, 1, 32, b) }) + b.Run(" Time: 4, Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2d, 4, 32*1024, 1, 32, b) }) + b.Run(" Time: 5, Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2d, 5, 32*1024, 1, 32, b) }) + b.Run(" Time: 3, Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2d, 3, 64*1024, 4, 32, b) }) + b.Run(" Time: 4, Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2d, 4, 64*1024, 4, 32, b) }) + b.Run(" Time: 5, Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2d, 5, 64*1024, 4, 32, b) }) +} + +func BenchmarkArgon2id(b *testing.B) { + b.Run(" Time: 3, Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2id, 3, 32*1024, 1, 32, b) }) + b.Run(" Time: 4, Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2id, 4, 32*1024, 1, 32, b) }) + b.Run(" Time: 5, Memory: 32 MB, Threads: 1", func(b *testing.B) { benchmarkArgon2(argon2id, 5, 32*1024, 1, 32, b) }) + b.Run(" Time: 3, Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2id, 3, 64*1024, 4, 32, b) }) + b.Run(" Time: 4, Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2id, 4, 64*1024, 4, 32, b) }) + b.Run(" Time: 5, Memory: 64 MB, Threads: 4", func(b *testing.B) { benchmarkArgon2(argon2id, 5, 64*1024, 4, 32, b) }) +} diff --git a/vendor/golang.org/x/crypto/argon2/blake2b.go b/vendor/golang.org/x/crypto/argon2/blake2b.go new file mode 100644 index 0000000..10f4694 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blake2b.go @@ -0,0 +1,53 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package argon2 + +import ( + "encoding/binary" + "hash" + + "golang.org/x/crypto/blake2b" +) + +// blake2bHash computes an arbitrary long hash value of in +// and writes the hash to out. +func blake2bHash(out []byte, in []byte) { + var b2 hash.Hash + if n := len(out); n < blake2b.Size { + b2, _ = blake2b.New(n, nil) + } else { + b2, _ = blake2b.New512(nil) + } + + var buffer [blake2b.Size]byte + binary.LittleEndian.PutUint32(buffer[:4], uint32(len(out))) + b2.Write(buffer[:4]) + b2.Write(in) + + if len(out) <= blake2b.Size { + b2.Sum(out[:0]) + return + } + + outLen := len(out) + b2.Sum(buffer[:0]) + b2.Reset() + copy(out, buffer[:32]) + out = out[32:] + for len(out) > blake2b.Size { + b2.Write(buffer[:]) + b2.Sum(buffer[:0]) + copy(out, buffer[:32]) + out = out[32:] + b2.Reset() + } + + if outLen%blake2b.Size > 0 { // outLen > 64 + r := ((outLen + 31) / 32) - 2 // ⌈τ /32⌉-2 + b2, _ = blake2b.New(outLen-32*r, nil) + } + b2.Write(buffer[:]) + b2.Sum(out[:0]) +} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.go b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go new file mode 100644 index 0000000..583ac4b --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.go @@ -0,0 +1,59 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package argon2 + +func init() { + useSSE4 = supportsSSE4() +} + +//go:noescape +func supportsSSE4() bool + +//go:noescape +func mixBlocksSSE2(out, a, b, c *block) + +//go:noescape +func xorBlocksSSE2(out, a, b, c *block) + +//go:noescape +func blamkaSSE4(b *block) + +func processBlockSSE(out, in1, in2 *block, xor bool) { + var t block + mixBlocksSSE2(&t, in1, in2, &t) + if useSSE4 { + blamkaSSE4(&t) + } else { + for i := 0; i < blockLength; i += 16 { + blamkaGeneric( + &t[i+0], &t[i+1], &t[i+2], &t[i+3], + &t[i+4], &t[i+5], &t[i+6], &t[i+7], + &t[i+8], &t[i+9], &t[i+10], &t[i+11], + &t[i+12], &t[i+13], &t[i+14], &t[i+15], + ) + } + for i := 0; i < blockLength/8; i += 2 { + blamkaGeneric( + &t[i], &t[i+1], &t[16+i], &t[16+i+1], + &t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1], + &t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1], + &t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1], + ) + } + } + if xor { + xorBlocksSSE2(out, in1, in2, &t) + } else { + mixBlocksSSE2(out, in1, in2, &t) + } +} + +func processBlock(out, in1, in2 *block) { + processBlockSSE(out, in1, in2, false) +} + +func processBlockXOR(out, in1, in2 *block) { + processBlockSSE(out, in1, in2, true) +} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_amd64.s b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s new file mode 100644 index 0000000..8a83f7c --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_amd64.s @@ -0,0 +1,252 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!gccgo,!appengine + +#include "textflag.h" + +DATA ·c40<>+0x00(SB)/8, $0x0201000706050403 +DATA ·c40<>+0x08(SB)/8, $0x0a09080f0e0d0c0b +GLOBL ·c40<>(SB), (NOPTR+RODATA), $16 + +DATA ·c48<>+0x00(SB)/8, $0x0100070605040302 +DATA ·c48<>+0x08(SB)/8, $0x09080f0e0d0c0b0a +GLOBL ·c48<>(SB), (NOPTR+RODATA), $16 + +#define SHUFFLE(v2, v3, v4, v5, v6, v7, t1, t2) \ + MOVO v4, t1; \ + MOVO v5, v4; \ + MOVO t1, v5; \ + MOVO v6, t1; \ + PUNPCKLQDQ v6, t2; \ + PUNPCKHQDQ v7, v6; \ + PUNPCKHQDQ t2, v6; \ + PUNPCKLQDQ v7, t2; \ + MOVO t1, v7; \ + MOVO v2, t1; \ + PUNPCKHQDQ t2, v7; \ + PUNPCKLQDQ v3, t2; \ + PUNPCKHQDQ t2, v2; \ + PUNPCKLQDQ t1, t2; \ + PUNPCKHQDQ t2, v3 + +#define SHUFFLE_INV(v2, v3, v4, v5, v6, v7, t1, t2) \ + MOVO v4, t1; \ + MOVO v5, v4; \ + MOVO t1, v5; \ + MOVO v2, t1; \ + PUNPCKLQDQ v2, t2; \ + PUNPCKHQDQ v3, v2; \ + PUNPCKHQDQ t2, v2; \ + PUNPCKLQDQ v3, t2; \ + MOVO t1, v3; \ + MOVO v6, t1; \ + PUNPCKHQDQ t2, v3; \ + PUNPCKLQDQ v7, t2; \ + PUNPCKHQDQ t2, v6; \ + PUNPCKLQDQ t1, t2; \ + PUNPCKHQDQ t2, v7 + +#define HALF_ROUND(v0, v1, v2, v3, v4, v5, v6, v7, t0, c40, c48) \ + MOVO v0, t0; \ + PMULULQ v2, t0; \ + PADDQ v2, v0; \ + PADDQ t0, v0; \ + PADDQ t0, v0; \ + PXOR v0, v6; \ + PSHUFD $0xB1, v6, v6; \ + MOVO v4, t0; \ + PMULULQ v6, t0; \ + PADDQ v6, v4; \ + PADDQ t0, v4; \ + PADDQ t0, v4; \ + PXOR v4, v2; \ + PSHUFB c40, v2; \ + MOVO v0, t0; \ + PMULULQ v2, t0; \ + PADDQ v2, v0; \ + PADDQ t0, v0; \ + PADDQ t0, v0; \ + PXOR v0, v6; \ + PSHUFB c48, v6; \ + MOVO v4, t0; \ + PMULULQ v6, t0; \ + PADDQ v6, v4; \ + PADDQ t0, v4; \ + PADDQ t0, v4; \ + PXOR v4, v2; \ + MOVO v2, t0; \ + PADDQ v2, t0; \ + PSRLQ $63, v2; \ + PXOR t0, v2; \ + MOVO v1, t0; \ + PMULULQ v3, t0; \ + PADDQ v3, v1; \ + PADDQ t0, v1; \ + PADDQ t0, v1; \ + PXOR v1, v7; \ + PSHUFD $0xB1, v7, v7; \ + MOVO v5, t0; \ + PMULULQ v7, t0; \ + PADDQ v7, v5; \ + PADDQ t0, v5; \ + PADDQ t0, v5; \ + PXOR v5, v3; \ + PSHUFB c40, v3; \ + MOVO v1, t0; \ + PMULULQ v3, t0; \ + PADDQ v3, v1; \ + PADDQ t0, v1; \ + PADDQ t0, v1; \ + PXOR v1, v7; \ + PSHUFB c48, v7; \ + MOVO v5, t0; \ + PMULULQ v7, t0; \ + PADDQ v7, v5; \ + PADDQ t0, v5; \ + PADDQ t0, v5; \ + PXOR v5, v3; \ + MOVO v3, t0; \ + PADDQ v3, t0; \ + PSRLQ $63, v3; \ + PXOR t0, v3 + +#define LOAD_MSG_0(block, off) \ + MOVOU 8*(off+0)(block), X0; \ + MOVOU 8*(off+2)(block), X1; \ + MOVOU 8*(off+4)(block), X2; \ + MOVOU 8*(off+6)(block), X3; \ + MOVOU 8*(off+8)(block), X4; \ + MOVOU 8*(off+10)(block), X5; \ + MOVOU 8*(off+12)(block), X6; \ + MOVOU 8*(off+14)(block), X7 + +#define STORE_MSG_0(block, off) \ + MOVOU X0, 8*(off+0)(block); \ + MOVOU X1, 8*(off+2)(block); \ + MOVOU X2, 8*(off+4)(block); \ + MOVOU X3, 8*(off+6)(block); \ + MOVOU X4, 8*(off+8)(block); \ + MOVOU X5, 8*(off+10)(block); \ + MOVOU X6, 8*(off+12)(block); \ + MOVOU X7, 8*(off+14)(block) + +#define LOAD_MSG_1(block, off) \ + MOVOU 8*off+0*8(block), X0; \ + MOVOU 8*off+16*8(block), X1; \ + MOVOU 8*off+32*8(block), X2; \ + MOVOU 8*off+48*8(block), X3; \ + MOVOU 8*off+64*8(block), X4; \ + MOVOU 8*off+80*8(block), X5; \ + MOVOU 8*off+96*8(block), X6; \ + MOVOU 8*off+112*8(block), X7 + +#define STORE_MSG_1(block, off) \ + MOVOU X0, 8*off+0*8(block); \ + MOVOU X1, 8*off+16*8(block); \ + MOVOU X2, 8*off+32*8(block); \ + MOVOU X3, 8*off+48*8(block); \ + MOVOU X4, 8*off+64*8(block); \ + MOVOU X5, 8*off+80*8(block); \ + MOVOU X6, 8*off+96*8(block); \ + MOVOU X7, 8*off+112*8(block) + +#define BLAMKA_ROUND_0(block, off, t0, t1, c40, c48) \ + LOAD_MSG_0(block, off); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \ + STORE_MSG_0(block, off) + +#define BLAMKA_ROUND_1(block, off, t0, t1, c40, c48) \ + LOAD_MSG_1(block, off); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE(X2, X3, X4, X5, X6, X7, t0, t1); \ + HALF_ROUND(X0, X1, X2, X3, X4, X5, X6, X7, t0, c40, c48); \ + SHUFFLE_INV(X2, X3, X4, X5, X6, X7, t0, t1); \ + STORE_MSG_1(block, off) + +// func blamkaSSE4(b *block) +TEXT ·blamkaSSE4(SB), 4, $0-8 + MOVQ b+0(FP), AX + + MOVOU ·c40<>(SB), X10 + MOVOU ·c48<>(SB), X11 + + BLAMKA_ROUND_0(AX, 0, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 16, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 32, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 48, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 64, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 80, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 96, X8, X9, X10, X11) + BLAMKA_ROUND_0(AX, 112, X8, X9, X10, X11) + + BLAMKA_ROUND_1(AX, 0, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 2, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 4, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 6, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 8, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 10, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 12, X8, X9, X10, X11) + BLAMKA_ROUND_1(AX, 14, X8, X9, X10, X11) + RET + +// func mixBlocksSSE2(out, a, b, c *block) +TEXT ·mixBlocksSSE2(SB), 4, $0-32 + MOVQ out+0(FP), DX + MOVQ a+8(FP), AX + MOVQ b+16(FP), BX + MOVQ a+24(FP), CX + MOVQ $128, BP + +loop: + MOVOU 0(AX), X0 + MOVOU 0(BX), X1 + MOVOU 0(CX), X2 + PXOR X1, X0 + PXOR X2, X0 + MOVOU X0, 0(DX) + ADDQ $16, AX + ADDQ $16, BX + ADDQ $16, CX + ADDQ $16, DX + SUBQ $2, BP + JA loop + RET + +// func xorBlocksSSE2(out, a, b, c *block) +TEXT ·xorBlocksSSE2(SB), 4, $0-32 + MOVQ out+0(FP), DX + MOVQ a+8(FP), AX + MOVQ b+16(FP), BX + MOVQ a+24(FP), CX + MOVQ $128, BP + +loop: + MOVOU 0(AX), X0 + MOVOU 0(BX), X1 + MOVOU 0(CX), X2 + MOVOU 0(DX), X3 + PXOR X1, X0 + PXOR X2, X0 + PXOR X3, X0 + MOVOU X0, 0(DX) + ADDQ $16, AX + ADDQ $16, BX + ADDQ $16, CX + ADDQ $16, DX + SUBQ $2, BP + JA loop + RET + +// func supportsSSE4() bool +TEXT ·supportsSSE4(SB), 4, $0-1 + MOVL $1, AX + CPUID + SHRL $19, CX // Bit 19 indicates SSE4 support + ANDL $1, CX // CX != 0 if support SSE4 + MOVB CX, ret+0(FP) + RET diff --git a/vendor/golang.org/x/crypto/argon2/blamka_generic.go b/vendor/golang.org/x/crypto/argon2/blamka_generic.go new file mode 100644 index 0000000..a481b22 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_generic.go @@ -0,0 +1,163 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package argon2 + +var useSSE4 bool + +func processBlockGeneric(out, in1, in2 *block, xor bool) { + var t block + for i := range t { + t[i] = in1[i] ^ in2[i] + } + for i := 0; i < blockLength; i += 16 { + blamkaGeneric( + &t[i+0], &t[i+1], &t[i+2], &t[i+3], + &t[i+4], &t[i+5], &t[i+6], &t[i+7], + &t[i+8], &t[i+9], &t[i+10], &t[i+11], + &t[i+12], &t[i+13], &t[i+14], &t[i+15], + ) + } + for i := 0; i < blockLength/8; i += 2 { + blamkaGeneric( + &t[i], &t[i+1], &t[16+i], &t[16+i+1], + &t[32+i], &t[32+i+1], &t[48+i], &t[48+i+1], + &t[64+i], &t[64+i+1], &t[80+i], &t[80+i+1], + &t[96+i], &t[96+i+1], &t[112+i], &t[112+i+1], + ) + } + if xor { + for i := range t { + out[i] ^= in1[i] ^ in2[i] ^ t[i] + } + } else { + for i := range t { + out[i] = in1[i] ^ in2[i] ^ t[i] + } + } +} + +func blamkaGeneric(t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15 *uint64) { + v00, v01, v02, v03 := *t00, *t01, *t02, *t03 + v04, v05, v06, v07 := *t04, *t05, *t06, *t07 + v08, v09, v10, v11 := *t08, *t09, *t10, *t11 + v12, v13, v14, v15 := *t12, *t13, *t14, *t15 + + v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04)) + v12 ^= v00 + v12 = v12>>32 | v12<<32 + v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12)) + v04 ^= v08 + v04 = v04>>24 | v04<<40 + + v00 += v04 + 2*uint64(uint32(v00))*uint64(uint32(v04)) + v12 ^= v00 + v12 = v12>>16 | v12<<48 + v08 += v12 + 2*uint64(uint32(v08))*uint64(uint32(v12)) + v04 ^= v08 + v04 = v04>>63 | v04<<1 + + v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05)) + v13 ^= v01 + v13 = v13>>32 | v13<<32 + v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13)) + v05 ^= v09 + v05 = v05>>24 | v05<<40 + + v01 += v05 + 2*uint64(uint32(v01))*uint64(uint32(v05)) + v13 ^= v01 + v13 = v13>>16 | v13<<48 + v09 += v13 + 2*uint64(uint32(v09))*uint64(uint32(v13)) + v05 ^= v09 + v05 = v05>>63 | v05<<1 + + v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06)) + v14 ^= v02 + v14 = v14>>32 | v14<<32 + v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14)) + v06 ^= v10 + v06 = v06>>24 | v06<<40 + + v02 += v06 + 2*uint64(uint32(v02))*uint64(uint32(v06)) + v14 ^= v02 + v14 = v14>>16 | v14<<48 + v10 += v14 + 2*uint64(uint32(v10))*uint64(uint32(v14)) + v06 ^= v10 + v06 = v06>>63 | v06<<1 + + v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07)) + v15 ^= v03 + v15 = v15>>32 | v15<<32 + v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15)) + v07 ^= v11 + v07 = v07>>24 | v07<<40 + + v03 += v07 + 2*uint64(uint32(v03))*uint64(uint32(v07)) + v15 ^= v03 + v15 = v15>>16 | v15<<48 + v11 += v15 + 2*uint64(uint32(v11))*uint64(uint32(v15)) + v07 ^= v11 + v07 = v07>>63 | v07<<1 + + v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05)) + v15 ^= v00 + v15 = v15>>32 | v15<<32 + v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15)) + v05 ^= v10 + v05 = v05>>24 | v05<<40 + + v00 += v05 + 2*uint64(uint32(v00))*uint64(uint32(v05)) + v15 ^= v00 + v15 = v15>>16 | v15<<48 + v10 += v15 + 2*uint64(uint32(v10))*uint64(uint32(v15)) + v05 ^= v10 + v05 = v05>>63 | v05<<1 + + v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06)) + v12 ^= v01 + v12 = v12>>32 | v12<<32 + v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12)) + v06 ^= v11 + v06 = v06>>24 | v06<<40 + + v01 += v06 + 2*uint64(uint32(v01))*uint64(uint32(v06)) + v12 ^= v01 + v12 = v12>>16 | v12<<48 + v11 += v12 + 2*uint64(uint32(v11))*uint64(uint32(v12)) + v06 ^= v11 + v06 = v06>>63 | v06<<1 + + v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07)) + v13 ^= v02 + v13 = v13>>32 | v13<<32 + v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13)) + v07 ^= v08 + v07 = v07>>24 | v07<<40 + + v02 += v07 + 2*uint64(uint32(v02))*uint64(uint32(v07)) + v13 ^= v02 + v13 = v13>>16 | v13<<48 + v08 += v13 + 2*uint64(uint32(v08))*uint64(uint32(v13)) + v07 ^= v08 + v07 = v07>>63 | v07<<1 + + v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04)) + v14 ^= v03 + v14 = v14>>32 | v14<<32 + v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14)) + v04 ^= v09 + v04 = v04>>24 | v04<<40 + + v03 += v04 + 2*uint64(uint32(v03))*uint64(uint32(v04)) + v14 ^= v03 + v14 = v14>>16 | v14<<48 + v09 += v14 + 2*uint64(uint32(v09))*uint64(uint32(v14)) + v04 ^= v09 + v04 = v04>>63 | v04<<1 + + *t00, *t01, *t02, *t03 = v00, v01, v02, v03 + *t04, *t05, *t06, *t07 = v04, v05, v06, v07 + *t08, *t09, *t10, *t11 = v08, v09, v10, v11 + *t12, *t13, *t14, *t15 = v12, v13, v14, v15 +} diff --git a/vendor/golang.org/x/crypto/argon2/blamka_ref.go b/vendor/golang.org/x/crypto/argon2/blamka_ref.go new file mode 100644 index 0000000..baf7b55 --- /dev/null +++ b/vendor/golang.org/x/crypto/argon2/blamka_ref.go @@ -0,0 +1,15 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !amd64 appengine gccgo + +package argon2 + +func processBlock(out, in1, in2 *block) { + processBlockGeneric(out, in1, in2, false) +} + +func processBlockXOR(out, in1, in2 *block) { + processBlockGeneric(out, in1, in2, true) +} diff --git a/vendor/golang.org/x/crypto/blake2b/blake2b.go b/vendor/golang.org/x/crypto/blake2b/blake2b.go index 7f0a86e..6dedb89 100644 --- a/vendor/golang.org/x/crypto/blake2b/blake2b.go +++ b/vendor/golang.org/x/crypto/blake2b/blake2b.go @@ -39,7 +39,10 @@ var ( useSSE4 bool ) -var errKeySize = errors.New("blake2b: invalid key size") +var ( + errKeySize = errors.New("blake2b: invalid key size") + errHashSize = errors.New("blake2b: invalid hash size") +) var iv = [8]uint64{ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, @@ -83,7 +86,18 @@ func New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) } // key turns the hash into a MAC. The key must between zero and 64 bytes long. func New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) } +// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length. +// A non-nil key turns the hash into a MAC. The key must between zero and 64 bytes long. +// The hash size can be a value between 1 and 64 but it is highly recommended to use +// values equal or greater than: +// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long). +// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long). +func New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) } + func newDigest(hashSize int, key []byte) (*digest, error) { + if hashSize < 1 || hashSize > Size { + return nil, errHashSize + } if len(key) > Size { return nil, errKeySize } diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go index 1379240..f83cb69 100644 --- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go +++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go @@ -155,3 +155,22 @@ func TestWithHMACSHA1(t *testing.T) { func TestWithHMACSHA256(t *testing.T) { testHash(t, sha256.New, "SHA256", sha256TestVectors) } + +var sink uint8 + +func benchmark(b *testing.B, h func() hash.Hash) { + password := make([]byte, h().Size()) + salt := make([]byte, 8) + for i := 0; i < b.N; i++ { + password = Key(password, salt, 4096, len(password), h) + } + sink += password[0] +} + +func BenchmarkHMACSHA1(b *testing.B) { + benchmark(b, sha1.New) +} + +func BenchmarkHMACSHA256(b *testing.B) { + benchmark(b, sha256.New) +} diff --git a/vendor/golang.org/x/crypto/ssh/certs_test.go b/vendor/golang.org/x/crypto/ssh/certs_test.go index 0200531..c8e7cf5 100644 --- a/vendor/golang.org/x/crypto/ssh/certs_test.go +++ b/vendor/golang.org/x/crypto/ssh/certs_test.go @@ -6,10 +6,15 @@ package ssh import ( "bytes" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rand" + "net" "reflect" "testing" "time" + + "golang.org/x/crypto/ssh/testdata" ) // Cert generated by ssh-keygen 6.0p1 Debian-4. @@ -220,3 +225,111 @@ func TestHostKeyCert(t *testing.T) { } } } + +func TestCertTypes(t *testing.T) { + var testVars = []struct { + name string + keys func() Signer + }{ + { + name: CertAlgoECDSA256v01, + keys: func() Signer { + s, _ := ParsePrivateKey(testdata.PEMBytes["ecdsap256"]) + return s + }, + }, + { + name: CertAlgoECDSA384v01, + keys: func() Signer { + s, _ := ParsePrivateKey(testdata.PEMBytes["ecdsap384"]) + return s + }, + }, + { + name: CertAlgoECDSA521v01, + keys: func() Signer { + s, _ := ParsePrivateKey(testdata.PEMBytes["ecdsap521"]) + return s + }, + }, + { + name: CertAlgoED25519v01, + keys: func() Signer { + s, _ := ParsePrivateKey(testdata.PEMBytes["ed25519"]) + return s + }, + }, + { + name: CertAlgoRSAv01, + keys: func() Signer { + s, _ := ParsePrivateKey(testdata.PEMBytes["rsa"]) + return s + }, + }, + { + name: CertAlgoDSAv01, + keys: func() Signer { + s, _ := ParsePrivateKey(testdata.PEMBytes["dsa"]) + return s + }, + }, + } + + k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatalf("error generating host key: %v", err) + } + + signer, err := NewSignerFromKey(k) + if err != nil { + t.Fatalf("error generating signer for ssh listener: %v", err) + } + + conf := &ServerConfig{ + PublicKeyCallback: func(c ConnMetadata, k PublicKey) (*Permissions, error) { + return new(Permissions), nil + }, + } + conf.AddHostKey(signer) + + for _, m := range testVars { + t.Run(m.name, func(t *testing.T) { + + c1, c2, err := netPipe() + if err != nil { + t.Fatalf("netPipe: %v", err) + } + defer c1.Close() + defer c2.Close() + + go NewServerConn(c1, conf) + + priv := m.keys() + if err != nil { + t.Fatalf("error generating ssh pubkey: %v", err) + } + + cert := &Certificate{ + CertType: UserCert, + Key: priv.PublicKey(), + } + cert.SignCert(rand.Reader, priv) + + certSigner, err := NewCertSigner(cert, priv) + if err != nil { + t.Fatalf("error generating cert signer: %v", err) + } + + config := &ClientConfig{ + User: "user", + HostKeyCallback: func(h string, r net.Addr, k PublicKey) error { return nil }, + Auth: []AuthMethod{PublicKeys(certSigner)}, + } + + _, _, _, err = NewClientConn(c2, "", config) + if err != nil { + t.Fatalf("error connecting: %v", err) + } + }) + } +} diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index d4df916..b83d473 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -256,7 +256,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) func isAcceptableAlgo(algo string) bool { switch algo { case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoED25519, - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01: + CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01: return true } return false diff --git a/vendor/golang.org/x/crypto/ssh/testdata/keys.go b/vendor/golang.org/x/crypto/ssh/testdata/keys.go index 3b3d26c..521b6be 100644 --- a/vendor/golang.org/x/crypto/ssh/testdata/keys.go +++ b/vendor/golang.org/x/crypto/ssh/testdata/keys.go @@ -23,6 +23,27 @@ MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ 6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== -----END EC PRIVATE KEY----- +`), + "ecdsap256": []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIAPCE25zK0PQSnsgVcEbM1mbKTASH4pqb5QJajplDwDZoAoGCCqGSM49 +AwEHoUQDQgAEWy8TxGcIHRh5XGpO4dFVfDjeNY+VkgubQrf/eyFJZHxAn1SKraXU +qJUjTKj1z622OxYtJ5P7s9CfAEVsTzLCzg== +-----END EC PRIVATE KEY----- +`), + "ecdsap384": []byte(`-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBWfSnMuNKq8J9rQLzzEkx3KAoEohSXqhE/4CdjEYtoU2i22HW80DDS +qQhYNHRAduygBwYFK4EEACKhZANiAAQWaDMAd0HUd8ZiXCX7mYDDnC54gwH/nG43 +VhCUEYmF7HMZm/B9Yn3GjFk3qYEDEvuF/52+NvUKBKKaLbh32AWxMv0ibcoba4cz +hL9+hWYhUD9XIUlzMWiZ2y6eBE9PdRI= +-----END EC PRIVATE KEY----- +`), + "ecdsap521": []byte(`-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIBrkYpQcy8KTVHNiAkjlFZwee90224Bu6wz94R4OBo+Ts0eoAQG7SF +iaygEDMUbx6kTgXTBcKZ0jrWPKakayNZ/kigBwYFK4EEACOhgYkDgYYABADFuvLV +UoaCDGHcw5uNfdRIsvaLKuWSpLsl48eWGZAwdNG432GDVKduO+pceuE+8XzcyJb+ +uMv+D2b11Q/LQUcHJwE6fqbm8m3EtDKPsoKs0u/XUJb0JsH4J8lkZzbUTjvGYamn +FFlRjzoB3Oxu8UQgb+MWPedtH9XYBbg9biz4jJLkXQ== +-----END EC PRIVATE KEY----- `), "rsa": []byte(`-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQC8A6FGHDiWCSREAXCq6yBfNVr0xCVG2CzvktFNRpue+RXrGs/2 diff --git a/vendor/golang.org/x/net/internal/socket/socket.go b/vendor/golang.org/x/net/internal/socket/socket.go index 729dea1..5f9730e 100644 --- a/vendor/golang.org/x/net/internal/socket/socket.go +++ b/vendor/golang.org/x/net/internal/socket/socket.go @@ -110,7 +110,7 @@ func ControlMessageSpace(dataLen int) int { type ControlMessage []byte // Data returns the data field of the control message at the head on -// w. +// m. func (m ControlMessage) Data(dataLen int) []byte { l := controlHeaderLen() if len(m) < l || len(m) < l+dataLen { @@ -119,7 +119,7 @@ func (m ControlMessage) Data(dataLen int) []byte { return m[l : l+dataLen] } -// Next returns the control message at the next on w. +// Next returns the control message at the next on m. // // Next works only for standard control messages. func (m ControlMessage) Next(dataLen int) ControlMessage { @@ -131,7 +131,7 @@ func (m ControlMessage) Next(dataLen int) ControlMessage { } // MarshalHeader marshals the header fields of the control message at -// the head on w. +// the head on m. func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error { if len(m) < controlHeaderLen() { return errors.New("short message") @@ -142,7 +142,7 @@ func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error { } // ParseHeader parses and returns the header fields of the control -// message at the head on w. +// message at the head on m. func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) { l := controlHeaderLen() if len(m) < l { @@ -152,7 +152,7 @@ func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) { return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil } -// Marshal marshals the control message at the head on w, and returns +// Marshal marshals the control message at the head on m, and returns // the next control message. func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) { l := len(data) @@ -167,7 +167,7 @@ func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, erro return m.Next(l), nil } -// Parse parses w as a single or multiple control messages. +// Parse parses m as a single or multiple control messages. // // Parse works for both standard and compatible messages. func (m ControlMessage) Parse() ([]ControlMessage, error) {