109 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package ftp
 | |
| 
 | |
| import (
 | |
| 	"strings"
 | |
| 
 | |
| 	osm "git.loafle.net/overflow/service_matcher-go"
 | |
| )
 | |
| 
 | |
| // 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"
 | |
| 	statusNotLoggedIn         = "530"
 | |
| 	statusTlsNotUse           = "534"
 | |
| 	statusNeedUserId          = "332"
 | |
| )
 | |
| 
 | |
| type FTPMatcher struct {
 | |
| 	osm.Matchers
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) Key() string {
 | |
| 	return "FTP"
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) Type() string {
 | |
| 	return "NETWORK"
 | |
| }
 | |
| func (m *FTPMatcher) Vendor(matchCtx *osm.MatchCtx) string {
 | |
| 	return "UNKNOWN"
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) Version(matchCtx *osm.MatchCtx) string {
 | |
| 	return "UNKNOWN"
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) OsType(matchCtx *osm.MatchCtx) string {
 | |
| 	return "UNKNOWN"
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) OsVersion(matchCtx *osm.MatchCtx) string {
 | |
| 	return "UNKNOWN"
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) Name(matchCtx *osm.MatchCtx) string {
 | |
| 	return "FTP"
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) IsPrePacket() bool {
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) HasResponse(matchCtx *osm.MatchCtx, index int) bool {
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) IsError(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) bool {
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func (m *FTPMatcher) Match(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) error {
 | |
| 
 | |
| 	if packet == nil || !packet.Valid() {
 | |
| 		return osm.NoPacketReceivedError()
 | |
| 	}
 | |
| 
 | |
| 	str := strings.Split(string(packet.Bytes()), "\r\n")[0]
 | |
| 	if len(str) < 4 {
 | |
| 		return osm.NotMatchedError()
 | |
| 	}
 | |
| 	code := str[:3]
 | |
| 
 | |
| 	if index == 0 {
 | |
| 		switch code {
 | |
| 		case statusNewConnectOK, statusReadyServer:
 | |
| 			matchCtx.SetAttribute("comment", str[4:])
 | |
| 			return nil
 | |
| 		}
 | |
| 	} else if index == 1 {
 | |
| 		switch code {
 | |
| 		case statusCloseConnect, statusSyntaxErr:
 | |
| 			return nil
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return osm.NotMatchedError()
 | |
| }
 | |
| 
 | |
| func NewMatcher() osm.Matcher {
 | |
| 	m := &FTPMatcher{}
 | |
| 
 | |
| 	quitStr := "QUIT\r\n"
 | |
| 	quitByte := make([]byte, len(quitStr))
 | |
| 	copy(quitByte[:], quitStr)
 | |
| 	m.AddPacket(osm.NewPacket(quitByte, len(quitStr)))
 | |
| 
 | |
| 	return m
 | |
| }
 |