commit 3fba6e6295a9b217a052ddb0ec0d74a7e4c0a3f7 Author: kayos@tcp.direct Date: Tue Sep 28 02:30:11 2021 -0700 init diff --git a/README.md b/README.md new file mode 100644 index 0000000..90afce6 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# durnkb0t + +``` + .drinkin + _.._..,_,_ + ( ) + ]~,"-.-~~[ + .=])' (; ([ + | ]:: ' [ the following lovely chatters + '=]): .) ([ are trying their absolute best + |:: ' | to get fuckin lit in 2021 + ~~----~~ + -------> kayos[m]1 d soyak +``` + + +``` +<&kayos> Where r u working now Oh, yes, I've just been to see The Exorcism of Emily Rose and may never sleep again! +<&kayos> They are going to mush! +<&kayos> Bad days give u happiness. +<&kayos> So, Wish u a very Happy New Year and I wanted to ask ü to wait 4 me there ar? +<&kayos> Then r we meeting tmr? +<&kayos> Try SPEEDCHAT, txt SPEEDCHAT to 80155, if you don't mind, as doing that nxt wk. +<&kayos> See you in the library? +<&kayos> Bring it if you got it I'm in a meeting, call me later at Oh wow thats gay. +<&kayos> Do have a fantastic year and all the best. ttyl 1.20 that call cost. +<&kayos> I know this is a challenging time for you also but i have hundreds of handsomes and beauties to wish. +<&kayos> If not then let this text give you a special treat if you keep the secret. +<&kayos> At home by the way it comes! +<&kayos> Just got some gas money, any chance you and the gang want to go to taunton if you still need to loose weight.``` \ No newline at end of file diff --git a/config.go b/config.go new file mode 100644 index 0000000..b3a6123 --- /dev/null +++ b/config.go @@ -0,0 +1,45 @@ +package main + +///////////// +///////// +/// RPC +var RPCPort string = "4321" +var RPCHost string = "127.0.0.1" +var cowPipe string = "/tmp/sh0rtbus.cowrie.fifo" +///////// +/// IRC +var ircHost string = "br3ircdrchatmfsk.onion" +var ircPort int = 6667 +var ircSSL bool = false +var ircFlood bool = true +var ircDebug uintptr = 0 //os.Stdout +var ircVersion string = "sh0rtbus 0.2 fun edition" +// Bot +var ircHome string = "#tcpdirect" +var ircOwner string = "kayos" +var ircNick string = "durnkb0t" +var ircUser string +var ircPass string // username:pasword defined in auth.text +// Proxy +var proxyProto string = "SOCKS5" // "false" to disable proxy +var proxyHost string = "127.0.0.1" +var proxyPort string = "9050" +//// Cowrie +var cowVerbose int = 0 +var cowLogs string = "/home/cowrie/cowrie/var/log/cowrie" +var cowPings string = "kayos hgc Civil Xair nameless moony Glock kuntz w00dsman" +// Cowrie SQL +//var sqlHost string = "127.0.0.1" +//var sqlPort string = "3306" +//var sqlDB string = "cowrie" +//var sqlUser string = "sh0rtbus" +//var sqlPass string = "Eir4OcertEutpyfryWadbiwobJaphAlf" +/////////////////// +//var db *sql.DB +var err error +var cowSesh []string +////////////////// + + +var soberStrings []string + diff --git a/cowrie.go b/cowrie.go new file mode 100644 index 0000000..2bb6b73 --- /dev/null +++ b/cowrie.go @@ -0,0 +1,96 @@ +package main + +import( + "syscall" + "os" + "bytes" + "fmt" + "io" + "strings" + "github.com/lrstanley/girc" +) + + + +//func stainSelect(query string) { +// db, err = sql.Open("mysql","user:"+sqlUser+"@"+sqlHost+"("+sqlHost+":"+sqlPort+")/"+sqlDB) +// defer db.Close() +// if err != nil { +// fmt.Println("[SQL] Fatal error when opening the MySQL database: ", err.Error()) +// } +// err = db.Ping() +// if err != nil { +// fmt.Println("[SQL] Fatal error when pinging the MySQL database: ", err.Error()) +// } +//} + +func Cowrie(c *girc.Client) error { + syscall.Mkfifo(cowPipe, 0600) + for { +// fmt.Println("[IPC] Opening named pipe for reading") + stdout, err := os.OpenFile(cowPipe, os.O_RDONLY, 0600) + var buff bytes.Buffer + + if err != nil { + fmt.Println("[IPC] FATAL! Cannot open named pipe!") + return err + os.Exit(2) + } + + io.Copy(&buff, stdout) + stdout.Close() + dataStr := buff.String() + + if (cowVerbose == 1 && strings.Contains(dataStr, "CMD:")) { + + fmt.Println("CMD detected!") + + cowSlice := strings.Split(dataStr,"]") + cowPrefix := cowSlice[0] + cowString := strings.Split(cowPrefix, ")") + cowString = strings.Split(cowString[0], ")") + cowSession := cowString[0] + cowIPstr := strings.Split(cowPrefix,",") + cowIP := cowIPstr[0] + cowCmd := "["+cowIP+"]["+cowSession+"] " + cowSlice[1] + + fmt.Println(cowCmd) + + if !contains(cowSesh,cowSession) { + Phone(c,"(new) Retard alert! Attn:") + PhoneOwner(c,"Retard alert!") + Phone(c,cowPings) + Phone(c,"-----------------") + cowSesh = append(cowSesh,cowSession) + printSlice(cowSesh) + } + + Phone(c,dataStr) + } + + if cowVerbose == 2 { + fmt.Printf("[IPC] sending data to [IRC]: %s\n", dataStr) + Phone(c,dataStr) + } + } +} + + +func cowSay(c *girc.Client, str0 string, str1 string, str2 string) { + Phone(c," __,._{i} " + str0) + Phone(c," / _ \\ ") + if (cowVerbose == 0) { + Phone(c," | 6 \\ \\ {red}oo{c} ") + } else if cowVerbose == 1 { + Phone(c," | 6 \\ \\ {green}oo{c} ") + } else { + Phone(c," {yellow}REEE{c} | 6 \\ \\ {green}$${c} ") + } + Phone(c," \\___/ .|__|| ") + Phone(c," __,..=\"^ . , \" ,\\ ") + Phone(c,"<.__________________/ ") + Phone(c,"{white}" + str1) + if str2 != "0" { + Phone(c,"{white}" + str2) + } +} diff --git a/drunkbot.go b/drunkbot.go new file mode 100644 index 0000000..81ac8b0 --- /dev/null +++ b/drunkbot.go @@ -0,0 +1,47 @@ +package main + +import ( +// "database/sql" + "github.com/lrstanley/girc" + "math/rand" + "time" + //////// +// _ "github.com/go-sql-driver/mysql" +) + +func Phone(c *girc.Client, Msg string) { + target := ircHome + c.Cmd.Message(target, girc.Fmt(Msg)) +} + +func PhoneOwner(c *girc.Client, Msg string) { + target := ircOwner + c.Cmd.Message(target, girc.Fmt(Msg)) +} + +func ircBanner(c *girc.Client) { + c.Cmd.Message(ircHome, girc.Fmt("{purple,black} {green,black} ___ {purple,black} {c}")) + c.Cmd.Message(ircHome, girc.Fmt("{purple,black} | {green,black}| /|{purple,black} | | {gold,black}v0.2{c}{green,black}fun{c}")) + c.Cmd.Message(ircHome, girc.Fmt("{purple,black} - |- {green,black}| + |{purple,black} |- -+- |- - {c}")) + c.Cmd.Message(ircHome, girc.Fmt("{purple,black} \\ | | {green,black}|/ |{purple,black} | | | | | | \\ {c}")) + c.Cmd.Message(ircHome, girc.Fmt("{purple,black} - {green,black} --- {purple,black} - - -- - {c}")) + return +} + + +func ircDrinkin(c *girc.Client) { + c.Cmd.Message(ircHome, girc.Fmt(" _.._..,_,_ ")) + c.Cmd.Message(ircHome, girc.Fmt(" ({black,white} {c})")) + c.Cmd.Message(ircHome, girc.Fmt(" ]{white,gold}~,\"-.-~~{c}[" )) + c.Cmd.Message(ircHome, girc.Fmt(".=]{white,gold})' (; ({c}[")) + c.Cmd.Message(ircHome, girc.Fmt("| ]{white,gold}:: ' {c}[ the following lovely chatters")) + c.Cmd.Message(ircHome, girc.Fmt("'=]{white,gold}): .) ({c}[ are trying their absolute best")) + c.Cmd.Message(ircHome, girc.Fmt(" |{white,gold}:: ' {c}| to get fuckin {orange}lit{c} in 2021")) + c.Cmd.Message(ircHome, girc.Fmt(" ~~----~~ ")) +} + +func soberString() string { + rand.Seed(time.Now().Unix()) + choice := soberStrings[rand.Intn(len(soberStrings))] + return choice +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..49788ab --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module drunkb0t + +go 1.17 + +require ( + github.com/lrstanley/girc v0.0.0-20210611213246-771323f1624b + golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..851c31c --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +github.com/lrstanley/girc v0.0.0-20210611213246-771323f1624b h1:jrLvME7VuLW6NRysbiZtenTB9QcNlR9RPKK4LFfZn60= +github.com/lrstanley/girc v0.0.0-20210611213246-771323f1624b/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/ircbot.go b/ircbot.go new file mode 100644 index 0000000..4686928 --- /dev/null +++ b/ircbot.go @@ -0,0 +1,339 @@ +package main + +import( + "github.com/lrstanley/girc" + "golang.org/x/net/proxy" + "strconv" + "strings" + "net/url" + "bufio" + "time" + "fmt" + "net" + "os" +) + +var drinkin []string +var smokin []string +var speedin []string +var vapin []string +var drinkyBoys string + +func ircbot() { + + soberStrings = []string { + " wakes up confused (sober)", + " sobers up and questions their entire life", + " is straight edge because drugs and alcohol are for LOSERS (sober)", + " doesn't wanna talk about it (sober)", + } + + + ////////////////////////////////// + ////////////////////////////////// + ///////////////// TCP Server + //inbound, err := net.ListenTCP("tcp", Host+":"+Port) // Define TCP Listener + //if err != nil { //logr.Fatal("RPC Listener error! " + err) } + //psad := new(psadRPC) // Create a new handler of type psadRPC + //rpc.Register(psad)// Adds all relevant functions to RPC registry (gives client options) + //rpc.Accept(inbound) // Begins listening on socket and offering functions + + /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + + //logr := //logr.WithContext("IRC") + + if (len(os.Args) > 1) { + ircNick = os.Args[1] + } + + var SASLbool bool = false + var client *girc.Client + var ircSASL *girc.SASLPlain + + fmt.Println("[IRC] Opening auth file for nickserv creds...") + f, err := os.Open("auth.txt") + if err != nil { + fmt.Println("[IRC] Error opening auth.txt file!") + fmt.Println("[IRC] Proceeding without authentication...") + ircUser = ircNick + ircPass = "" + } else { + defer f.Close() + scanner := bufio.NewScanner(f) + scanner.Scan() + line := scanner.Text() + auth := strings.Split(line, ":") + ircUser = auth[0] + ircPass = auth[1] + ircSASL = &girc.SASLPlain{User: ircUser, Pass: ircPass} + SASLbool = true + f.Close() + } + + if SASLbool == true { + client = girc.New(girc.Config{ + Server: ircHost, + Port: ircPort, + Nick: ircNick, + Name: ircNick, + User: ircUser, + SSL: ircSSL, + SASL: ircSASL, + AllowFlood: ircFlood, + Out: os.Stdout, + Version: ircVersion, + }) + } else { + client = girc.New(girc.Config{ + Server: ircHost, + Port: ircPort, + Nick: ircNick, + Name: ircNick, + User: ircUser, + SSL: ircSSL, + AllowFlood: ircFlood, + Out: os.Stdout, + Version: ircVersion, + }) + } + + client.Handlers.Add(girc.CONNECTED, func(c *girc.Client, e girc.Event) { + fmt.Println("[IRC] Successfully connected to: " + ircHost) + c.Cmd.Join(ircHome) + fmt.Println("[IRC] Joining channel: " + ircHome) + + err = Cowrie(c) + + if err != nil { + fmt.Println("[IPC] Error: " + err.Error()) + c.Cmd.Message(ircOwner, "IPC Error: err.Error()") + os.Exit(2) + } + }) + client.Handlers.Add(girc.INVITE, func(c *girc.Client, e girc.Event) { + c.Cmd.Join(e.Last()) + }) + client.Handlers.Add(girc.ERR_CANNOTSENDTOCHAN, func(c *girc.Client, e girc.Event) { + Target := ircHome + if (strings.Contains(girc.Fmt(e.String()), ircHome)) { + Target = ircOwner + } + c.Cmd.Message(Target, "ERR_INVITEONLYCHAN:") + c.Cmd.Message(Target, girc.Fmt(e.String())) + }) + client.Handlers.Add(girc.ERR_INVITEONLYCHAN, func(c *girc.Client, e girc.Event) { + Phone(c,"ERR_INVITEONLYCHAN:") + Phone(c,girc.Fmt(e.String())) + }) + client.Handlers.Add(girc.RPL_WHOISUSER, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_WHOISUSER:") + Phone(c,girc.Fmt(e.String())) + }) + client.Handlers.Add(girc.RPL_WHOISOPERATOR, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_WHOISOPERATOR:") + Phone(c,girc.Fmt(e.String())) + }) + client.Handlers.Add(girc.RPL_WHOISIDLE, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_WHOISIDLE:") + Phone(c,girc.Fmt(e.String())) + }) + client.Handlers.Add(girc.RPL_WHOISSERVER, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_WHOISSERVER:") + Phone(c,girc.Fmt(e.String())) + }) + client.Handlers.Add(girc.RPL_WHOISCHANOP, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_WHOISCHANOP:") + Phone(c,girc.Fmt(e.String())) + }) + + client.Handlers.Add(girc.RPL_WHOISCHANOP, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_LINKS:") + Phone(c,girc.Fmt(e.String())) + }) + + client.Handlers.Add(girc.RPL_WHOISCHANOP, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_STATSLINKINFO:") + Phone(c,girc.Fmt(e.String())) + }) + + client.Handlers.Add(girc.RPL_WHOISCHANOP, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_TRACELINK:") + Phone(c,girc.Fmt(e.String())) + }) + + client.Handlers.Add(girc.RPL_TOPICWHOTIME, func(c *girc.Client, e girc.Event) { + Chan := strings.Split(e.String(), " ")[4] + if Chan != ircHome { + Phone(c,"Joined " + Chan + " on " + e.Source.ID()) + Phone(c,girc.Fmt(e.String())) + } + }) + +/* client.Handlers.Add(girc.RPL_NAMREPLY, func(c *girc.Client, e girc.Event) { + reply := strings.Split(e.String(), " ") + if reply[5] != ircHome { + + for i, h := range reply { + if i < 4 { continue } + Phone(c,h) + } + + } else { + ircBanner(c) + Phone(c,ircVersion) + } + })*/ + + client.Handlers.Add(girc.RPL_WHOISCHANNELS, func(c *girc.Client, e girc.Event) { + Phone(c,"RPL_WHOISCHANNELS:") + Phone(c,e.String()) + }) + + client.Handlers.Add(girc.PRIVMSG, func(c *girc.Client, e girc.Event) { + Sender := e.Source.Name + if Sender == "NickServ" { + fmt.Println("[IRC] NickServ response: " + e.Last()) + } + if (strings.HasPrefix(e.Last(), ".")) { + + fmt.Println("[IRC] "+e.String()) + + thyWill := strings.Split(e.Last(), " ") + + switch thyWill[0] { + + case ".whois": + if len(thyWill) == 1 { + c.Cmd.ReplyTo(e, girc.Fmt("Usage: !whois nick")) + return + } + fmt.Println("[IRC] <"+string(Sender)+"> !spider " + thyWill[1]) + if girc.IsValidNick(thyWill[1]) { + c.Cmd.Whois(thyWill[1]) + return + } else { + fmt.Println("[IRC] ERROR: Bad whois target!") + Phone(c,"Bad Target! Wtf is that shit?") + return + } + + case ".spider": + if Sender != ircOwner { + c.Cmd.Kick(ircHome,Sender,"lol r3kt") + return + } + + thyWill := strings.Split(e.Last(), " ") + var thyMark string + if len(thyWill) == 1 { + c.Cmd.ReplyTo(e, girc.Fmt("Usage: !spider #channel")) + return + } + + thyMark = thyWill[1] + fmt.Println("[IRC] <"+string(Sender)+"> !spider " + thyMark) + + if girc.IsValidChannel(thyMark) { + fmt.Println("[IRC][SPIDER] Joining target " + thyMark) + Phone(c,"Joining " + thyMark) + c.Cmd.Join(thyMark) + return + } else { + fmt.Println("[IRC][SPIDER] Bad scan target! " + thyMark) + Phone(c,"Bad Target! Wtf is that shit?") + return + } + + case ".stop": + if Sender == ircOwner { + c.Close() + return + } else { + c.Cmd.Kick(ircHome,Sender,"yeah okay retard") + } + + case ".motd": + ircBanner(c) + + case ".cowrie": + if (len(thyWill) < 3) { + cowSay(c,"snail","snailyboi","Cowrie is disabled on this instance, but i hope you like this cute snail :)") + return + } + + case ".drinkin": + if !contains(drinkin,Sender) { + fmt.Println("[IRC][drinkin] New drinker! " + Sender) + drinkin = append(drinkin, Sender) + } else { + fmt.Println("[IRC][drinkin] Existing drinker " + Sender) + drinkyBoys = strings.Join(drinkin, " ") + drinkyBoys = strings.Replace(drinkyBoys, "nil", "", -1) + drinkyBoys = strings.Replace(drinkyBoys, " ", "", -1) + Phone(c, Sender + " takes another swig ;D") + Phone(c, " 🍺 ------> " + drinkyBoys) + return + } + ircDrinkin(c) + drinkyBoys = strings.Join(drinkin," ") + drinkyBoys = strings.Replace(drinkyBoys, "nil ", "", -1) + drinkyBoys = strings.Replace(drinkyBoys, " ", "", -1) + Phone(c," -------> "+drinkyBoys) + + case ".sober": + if contains(drinkin,Sender) { + for i, v := range drinkin { + if v == Sender { + drinkin[i] = "nil" + } + } + } + Phone(c, Sender + soberString()) + + default: + fmt.Println("[IRC] Unknown bot command issued: " + thyWill[0]) + } + } + }) + + sslString := " " + + ////logr.Debug("Parsing proxy URI: " + ProxyURI) + //logr.Debug("Validating " + proxyProto + " proxy at host " + proxyHost + " on port " + proxyPort) + if ircSSL == true { + sslString = "-ssl" + } + if proxyProto != "false" { + ProxyUrl, err := url.Parse(proxyProto + "://" + proxyHost + ":" + proxyPort) + if err != nil { + fmt.Println("Proxy URI is malformed!") + panic(err) + } + dialer, _ := proxy.FromURL(ProxyUrl, &net.Dialer{Timeout: 5 * time.Second}) + for { + fmt.Println("[IRC] Dialing through a " + proxyProto + " proxy at host " + proxyHost + " on port " + proxyPort) + fmt.Println("[IRC] Connecting to " + ircHost + "/" + strconv.Itoa(ircPort) + " " + sslString) + if err := client.DialerConnect(dialer); err != nil { + fmt.Println("[IRC] Connection error! " + err.Error()) + fmt.Println("[IRC] reconnecting...") + time.Sleep(1) + } else { + return + } + } + } else { + for { + fmt.Println("[IRC] Connecting to " + ircHost + "/" + strconv.Itoa(ircPort) + " " + sslString) + if err := client.Connect(); err != nil { + fmt.Println("[IRC] Connection error! " + err.Error()) + fmt.Println("[IRC] reconnecting...") + time.Sleep(1) + } else { + return + } + } + + } +} + diff --git a/main.go b/main.go new file mode 100644 index 0000000..54d86a0 --- /dev/null +++ b/main.go @@ -0,0 +1,18 @@ +package main + +import "os" +import "fmt" + +func init() { + fmt.Println("yeet") +} + +func main() { + if (len(os.Args) > 2 && os.Args[1] == "client") { + //fmt.Println("Starting client...") + } else { + conBanner() + ircbot() + } +} + diff --git a/util.go b/util.go new file mode 100644 index 0000000..f990d93 --- /dev/null +++ b/util.go @@ -0,0 +1,32 @@ +package main + +import "encoding/base64" +import "fmt" + +func b64d(str string) string { + data, err := base64.StdEncoding.DecodeString(str) + if err != nil { + return err.Error() + } + return string(data) +} + +func conBanner() { + data := "ICAgICAgICAg4paI4paIICAgICAgIOKWiOKWiOKWiOKWiCAgICAgICAgICAg4paI4paIICAg4paI4paIICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAg4paR4paI4paIICAgICAg4paI4paR4paR4paR4paI4paIICAgICAgICAg4paR4paI4paIICDilpHilojiloggICAgICAgICAgICAgICAgICAgICAKICDilojilojilojilojilojilojilpHilojiloggICAgIOKWkeKWiCAg4paI4paR4paIIOKWiOKWiOKWiOKWiOKWiOKWiCDilojilojilojilojilojilojilpHilojiloggICAgICDilojiloggICDilojiloggIOKWiOKWiOKWiOKWiOKWiOKWiAog4paI4paI4paR4paR4paR4paRIOKWkeKWiOKWiOKWiOKWiOKWiOKWiCDilpHilogg4paIIOKWkeKWiOKWkeKWkeKWiOKWiOKWkeKWkeKWiOKWkeKWkeKWkeKWiOKWiOKWkSDilpHilojilojilojilojilojilogg4paR4paI4paIICDilpHilojilogg4paI4paI4paR4paR4paR4paRIArilpHilpHilojilojilojilojilogg4paR4paI4paI4paR4paR4paR4paI4paI4paR4paI4paIICDilpHilogg4paR4paI4paIIOKWkSAgIOKWkeKWiOKWiCAg4paR4paI4paI4paR4paR4paR4paI4paI4paR4paI4paIICDilpHilojilojilpHilpHilojilojilojilojiloggCiDilpHilpHilpHilpHilpHilojilojilpHilojiloggIOKWkeKWiOKWiOKWkeKWiCAgIOKWkeKWiCDilpHilojiloggICAgIOKWkeKWiOKWiCAg4paR4paI4paIICDilpHilojilojilpHilojiloggIOKWkeKWiOKWiCDilpHilpHilpHilpHilpHilojilogKIOKWiOKWiOKWiOKWiOKWiOKWiCDilpHilojiloggIOKWkeKWiOKWiOKWkSDilojilojilojilogg4paR4paI4paI4paIICAgICDilpHilpHilojilogg4paR4paI4paI4paI4paI4paI4paIIOKWkeKWkeKWiOKWiOKWiOKWiOKWiOKWiCDilojilojilojilojilojiloggCuKWkeKWkeKWkeKWkeKWkeKWkSAg4paR4paRICAg4paR4paRICDilpHilpHilpHilpEgIOKWkeKWkeKWkSAgICAgICDilpHilpEgIOKWkeKWkeKWkeKWkeKWkSAgICDilpHilpHilpHilpHilpHilpEg4paR4paR4paR4paR4paR4paRICAK" + fmt.Println(b64d(data)) + return +} + +func contains(s []string, v string) bool { + for _, a := range s { + if a == v { + return true + } + } + return false +} + +func printSlice(s []string) { + fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) +} +