package ftp import ( "fmt" "git.loafle.net/commons_go/logging" cnsm "git.loafle.net/commons_go/network_service_matcher" ) // FTP Status codes, defined in RFC 959 const ( statusReadyServer = "120" statusOK = "200" statusNewConnectOK = "220" statusSystemNameOK = "215" statusCloseConnect = "221" statusUnkownCMD = "202" statusTlsUseOK = "234" statusCloseControlConnect = "421" statusSyntaxErr = "500" statusParamSyntaxErr = "501" statusNotUseCMD = "502" statusIncorrectCMD = "503" statusTlsNotUse = "534" statusNeedUserId = "332" ) type FTPMatcher struct { cnsm.Matchers isFtps bool } func (ftp *FTPMatcher) ServiceName() string { re := "" if ftp.isFtps { re = "FTPS" } else { re = "FTP" } return re } func (ftp *FTPMatcher) IsPrePacket() bool { return true } func (ftp *FTPMatcher) HasResponse(index int) bool { return true } func (ftp *FTPMatcher) IsError(info cnsm.MatchInfo, index int, packet *cnsm.Packet) bool { return false } func (ftp *FTPMatcher) Match(info cnsm.MatchInfo, index int, packet *cnsm.Packet) bool { result := false if packet == nil || packet.Buffer == nil || packet.Len == 0 { logging.Logger().Errorf("Discovery: FTP Matcher Packet nil") return result } str := string(packet.Buffer) //fmt.Println(str) code := str[:3] if index == 0 { switch code { case statusNewConnectOK, statusReadyServer: //fmt.Println(code) result = true break } } else if index == 1 { switch code { case statusSystemNameOK, statusSyntaxErr, statusParamSyntaxErr, statusNotUseCMD: //fmt.Println(code) result = true break } } else if index == 2 { switch code { case statusIncorrectCMD, statusParamSyntaxErr, statusNotUseCMD, statusNeedUserId: //fmt.Println(code) result = true break } } else if index == 3 { switch code { case statusCloseConnect, statusSyntaxErr: //fmt.Println(code) result = true break } } if index == 3 && result == true { var err error var isfs bool //fmt.Println(info.Port.Host.Ip, info.Port.Port) isfs, err = StartCheckFTPS(info) if isfs && err == nil { ftp.isFtps = isfs } else if err != nil { logging.Logger().Warnf("Discovery: FTP Matcher Check Error %v", err) } } return result } func NewMatcher() cnsm.Matcher { m := &FTPMatcher{} sysStr := "SYST\r\n" systByte := make([]byte, len(sysStr)) copy(systByte[:], sysStr) m.AddPacket(cnsm.NewPacket(systByte, len(sysStr))) passStr := "PASS \r\n" passByte := make([]byte, len(passStr)) copy(passByte[:], passStr) m.AddPacket(cnsm.NewPacket(passByte, len(passStr))) quitStr := "QUIT\r\n" quitByte := make([]byte, len(quitStr)) copy(quitByte[:], quitStr) m.AddPacket(cnsm.NewPacket(quitByte, len(quitStr))) return m }