github-vet / github-vet/rangeloop-pointer-findings
rhowell7/startTLS_go: smtpConnection.go; 170 LoC
- Dominant language
- No language data
- Stars
- 0
- Forks
- 0
- PR merge metrics
- PR metrics pending
Description
Found a possible issue in [rhowell7/startTLS_go](https://www.github.com/rhowell7/startTLS_go) at [smtpConnection.go](https://github.com/rhowell7/startTLS_go/blob/a529003c2f46188f63a201c707729ee701e922b3/smtpConnection.go#L232-L401)
Below is the message reported by the analyzer for this snippet of code. Beware that the analyzer only reports the first issue it finds, so please do not limit your consideration to the contents of the below message.
> range-loop variable ip used in defer or goroutine at line 239
[Click here to see the code in its original context.](https://github.com/rhowell7/startTLS_go/blob/a529003c2f46188f63a201c707729ee701e922b3/smtpConnection.go#L232-L401)
Click here to show the 170 line(s) of Go which triggered the analyzer.
```go
for ip := range input_chan {
//------------ Get an IP Address from input_chan -------------//
m.Lock()
in_process[ip] = c
m.Unlock()
defer func() {
m.Lock()
delete(in_process, ip)
m.Unlock()
}()
target := ip+":25"
fmt.Print("\nTarget: ", ip)
//------------------ Open the SMTP connection ----------------//
timeOut := time.Duration(3) * time.Second
conn, err := net.DialTimeout("tcp", target, timeOut)
if err != nil {
fmt.Println("\ndial error:", err)
continue
}
defer conn.Close()
// Wait for 220 banner
banner, err := bufio.NewReader(conn).ReadString('\n')
// fmt.Println(banner)
// Are we being greylisted/blacklisted?
bannerGood, err := regexp.MatchString("220 ", string(banner))
if !bannerGood {
fmt.Println("\nThis server did not give us a good banner: ",
target)
fmt.Println(banner)
continue
}
//---------------- Send EHLO, receive Extensions -------------//
conn.Write([]byte("EHLO ME\r\n"))
bufReader := bufio.NewReader(conn)
for {
// Read tokens delimited by newline
extensions, err := bufReader.ReadBytes('\n')
if err != nil { // if there's an error
fmt.Println()
break
}
// fmt.Printf("%s", extensions)
done, err := regexp.MatchString("250 ", string(extensions))
if done {
// Extensions start with 250-, except the last one is just 250
// fmt.Println("Found the last extension\n")
fmt.Println()
break
}
// 500 5.5.1 Command unrecognized: "XXXX ME"
ehloError, err := regexp.MatchString("500 ", string(extensions))
if ehloError {
// fmt.Println("got a 500 error: ", string(extensions))
// fmt.Println("Sending 'HELO' instead")
conn.Write([]byte("HELO ME\r\n"))
}
} // for (receiving extensions)
//----------------- Send magic StartTLS packets ------------------//
tcpResponseChan := make(chan []byte)
hostTimeoutChan := make(chan bool)
//--------------------- TCP Listener -------------------------//
w.Add(1)
go func() {
defer w.Done()
defer fmt.Println("TCP Listener goroutine has finished")
tlsResponse, err := bufReader.ReadBytes('\n')
if err != nil { // if there's an error
fmt.Println()
// break
hostTimeoutChan <- true
}
tcpResponseChan <- tlsResponse
}() // TCP Listener
hostDone := false
results := Output{TargetIP: ip}
// Fork a new ipv4 connection from the original one
startTlsConn := ipv4.NewConn(conn)
if err != nil {
fmt.Println("Forking conn error:", err)
return
}
defer startTlsConn.Close()
// Send the fudged StartTLS packets
ttl := minTTL
for ; ttl < maxTTL && !hostDone; ttl++ {
startTlsConn.SetTTL(ttl)
startTlsConn.Write([]byte("STARTTLS\r\n"))
// fmt.Println("\n\nSent STARTTLS packet with TTL: ", ttl)
hopDone := false
for !hopDone && !hostDone {
select {
case icmpPkt := <- c:
// got an icmp packet, add it to results
hopDone = true
hop_ip := icmpPkt.ReachedIPv4
hop_response := strings.Replace(icmpPkt.Data, "\n", "", -1)
hop_response = strings.Replace(hop_response, "\u0000", "", -1)
hop_result := Hop{IP: hop_ip, HopOutput: hop_response, Hop: ttl}
results.Hops = append(results.Hops, hop_result)
hop_censored, _ := regexp.MatchString("XXX", hop_response)
if hop_censored && results.FirstCensoredIP == "" {
// fmt.Println("First censored hop: ", ttl, ": ", hop_ip)
results.FirstCensoredHop = ttl
results.FirstCensoredIP = hop_ip
}
hop_uncensored, _ := regexp.MatchString("STARTTLS", hop_response)
if hop_uncensored {
// fmt.Println("Uncensored hop: ", ttl, ": ", hop_ip)
results.LastUncensoredHop = ttl
results.LastUncensoredIP = hop_ip
}
fmt.Print("Hop ", ttl, ": ", hop_ip)
fmt.Println("\tICMP Packet: ", hop_response)
continue
case tcpBytes := <- tcpResponseChan:
// got a TCP packet, add it to results and break
hostDone = true
hopDone = true
tcpResponse := string(tcpBytes)
hop_censored, _ := regexp.MatchString("XXX", tcpResponse)
if hop_censored && results.FirstCensoredIP == "" {
// fmt.Println("First censored hop: ", ttl, ": ", ip)
results.FirstCensoredHop = ttl
results.FirstCensoredIP = ip
results.TcpResponse = tcpResponse
results.Censored = true
}
output_chan <- results
fmt.Print("Hop ", ttl, ": ")
fmt.Print(ip)
fmt.Println("\tTCP Response: ", tcpResponse)
break
case <-time.After(hopTimeout * time.Second):
hopDone = true
continue
case <-time.After(hostTimeout * time.Second):
hostDone = true
fmt.Println("Host timed out")
break
} // select: ICMP, TCP, or timeout?
} // for !hopDone && !hostDone
} // for ; ttl < maxTTL && !hostDone
} // for ip := range input_chan
```
Leave a reaction on this issue to contribute to the project by classifying this instance as a **Bug** :-1:, **Mitigated** :+1:, or **Desirable Behavior** :rocket:
See the descriptions of the classifications [here](https://github.com/github-vet/rangeclosure-findings#how-can-i-help) for more information.
commit ID: a529003c2f46188f63a201c707729ee701e922b3
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.