package protocol import ( "bytes" ) // The required prefix for the SSH protocol identification line. const ( ssh199Prefix = "SSH-1.99-" ssh20Prefix = "SSH-2.0-" ) func init() { Register(Both, "", detectSSH) } func detectSSH(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64) { // The data must be at least as long as the prefix itself. if len(data) < len(ssh20Prefix) { return nil, 0 } if dstPort == 22 || dstPort == 2200 || dstPort == 2222 { confidence = .1 } // The protocol allows for pre-banner text, so we have to check all lines. for _, line := range bytes.Split(data, []byte{'\n'}) { line = bytes.TrimSuffix(line, []byte{'\r'}) if bytes.HasPrefix(line, []byte(ssh20Prefix)) { return &Protocol{ Name: ProtocolSSH, Version: Version{ Major: 2, Minor: 0, Patch: -1, Extra: string(line[len(ssh20Prefix):]), }, }, confidence + 0.75 } if bytes.HasPrefix(line, []byte(ssh199Prefix)) { return &Protocol{ Name: ProtocolSSH, Version: Version{ Major: 1, Minor: 99, Patch: -1, Extra: string(line[len(ssh20Prefix):]), }, }, confidence + 0.75 } } return nil, 0 }