mirror of
https://github.com/bettercap/bettercap
synced 2025-08-19 04:59:25 -07:00
Refactor if/else and switch for the modules package
This commit is contained in:
parent
ed6d40f163
commit
191e8eacff
34 changed files with 326 additions and 199 deletions
|
@ -82,17 +82,23 @@ func (p *AnyProxy) Configure() error {
|
|||
|
||||
if p.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, iface = p.StringParam("any.proxy.iface"); err != nil {
|
||||
}
|
||||
if err, iface = p.StringParam("any.proxy.iface"); err != nil {
|
||||
return err
|
||||
} else if err, protocol = p.StringParam("any.proxy.protocol"); err != nil {
|
||||
}
|
||||
if err, protocol = p.StringParam("any.proxy.protocol"); err != nil {
|
||||
return err
|
||||
} else if err, srcPort = p.IntParam("any.proxy.src_port"); err != nil {
|
||||
}
|
||||
if err, srcPort = p.IntParam("any.proxy.src_port"); err != nil {
|
||||
return err
|
||||
} else if err, dstPort = p.IntParam("any.proxy.dst_port"); err != nil {
|
||||
}
|
||||
if err, dstPort = p.IntParam("any.proxy.dst_port"); err != nil {
|
||||
return err
|
||||
} else if err, srcAddress = p.StringParam("any.proxy.src_address"); err != nil {
|
||||
}
|
||||
if err, srcAddress = p.StringParam("any.proxy.src_address"); err != nil {
|
||||
return err
|
||||
} else if err, dstAddress = p.StringParam("any.proxy.dst_address"); err != nil {
|
||||
}
|
||||
if err, dstAddress = p.StringParam("any.proxy.dst_address"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -128,25 +128,35 @@ func (api *RestAPI) Configure() error {
|
|||
|
||||
if api.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, ip = api.StringParam("api.rest.address"); err != nil {
|
||||
}
|
||||
if err, ip = api.StringParam("api.rest.address"); err != nil {
|
||||
return err
|
||||
} else if err, port = api.IntParam("api.rest.port"); err != nil {
|
||||
}
|
||||
if err, port = api.IntParam("api.rest.port"); err != nil {
|
||||
return err
|
||||
} else if err, api.allowOrigin = api.StringParam("api.rest.alloworigin"); err != nil {
|
||||
}
|
||||
if err, api.allowOrigin = api.StringParam("api.rest.alloworigin"); err != nil {
|
||||
return err
|
||||
} else if err, api.certFile = api.StringParam("api.rest.certificate"); err != nil {
|
||||
}
|
||||
if err, api.certFile = api.StringParam("api.rest.certificate"); err != nil {
|
||||
return err
|
||||
} else if api.certFile, err = fs.Expand(api.certFile); err != nil {
|
||||
}
|
||||
if api.certFile, err = fs.Expand(api.certFile); err != nil {
|
||||
return err
|
||||
} else if err, api.keyFile = api.StringParam("api.rest.key"); err != nil {
|
||||
}
|
||||
if err, api.keyFile = api.StringParam("api.rest.key"); err != nil {
|
||||
return err
|
||||
} else if api.keyFile, err = fs.Expand(api.keyFile); err != nil {
|
||||
}
|
||||
if api.keyFile, err = fs.Expand(api.keyFile); err != nil {
|
||||
return err
|
||||
} else if err, api.username = api.StringParam("api.rest.username"); err != nil {
|
||||
}
|
||||
if err, api.username = api.StringParam("api.rest.username"); err != nil {
|
||||
return err
|
||||
} else if err, api.password = api.StringParam("api.rest.password"); err != nil {
|
||||
}
|
||||
if err, api.password = api.StringParam("api.rest.password"); err != nil {
|
||||
return err
|
||||
} else if err, api.useWebsocket = api.BoolParam("api.rest.websocket"); err != nil {
|
||||
}
|
||||
if err, api.useWebsocket = api.BoolParam("api.rest.websocket"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ func (api *RestAPI) checkAuth(r *http.Request) bool {
|
|||
// timing attack my ass
|
||||
if subtle.ConstantTimeCompare([]byte(user), []byte(api.username)) != 1 {
|
||||
return false
|
||||
} else if subtle.ConstantTimeCompare([]byte(pass), []byte(api.password)) != 1 {
|
||||
}
|
||||
if subtle.ConstantTimeCompare([]byte(pass), []byte(api.password)) != 1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -184,10 +185,12 @@ func (api *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) {
|
|||
if !api.checkAuth(r) {
|
||||
setAuthFailed(w, r)
|
||||
return
|
||||
} else if r.Method == "POST" {
|
||||
}
|
||||
if r.Method == "POST" {
|
||||
api.runSessionCommand(w, r)
|
||||
return
|
||||
} else if r.Method != "GET" {
|
||||
}
|
||||
if r.Method != "GET" {
|
||||
http.Error(w, "Bad Request", 400)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -92,13 +92,17 @@ func (p *ArpSpoofer) Configure() error {
|
|||
|
||||
if err, p.internal = p.BoolParam("arp.spoof.internal"); err != nil {
|
||||
return err
|
||||
} else if err, targets = p.StringParam("arp.spoof.targets"); err != nil {
|
||||
}
|
||||
if err, targets = p.StringParam("arp.spoof.targets"); err != nil {
|
||||
return err
|
||||
} else if err, whitelist = p.StringParam("arp.spoof.whitelist"); err != nil {
|
||||
}
|
||||
if err, whitelist = p.StringParam("arp.spoof.whitelist"); err != nil {
|
||||
return err
|
||||
} else if p.addresses, p.macs, err = network.ParseTargets(targets, p.Session.Lan.Aliases()); err != nil {
|
||||
}
|
||||
if p.addresses, p.macs, err = network.ParseTargets(targets, p.Session.Lan.Aliases()); err != nil {
|
||||
return err
|
||||
} else if p.wAddresses, p.wMacs, err = network.ParseTargets(whitelist, p.Session.Lan.Aliases()); err != nil {
|
||||
}
|
||||
if p.wAddresses, p.wMacs, err = network.ParseTargets(whitelist, p.Session.Lan.Aliases()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -236,10 +240,12 @@ func (p *ArpSpoofer) sendArp(saddr net.IP, smac net.HardwareAddr, check_running
|
|||
for ip, mac := range targets {
|
||||
if check_running && !p.Running() {
|
||||
return
|
||||
} else if p.isWhitelisted(ip, mac) {
|
||||
}
|
||||
if p.isWhitelisted(ip, mac) {
|
||||
log.Debug("%s (%s) is whitelisted, skipping from spoofing loop.", ip, mac)
|
||||
continue
|
||||
} else if saddr.String() == ip {
|
||||
}
|
||||
if saddr.String() == ip {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,8 @@ func (d *BLERecon) enumAllTheThings(mac string) error {
|
|||
dev, found := d.Session.BLE.Get(mac)
|
||||
if !found || dev == nil {
|
||||
return fmt.Errorf("BLE device with address %s not found.", mac)
|
||||
} else if d.Running() {
|
||||
}
|
||||
if d.Running() {
|
||||
d.gattDevice.StopScanning()
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ func (d *BLERecon) onPeriphConnected(p gatt.Peripheral, err error) {
|
|||
if err != nil {
|
||||
log.Warning("Connected to %s but with error: %s", p.ID(), err)
|
||||
return
|
||||
} else if d.currDevice == nil {
|
||||
}
|
||||
if d.currDevice == nil {
|
||||
// timed out
|
||||
log.Warning("Connected to %s but after the timeout :(", p.ID())
|
||||
return
|
||||
|
|
|
@ -117,9 +117,8 @@ func parseRawData(raw []byte) string {
|
|||
return fmt.Sprintf("%x", raw)
|
||||
} else if b == 0 {
|
||||
break
|
||||
} else {
|
||||
s += fmt.Sprintf("%c", b)
|
||||
}
|
||||
s += fmt.Sprintf("%c", b)
|
||||
}
|
||||
|
||||
return tui.Yellow(s)
|
||||
|
|
|
@ -89,17 +89,23 @@ func (s *DNSSpoofer) Configure() error {
|
|||
|
||||
if s.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if s.Handle, err = pcap.OpenLive(s.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil {
|
||||
}
|
||||
if s.Handle, err = pcap.OpenLive(s.Session.Interface.Name(), 65536, true, pcap.BlockForever); err != nil {
|
||||
return err
|
||||
} else if err = s.Handle.SetBPFFilter("udp"); err != nil {
|
||||
}
|
||||
if err = s.Handle.SetBPFFilter("udp"); err != nil {
|
||||
return err
|
||||
} else if err, s.All = s.BoolParam("dns.spoof.all"); err != nil {
|
||||
}
|
||||
if err, s.All = s.BoolParam("dns.spoof.all"); err != nil {
|
||||
return err
|
||||
} else if err, address = s.IPParam("dns.spoof.address"); err != nil {
|
||||
}
|
||||
if err, address = s.IPParam("dns.spoof.address"); err != nil {
|
||||
return err
|
||||
} else if err, domains = s.ListParam("dns.spoof.domains"); err != nil {
|
||||
}
|
||||
if err, domains = s.ListParam("dns.spoof.domains"); err != nil {
|
||||
return err
|
||||
} else if err, hostsFile = s.StringParam("dns.spoof.hosts"); err != nil {
|
||||
}
|
||||
if err, hostsFile = s.StringParam("dns.spoof.hosts"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,14 @@ func (s *EventsStream) shouldDumpHttpRequest(req HTTPRequest) bool {
|
|||
func (s *EventsStream) shouldDumpHttpResponse(res HTTPResponse) bool {
|
||||
if s.dumpHttpResp {
|
||||
return true
|
||||
} else if strings.Contains(res.ContentType, "text/plain") {
|
||||
}
|
||||
if strings.Contains(res.ContentType, "text/plain") {
|
||||
return true
|
||||
} else if strings.Contains(res.ContentType, "application/json") {
|
||||
}
|
||||
if strings.Contains(res.ContentType, "application/json") {
|
||||
return true
|
||||
} else if strings.Contains(res.ContentType, "text/xml") {
|
||||
}
|
||||
if strings.Contains(res.ContentType, "text/xml") {
|
||||
return true
|
||||
}
|
||||
// search for interesting headers
|
||||
|
@ -90,7 +93,8 @@ func (s *EventsStream) dumpGZIP(body []byte) string {
|
|||
reader, err := gzip.NewReader(buffer)
|
||||
if err != nil {
|
||||
return s.dumpRaw(body)
|
||||
} else if _, err = uncompressed.ReadFrom(reader); err != nil {
|
||||
}
|
||||
if _, err = uncompressed.ReadFrom(reader); err != nil {
|
||||
return s.dumpRaw(body)
|
||||
}
|
||||
return s.dumpRaw(uncompressed.Bytes())
|
||||
|
|
|
@ -74,9 +74,11 @@ func (gps *GPS) Author() string {
|
|||
func (gps *GPS) Configure() (err error) {
|
||||
if gps.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, gps.serialPort = gps.StringParam("gps.device"); err != nil {
|
||||
}
|
||||
if err, gps.serialPort = gps.StringParam("gps.device"); err != nil {
|
||||
return err
|
||||
} else if err, gps.baudRate = gps.IntParam("gps.baudrate"); err != nil {
|
||||
}
|
||||
if err, gps.baudRate = gps.IntParam("gps.baudrate"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -80,17 +80,23 @@ func (p *HttpProxy) Configure() error {
|
|||
|
||||
if p.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, address = p.StringParam("http.proxy.address"); err != nil {
|
||||
}
|
||||
if err, address = p.StringParam("http.proxy.address"); err != nil {
|
||||
return err
|
||||
} else if err, proxyPort = p.IntParam("http.proxy.port"); err != nil {
|
||||
}
|
||||
if err, proxyPort = p.IntParam("http.proxy.port"); err != nil {
|
||||
return err
|
||||
} else if err, httpPort = p.IntParam("http.port"); err != nil {
|
||||
}
|
||||
if err, httpPort = p.IntParam("http.port"); err != nil {
|
||||
return err
|
||||
} else if err, scriptPath = p.StringParam("http.proxy.script"); err != nil {
|
||||
}
|
||||
if err, scriptPath = p.StringParam("http.proxy.script"); err != nil {
|
||||
return err
|
||||
} else if err, stripSSL = p.BoolParam("http.proxy.sslstrip"); err != nil {
|
||||
}
|
||||
if err, stripSSL = p.BoolParam("http.proxy.sslstrip"); err != nil {
|
||||
return err
|
||||
} else if err, jsToInject = p.StringParam("http.proxy.injectjs"); err != nil {
|
||||
}
|
||||
if err, jsToInject = p.StringParam("http.proxy.injectjs"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -119,11 +119,11 @@ func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scrip
|
|||
if strings.HasPrefix(jsToInject, "http://") || strings.HasPrefix(jsToInject, "https://") {
|
||||
p.jsHook = fmt.Sprintf("<script src=\"%s\" type=\"text/javascript\"></script></head>", jsToInject)
|
||||
} else if fs.Exists(jsToInject) {
|
||||
if data, err := ioutil.ReadFile(jsToInject); err != nil {
|
||||
data, err := ioutil.ReadFile(jsToInject)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
jsToInject = string(data)
|
||||
}
|
||||
jsToInject = string(data)
|
||||
}
|
||||
|
||||
if p.jsHook == "" && jsToInject != "" {
|
||||
|
@ -134,11 +134,11 @@ func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, scrip
|
|||
}
|
||||
|
||||
if scriptPath != "" {
|
||||
if err, p.Script = LoadHttpProxyScript(scriptPath, p.sess); err != nil {
|
||||
err, p.Script = LoadHttpProxyScript(scriptPath, p.sess)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
log.Debug("Proxy script %s loaded.", scriptPath)
|
||||
}
|
||||
log.Debug("Proxy script %s loaded.", scriptPath)
|
||||
}
|
||||
|
||||
p.Server = &http.Server{
|
||||
|
|
|
@ -24,12 +24,12 @@ func NewCookieTracker() *CookieTracker {
|
|||
}
|
||||
|
||||
func (t *CookieTracker) domainOf(req *http.Request) string {
|
||||
if parsed, err := tld.Parse(req.Host); err != nil {
|
||||
parsed, err := tld.Parse(req.Host)
|
||||
if err != nil {
|
||||
log.Warning("Could not parse host %s: %s", req.Host, err)
|
||||
return req.Host
|
||||
} else {
|
||||
return fmt.Sprintf("%s.%s", parsed.Domain, parsed.TLD)
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", parsed.Domain, parsed.TLD)
|
||||
}
|
||||
|
||||
func (t *CookieTracker) keyOf(req *http.Request) string {
|
||||
|
|
|
@ -43,7 +43,8 @@ func (p *HTTPProxy) onRequestFilter(req *http.Request, ctx *goproxy.ProxyCtx) (*
|
|||
// the request has been changed by the script
|
||||
p.logRequestAction(req, jsreq)
|
||||
return jsreq.ToRequest(), nil
|
||||
} else if jsres != nil {
|
||||
}
|
||||
if jsres != nil {
|
||||
// a fake response has been returned by the script
|
||||
p.logResponseAction(req, jsres)
|
||||
return req, jsres.ToResponse(req)
|
||||
|
@ -98,7 +99,8 @@ func (p *HTTPProxy) doScriptInjection(res *http.Response, cType string) (error,
|
|||
raw, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
} else if html := string(raw); strings.Contains(html, "</head>") {
|
||||
}
|
||||
if html := string(raw); strings.Contains(html, "</head>") {
|
||||
log.Info("(%s) > injecting javascript (%d bytes) into %s (%d bytes) for %s",
|
||||
tui.Green(p.Name),
|
||||
len(p.jsHook),
|
||||
|
|
|
@ -272,10 +272,9 @@ func (s *SSLStripper) isMaxRedirs(hostname string) bool {
|
|||
// reset
|
||||
delete(s.redirs, hostname)
|
||||
return true
|
||||
} else {
|
||||
}
|
||||
// increment
|
||||
s.redirs[hostname]++
|
||||
}
|
||||
} else {
|
||||
// start tracking redirections
|
||||
s.redirs[hostname] = 1
|
||||
|
|
|
@ -65,10 +65,12 @@ func (j *JSResponse) WasModified() bool {
|
|||
if j.bodyRead {
|
||||
// body was read
|
||||
return true
|
||||
} else if j.bodyClear {
|
||||
}
|
||||
if j.bodyClear {
|
||||
// body was cleared manually
|
||||
return true
|
||||
} else if j.Body != "" {
|
||||
}
|
||||
if j.Body != "" {
|
||||
// body was not read but just set
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -58,10 +58,12 @@ func (s *HttpProxyScript) OnRequest(original *http.Request) (jsreq *JSRequest, j
|
|||
if _, err := s.Call("onRequest", jsreq, jsres); err != nil {
|
||||
log.Error("%s", err)
|
||||
return nil, nil
|
||||
} else if jsreq.WasModified() {
|
||||
}
|
||||
if jsreq.WasModified() {
|
||||
jsreq.UpdateHash()
|
||||
return jsreq, nil
|
||||
} else if jsres.WasModified() {
|
||||
}
|
||||
if jsres.WasModified() {
|
||||
jsres.UpdateHash()
|
||||
return nil, jsres
|
||||
}
|
||||
|
@ -89,10 +91,13 @@ func (s *HttpProxyScript) OnResponse(res *http.Response) (jsreq *JSRequest, jsre
|
|||
|
||||
func (s *HttpProxyScript) OnCommand(cmd string) bool {
|
||||
if s.doOnCommand {
|
||||
if ret, err := s.Call("onCommand", cmd); err != nil {
|
||||
ret, err := s.Call("onCommand", cmd)
|
||||
if err != nil {
|
||||
log.Error("Error while executing onCommand callback: %+v", err)
|
||||
return false
|
||||
} else if v, ok := ret.(bool); ok {
|
||||
}
|
||||
v, ok := ret.(bool)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,25 +98,35 @@ func (p *HttpsProxy) Configure() error {
|
|||
|
||||
if p.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, address = p.StringParam("https.proxy.address"); err != nil {
|
||||
}
|
||||
if err, address = p.StringParam("https.proxy.address"); err != nil {
|
||||
return err
|
||||
} else if err, proxyPort = p.IntParam("https.proxy.port"); err != nil {
|
||||
}
|
||||
if err, proxyPort = p.IntParam("https.proxy.port"); err != nil {
|
||||
return err
|
||||
} else if err, httpPort = p.IntParam("https.port"); err != nil {
|
||||
}
|
||||
if err, httpPort = p.IntParam("https.port"); err != nil {
|
||||
return err
|
||||
} else if err, stripSSL = p.BoolParam("https.proxy.sslstrip"); err != nil {
|
||||
}
|
||||
if err, stripSSL = p.BoolParam("https.proxy.sslstrip"); err != nil {
|
||||
return err
|
||||
} else if err, certFile = p.StringParam("https.proxy.certificate"); err != nil {
|
||||
}
|
||||
if err, certFile = p.StringParam("https.proxy.certificate"); err != nil {
|
||||
return err
|
||||
} else if certFile, err = fs.Expand(certFile); err != nil {
|
||||
}
|
||||
if certFile, err = fs.Expand(certFile); err != nil {
|
||||
return err
|
||||
} else if err, keyFile = p.StringParam("https.proxy.key"); err != nil {
|
||||
}
|
||||
if err, keyFile = p.StringParam("https.proxy.key"); err != nil {
|
||||
return err
|
||||
} else if keyFile, err = fs.Expand(keyFile); err != nil {
|
||||
}
|
||||
if keyFile, err = fs.Expand(keyFile); err != nil {
|
||||
return err
|
||||
} else if err, scriptPath = p.StringParam("https.proxy.script"); err != nil {
|
||||
}
|
||||
if err, scriptPath = p.StringParam("https.proxy.script"); err != nil {
|
||||
return err
|
||||
} else if err, jsToInject = p.StringParam("https.proxy.injectjs"); err != nil {
|
||||
}
|
||||
if err, jsToInject = p.StringParam("https.proxy.injectjs"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ func (mc *MacChanger) Configure() (err error) {
|
|||
|
||||
if err, mc.iface = mc.StringParam("mac.changer.iface"); err != nil {
|
||||
return err
|
||||
} else if err, changeTo = mc.StringParam("mac.changer.address"); err != nil {
|
||||
}
|
||||
if err, changeTo = mc.StringParam("mac.changer.address"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -105,9 +106,11 @@ func (mc *MacChanger) setMac(mac net.HardwareAddr) error {
|
|||
func (mc *MacChanger) Start() error {
|
||||
if mc.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err := mc.Configure(); err != nil {
|
||||
}
|
||||
if err := mc.Configure(); err != nil {
|
||||
return err
|
||||
} else if err := mc.setMac(mc.fakeMac); err != nil {
|
||||
}
|
||||
if err := mc.setMac(mc.fakeMac); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -82,17 +82,23 @@ func (mysql *MySQLServer) Configure() error {
|
|||
|
||||
if mysql.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, mysql.infile = mysql.StringParam("mysql.server.infile"); err != nil {
|
||||
}
|
||||
if err, mysql.infile = mysql.StringParam("mysql.server.infile"); err != nil {
|
||||
return err
|
||||
} else if err, mysql.outfile = mysql.StringParam("mysql.server.outfile"); err != nil {
|
||||
}
|
||||
if err, mysql.outfile = mysql.StringParam("mysql.server.outfile"); err != nil {
|
||||
return err
|
||||
} else if err, address = mysql.StringParam("mysql.server.address"); err != nil {
|
||||
}
|
||||
if err, address = mysql.StringParam("mysql.server.address"); err != nil {
|
||||
return err
|
||||
} else if err, port = mysql.IntParam("mysql.server.port"); err != nil {
|
||||
}
|
||||
if err, port = mysql.IntParam("mysql.server.port"); err != nil {
|
||||
return err
|
||||
} else if mysql.address, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil {
|
||||
}
|
||||
if mysql.address, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil {
|
||||
return err
|
||||
} else if mysql.listener, err = net.ListenTCP("tcp", mysql.address); err != nil {
|
||||
}
|
||||
if mysql.listener, err = net.ListenTCP("tcp", mysql.address); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -141,13 +147,16 @@ func (mysql *MySQLServer) Start() error {
|
|||
if _, err := conn.Write(packets.MySQLFirstResponseOK); err != nil {
|
||||
log.Warning("[%s] error while writing server first response ok: %s", tui.Green("mysql.server"), err)
|
||||
continue
|
||||
} else if _, err := reader.Read(readBuffer); err != nil {
|
||||
}
|
||||
if _, err := reader.Read(readBuffer); err != nil {
|
||||
log.Warning("[%s] error while reading client message: %s", tui.Green("mysql.server"), err)
|
||||
continue
|
||||
} else if _, err := conn.Write(packets.MySQLGetFile(mysql.infile)); err != nil {
|
||||
}
|
||||
if _, err := conn.Write(packets.MySQLGetFile(mysql.infile)); err != nil {
|
||||
log.Warning("[%s] error while writing server get file request: %s", tui.Green("mysql.server"), err)
|
||||
continue
|
||||
} else if read, err = reader.Read(readBuffer); err != nil {
|
||||
}
|
||||
if read, err = reader.Read(readBuffer); err != nil {
|
||||
log.Warning("[%s] error while readind buffer: %s", tui.Green("mysql.server"), err)
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -82,17 +82,20 @@ func (p *Prober) Configure() error {
|
|||
var err error
|
||||
if err, p.throttle = p.IntParam("net.probe.throttle"); err != nil {
|
||||
return err
|
||||
} else if err, p.probes.NBNS = p.BoolParam("net.probe.nbns"); err != nil {
|
||||
return err
|
||||
} else if err, p.probes.MDNS = p.BoolParam("net.probe.mdns"); err != nil {
|
||||
return err
|
||||
} else if err, p.probes.UPNP = p.BoolParam("net.probe.upnp"); err != nil {
|
||||
return err
|
||||
} else if err, p.probes.WSD = p.BoolParam("net.probe.wsd"); err != nil {
|
||||
return err
|
||||
} else {
|
||||
log.Debug("Throttling packets of %d ms.", p.throttle)
|
||||
}
|
||||
if err, p.probes.NBNS = p.BoolParam("net.probe.nbns"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err, p.probes.MDNS = p.BoolParam("net.probe.mdns"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err, p.probes.UPNP = p.BoolParam("net.probe.upnp"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err, p.probes.WSD = p.BoolParam("net.probe.wsd"); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug("Throttling packets of %d ms.", p.throttle)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -136,10 +139,12 @@ func (p *Prober) Start() error {
|
|||
for _, ip := range addresses {
|
||||
if !p.Running() {
|
||||
return
|
||||
} else if p.Session.Skip(ip) {
|
||||
}
|
||||
if p.Session.Skip(ip) {
|
||||
log.Debug("skipping address %s from probing.", ip)
|
||||
continue
|
||||
} else if p.probes.NBNS {
|
||||
}
|
||||
if p.probes.NBNS {
|
||||
p.sendProbeNBNS(from, from_hw, ip)
|
||||
}
|
||||
time.Sleep(throttle)
|
||||
|
|
|
@ -12,7 +12,8 @@ func (p *Prober) sendProbeMDNS(from net.IP, from_hw net.HardwareAddr) {
|
|||
if err != nil {
|
||||
log.Error("error while sending mdns probe: %v", err)
|
||||
return
|
||||
} else if err := p.Session.Queue.Send(raw); err != nil {
|
||||
}
|
||||
if err := p.Session.Queue.Send(raw); err != nil {
|
||||
log.Error("error sending mdns packet: %s", err)
|
||||
} else {
|
||||
log.Debug("sent %d bytes of MDNS probe", len(raw))
|
||||
|
|
|
@ -88,7 +88,8 @@ func (d *Discovery) getRow(e *network.Endpoint, withMeta bool) [][]string {
|
|||
|
||||
if !withMeta {
|
||||
return [][]string{row}
|
||||
} else if e.Meta.Empty() {
|
||||
}
|
||||
if e.Meta.Empty() {
|
||||
return [][]string{append(row, tui.Dim("-"))}
|
||||
}
|
||||
|
||||
|
@ -120,13 +121,14 @@ func (d *Discovery) Show(by string, expr string) (err error) {
|
|||
targets = d.Session.Lan.List()
|
||||
}
|
||||
|
||||
if by == "seen" {
|
||||
switch by {
|
||||
case "seen" :
|
||||
sort.Sort(BySeenSorter(targets))
|
||||
} else if by == "sent" {
|
||||
case "sent" :
|
||||
sort.Sort(BySentSorter(targets))
|
||||
} else if by == "rcvd" {
|
||||
case "rcvd" :
|
||||
sort.Sort(ByRcvdSorter(targets))
|
||||
} else {
|
||||
default:
|
||||
sort.Sort(ByAddressSorter(targets))
|
||||
}
|
||||
|
||||
|
@ -139,9 +141,11 @@ func (d *Discovery) Show(by string, expr string) (err error) {
|
|||
}
|
||||
|
||||
hasMeta := false
|
||||
if err, showMeta := d.BoolParam("net.show.meta"); err != nil {
|
||||
err, showMeta := d.BoolParam("net.show.meta")
|
||||
if err != nil {
|
||||
return err
|
||||
} else if showMeta {
|
||||
}
|
||||
if showMeta {
|
||||
for _, t := range targets {
|
||||
if !t.Meta.Empty() {
|
||||
hasMeta = true
|
||||
|
|
|
@ -112,7 +112,8 @@ func (s *Sniffer) Configure() error {
|
|||
|
||||
if s.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, s.Ctx = s.GetContext(); err != nil {
|
||||
}
|
||||
if err, s.Ctx = s.GetContext(); err != nil {
|
||||
if s.Ctx != nil {
|
||||
s.Ctx.Close()
|
||||
s.Ctx = nil
|
||||
|
|
|
@ -17,11 +17,14 @@ func tcpParser(ip *layers.IPv4, pkt gopacket.Packet, verbose bool) {
|
|||
|
||||
if sniParser(ip, pkt, tcp) {
|
||||
return
|
||||
} else if ntlmParser(ip, pkt, tcp) {
|
||||
}
|
||||
if ntlmParser(ip, pkt, tcp) {
|
||||
return
|
||||
} else if httpParser(ip, pkt, tcp) {
|
||||
}
|
||||
if httpParser(ip, pkt, tcp) {
|
||||
return
|
||||
} else if verbose {
|
||||
}
|
||||
if verbose {
|
||||
NewSnifferEvent(
|
||||
pkt.Metadata().Timestamp,
|
||||
"tcp",
|
||||
|
@ -46,13 +49,17 @@ func udpParser(ip *layers.IPv4, pkt gopacket.Packet, verbose bool) {
|
|||
|
||||
if dnsParser(ip, pkt, udp) {
|
||||
return
|
||||
} else if mdnsParser(ip, pkt, udp) {
|
||||
}
|
||||
if mdnsParser(ip, pkt, udp) {
|
||||
return
|
||||
} else if krb5Parser(ip, pkt, udp) {
|
||||
}
|
||||
if krb5Parser(ip, pkt, udp) {
|
||||
return
|
||||
} else if upnpParser(ip, pkt, udp) {
|
||||
}
|
||||
if upnpParser(ip, pkt, udp) {
|
||||
return
|
||||
} else if verbose {
|
||||
}
|
||||
if verbose {
|
||||
NewSnifferEvent(
|
||||
pkt.Metadata().Timestamp,
|
||||
"udp",
|
||||
|
@ -118,7 +125,8 @@ func mainParser(pkt gopacket.Packet, verbose bool) bool {
|
|||
unkParser(ip, pkt, verbose)
|
||||
}
|
||||
return true
|
||||
} else if ok, radiotap, dot11 := packets.Dot11Parse(pkt); ok {
|
||||
}
|
||||
if ok, radiotap, dot11 := packets.Dot11Parse(pkt); ok {
|
||||
// are we sniffing in monitor mode?
|
||||
dot11Parser(radiotap, dot11, pkt, verbose)
|
||||
return true
|
||||
|
|
|
@ -13,7 +13,8 @@ import (
|
|||
func vIP(ip net.IP) string {
|
||||
if session.I.Interface.IP.Equal(ip) {
|
||||
return tui.Dim("local")
|
||||
} else if session.I.Gateway.IP.Equal(ip) {
|
||||
}
|
||||
if session.I.Gateway.IP.Equal(ip) {
|
||||
return "gateway"
|
||||
}
|
||||
|
||||
|
|
|
@ -135,17 +135,21 @@ func (pp *PacketProxy) Configure() (err error) {
|
|||
|
||||
if err, pp.queueNum = pp.IntParam("packet.proxy.queue.num"); err != nil {
|
||||
return
|
||||
} else if err, pp.chainName = pp.StringParam("packet.proxy.chain"); err != nil {
|
||||
}
|
||||
if err, pp.chainName = pp.StringParam("packet.proxy.chain"); err != nil {
|
||||
return
|
||||
} else if err, pp.rule = pp.StringParam("packet.proxy.rule"); err != nil {
|
||||
}
|
||||
if err, pp.rule = pp.StringParam("packet.proxy.rule"); err != nil {
|
||||
return
|
||||
} else if err, pp.pluginPath = pp.StringParam("packet.proxy.plugin"); err != nil {
|
||||
}
|
||||
if err, pp.pluginPath = pp.StringParam("packet.proxy.plugin"); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if pp.pluginPath == "" {
|
||||
return fmt.Errorf("The parameter %s can not be empty.", tui.Bold("packet.proxy.plugin"))
|
||||
} else if !fs.Exists(pp.pluginPath) {
|
||||
}
|
||||
if !fs.Exists(pp.pluginPath) {
|
||||
return fmt.Errorf("%s does not exist.", pp.pluginPath)
|
||||
}
|
||||
|
||||
|
@ -156,26 +160,34 @@ func (pp *PacketProxy) Configure() (err error) {
|
|||
|
||||
if pp.plugin, err = plugin.Open(pp.pluginPath); err != nil {
|
||||
return
|
||||
} else if sym, err = pp.plugin.Lookup("OnPacket"); err != nil {
|
||||
}
|
||||
if sym, err = pp.plugin.Lookup("OnPacket"); err != nil {
|
||||
return
|
||||
} else if pp.queueCb, ok = sym.(func(*nfqueue.Payload) int); !ok {
|
||||
}
|
||||
if pp.queueCb, ok = sym.(func(*nfqueue.Payload) int); !ok {
|
||||
return fmt.Errorf("Symbol OnPacket is not a valid callback function.")
|
||||
}
|
||||
|
||||
pp.queue = new(nfqueue.Queue)
|
||||
if err = pp.queue.SetCallback(dummyCallback); err != nil {
|
||||
return
|
||||
} else if err = pp.queue.Init(); err != nil {
|
||||
}
|
||||
if err = pp.queue.Init(); err != nil {
|
||||
return
|
||||
} else if err = pp.queue.Unbind(syscall.AF_INET); err != nil {
|
||||
}
|
||||
if err = pp.queue.Unbind(syscall.AF_INET); err != nil {
|
||||
return
|
||||
} else if err = pp.queue.Bind(syscall.AF_INET); err != nil {
|
||||
}
|
||||
if err = pp.queue.Bind(syscall.AF_INET); err != nil {
|
||||
return
|
||||
} else if err = pp.queue.CreateQueue(pp.queueNum); err != nil {
|
||||
}
|
||||
if err = pp.queue.CreateQueue(pp.queueNum); err != nil {
|
||||
return
|
||||
} else if err = pp.queue.SetMode(nfqueue.NFQNL_COPY_PACKET); err != nil {
|
||||
}
|
||||
if err = pp.queue.SetMode(nfqueue.NFQNL_COPY_PACKET); err != nil {
|
||||
return
|
||||
} else if err = pp.runRule(true); err != nil {
|
||||
}
|
||||
if err = pp.runRule(true); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -97,27 +97,38 @@ func (p *TcpProxy) Configure() error {
|
|||
|
||||
if p.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, address = p.StringParam("tcp.address"); err != nil {
|
||||
}
|
||||
if err, address = p.StringParam("tcp.address"); err != nil {
|
||||
return err
|
||||
} else if err, proxyAddress = p.StringParam("tcp.proxy.address"); err != nil {
|
||||
}
|
||||
if err, proxyAddress = p.StringParam("tcp.proxy.address"); err != nil {
|
||||
return err
|
||||
} else if err, proxyPort = p.IntParam("tcp.proxy.port"); err != nil {
|
||||
}
|
||||
if err, proxyPort = p.IntParam("tcp.proxy.port"); err != nil {
|
||||
return err
|
||||
} else if err, port = p.IntParam("tcp.port"); err != nil {
|
||||
}
|
||||
if err, port = p.IntParam("tcp.port"); err != nil {
|
||||
return err
|
||||
} else if err, tunnelAddress = p.StringParam("tcp.tunnel.address"); err != nil {
|
||||
}
|
||||
if err, tunnelAddress = p.StringParam("tcp.tunnel.address"); err != nil {
|
||||
return err
|
||||
} else if err, tunnelPort = p.IntParam("tcp.tunnel.port"); err != nil {
|
||||
}
|
||||
if err, tunnelPort = p.IntParam("tcp.tunnel.port"); err != nil {
|
||||
return err
|
||||
} else if err, scriptPath = p.StringParam("tcp.proxy.script"); err != nil {
|
||||
}
|
||||
if err, scriptPath = p.StringParam("tcp.proxy.script"); err != nil {
|
||||
return err
|
||||
} else if p.localAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", proxyAddress, proxyPort)); err != nil {
|
||||
}
|
||||
if p.localAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", proxyAddress, proxyPort)); err != nil {
|
||||
return err
|
||||
} else if p.remoteAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil {
|
||||
}
|
||||
if p.remoteAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", address, port)); err != nil {
|
||||
return err
|
||||
} else if p.tunnelAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", tunnelAddress, tunnelPort)); err != nil {
|
||||
}
|
||||
if p.tunnelAddr, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", tunnelAddress, tunnelPort)); err != nil {
|
||||
return err
|
||||
} else if p.listener, err = net.ListenTCP("tcp", p.localAddr); err != nil {
|
||||
}
|
||||
if p.listener, err = net.ListenTCP("tcp", p.localAddr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -61,9 +61,11 @@ func (t *Ticker) Configure() error {
|
|||
|
||||
if t.Running() {
|
||||
return session.ErrAlreadyStarted
|
||||
} else if err, commands = t.StringParam("ticker.commands"); err != nil {
|
||||
}
|
||||
if err, commands = t.StringParam("ticker.commands"); err != nil {
|
||||
return err
|
||||
} else if err, period = t.IntParam("ticker.period"); err != nil {
|
||||
}
|
||||
if err, period = t.IntParam("ticker.period"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,9 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
|||
bssid, err := net.ParseMAC(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
} else if ap, found := w.Session.WiFi.Get(bssid.String()); found {
|
||||
}
|
||||
ap, found := w.Session.WiFi.Get(bssid.String())
|
||||
if found {
|
||||
w.ap = ap
|
||||
w.stickChan = ap.Channel()
|
||||
return nil
|
||||
|
@ -104,9 +106,8 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
|||
func(args []string) error {
|
||||
if err := w.parseApConfig(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
return w.startAp()
|
||||
}
|
||||
return w.startAp()
|
||||
}))
|
||||
|
||||
w.AddParam(session.NewStringParameter("wifi.ap.ssid",
|
||||
|
@ -150,11 +151,11 @@ func NewWiFiModule(s *session.Session) *WiFiModule {
|
|||
}
|
||||
} else {
|
||||
// No channels setted, retrieve frequencies supported by the card
|
||||
if frequencies, err := network.GetSupportedFrequencies(w.Session.Interface.Name()); err != nil {
|
||||
frequencies, err := network.GetSupportedFrequencies(w.Session.Interface.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
newfrequencies = frequencies
|
||||
}
|
||||
newfrequencies = frequencies
|
||||
}
|
||||
|
||||
w.frequencies = newfrequencies
|
||||
|
@ -211,18 +212,22 @@ func (w *WiFiModule) Configure() error {
|
|||
|
||||
if err = ihandle.SetRFMon(true); err != nil {
|
||||
return fmt.Errorf("Error while setting interface %s in monitor mode: %s", tui.Bold(w.Session.Interface.Name()), err)
|
||||
} else if err = ihandle.SetSnapLen(65536); err != nil {
|
||||
}
|
||||
if err = ihandle.SetSnapLen(65536); err != nil {
|
||||
return err
|
||||
} else if err = ihandle.SetTimeout(pcap.BlockForever); err != nil {
|
||||
}
|
||||
if err = ihandle.SetTimeout(pcap.BlockForever); err != nil {
|
||||
return err
|
||||
} else if w.handle, err = ihandle.Activate(); err != nil {
|
||||
}
|
||||
if w.handle, err = ihandle.Activate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err, w.skipBroken = w.BoolParam("wifi.skip-broken"); err != nil {
|
||||
return err
|
||||
} else if err, hopPeriod = w.IntParam("wifi.hop.period"); err != nil {
|
||||
}
|
||||
if err, hopPeriod = w.IntParam("wifi.hop.period"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -295,7 +300,8 @@ func (w *WiFiModule) Start() error {
|
|||
for packet := range w.pktSourceChan {
|
||||
if !w.Running() {
|
||||
break
|
||||
} else if packet == nil {
|
||||
}
|
||||
if packet == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,17 @@ func (w *WiFiModule) parseApConfig() (err error) {
|
|||
var bssid string
|
||||
if err, w.apConfig.SSID = w.StringParam("wifi.ap.ssid"); err != nil {
|
||||
return
|
||||
} else if err, bssid = w.StringParam("wifi.ap.bssid"); err != nil {
|
||||
}
|
||||
if err, bssid = w.StringParam("wifi.ap.bssid"); err != nil {
|
||||
return
|
||||
} else if w.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil {
|
||||
}
|
||||
if w.apConfig.BSSID, err = net.ParseMAC(network.NormalizeMac(bssid)); err != nil {
|
||||
return
|
||||
} else if err, w.apConfig.Channel = w.IntParam("wifi.ap.channel"); err != nil {
|
||||
}
|
||||
if err, w.apConfig.Channel = w.IntParam("wifi.ap.channel"); err != nil {
|
||||
return
|
||||
} else if err, w.apConfig.Encryption = w.BoolParam("wifi.ap.encryption"); err != nil {
|
||||
}
|
||||
if err, w.apConfig.Encryption = w.BoolParam("wifi.ap.encryption"); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
|
@ -35,7 +39,8 @@ func (w *WiFiModule) startAp() error {
|
|||
// we need channel hopping and packet injection for this
|
||||
if !w.Running() {
|
||||
return errNoRecon
|
||||
} else if w.apRunning {
|
||||
}
|
||||
if w.apRunning {
|
||||
return session.ErrAlreadyStarted
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
|
|||
recvd,
|
||||
seen,
|
||||
}, include
|
||||
} else {
|
||||
}
|
||||
// this is ugly, but necessary in order to have this
|
||||
// method handle both access point and clients
|
||||
// transparently
|
||||
|
@ -108,7 +108,6 @@ func (w *WiFiModule) getRow(station *network.Station) ([]string, bool) {
|
|||
seen,
|
||||
}, include
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WiFiModule) Show(by string) error {
|
||||
var stations []*network.Station
|
||||
|
@ -123,14 +122,14 @@ func (w *WiFiModule) Show(by string) error {
|
|||
} else {
|
||||
stations = w.Session.WiFi.Stations()
|
||||
}
|
||||
|
||||
if by == "seen" {
|
||||
switch by {
|
||||
case "seen":
|
||||
sort.Sort(ByWiFiSeenSorter(stations))
|
||||
} else if by == "essid" {
|
||||
case "essid":
|
||||
sort.Sort(ByEssidSorter(stations))
|
||||
} else if by == "channel" {
|
||||
case "channel":
|
||||
sort.Sort(ByChannelSorter(stations))
|
||||
} else {
|
||||
default:
|
||||
sort.Sort(ByRSSISorter(stations))
|
||||
}
|
||||
|
||||
|
|
|
@ -31,21 +31,21 @@ func NewWOL(s *session.Session) *WOL {
|
|||
w.AddHandler(session.NewModuleHandler("wol.eth MAC", "wol.eth(\\s.+)?",
|
||||
"Send a WOL as a raw ethernet packet of type 0x0847 (if no MAC is specified, ff:ff:ff:ff:ff:ff will be used).",
|
||||
func(args []string) error {
|
||||
if mac, err := parseMAC(args); err != nil {
|
||||
mac, err := parseMAC(args)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
return w.wolETH(mac)
|
||||
}
|
||||
return w.wolETH(mac)
|
||||
}))
|
||||
|
||||
w.AddHandler(session.NewModuleHandler("wol.udp MAC", "wol.udp(\\s.+)?",
|
||||
"Send a WOL as an IPv4 broadcast packet to UDP port 9 (if no MAC is specified, ff:ff:ff:ff:ff:ff will be used).",
|
||||
func(args []string) error {
|
||||
if mac, err := parseMAC(args); err != nil {
|
||||
mac, err := parseMAC(args)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
return w.wolUDP(mac)
|
||||
}
|
||||
return w.wolUDP(mac)
|
||||
}))
|
||||
|
||||
return w
|
||||
|
@ -58,9 +58,8 @@ func parseMAC(args []string) (string, error) {
|
|||
if tmp != "" {
|
||||
if !reMAC.MatchString(tmp) {
|
||||
return "", fmt.Errorf("%s is not a valid MAC address.", tmp)
|
||||
} else {
|
||||
mac = tmp
|
||||
}
|
||||
mac = tmp
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,11 +19,10 @@ func cleanESSID(essid string) string {
|
|||
res := ""
|
||||
|
||||
for _, c := range essid {
|
||||
if strconv.IsPrint(c) {
|
||||
res += string(c)
|
||||
} else {
|
||||
if !strconv.IsPrint(c) {
|
||||
break
|
||||
}
|
||||
res += string(c)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue