package asaModels import ( "regexp" "strconv" "strings" ) type ( SNMPConfig struct { SnmpServers []*SNMPServer `json:"snmp_servers"` Location string `json:"location"` Contact string `json:"contact"` Traps map[string][]string `json:"traps"` Enabled bool `json:"enabled"` ListenPort int `json:"listen_port"` SnmpGroups []*SNMPGroup `json:"snmp_groups"` SnmpUsers []*SNMPUser `json:"snmp_users"` } SNMPServer struct { IfName string `json:"interface"` IpAddress string `json:"ip_address"` Poll bool `json:"poll_only"` Trap bool `json:"trap_only"` Version string `json:"version"` UDPPort int `json:"udp_port"` Community string `json:"community"` User string `json:"user"` HostGroup bool `json:"host_group"` } SNMPGroup struct { Name string `json:"name"` Version string `json:"version"` Security string `json:"security"` } SNMPUser struct { Name string `json:"name"` Group string `json:"group"` Version string `json:"version"` Encrypted bool `json:"encrypted"` AuthType string `json:"auth_type"` AuthPassword string `json:"auth_hash"` PrivType string `json:"priv_type"` PrivPassword string `json:"priv_hash"` } ) var versionRE = regexp.MustCompile(`(?i)version (\d)`) var udpPortRE = regexp.MustCompile(`(?i)udp-port (\d+)`) var communityRE = regexp.MustCompile(`(?i)community (\S+)`) var pollRE = regexp.MustCompile(`(?i)(poll)`) var trapRE = regexp.MustCompile(`(?i)(trap)`) var v3UserRE = regexp.MustCompile(`(?i)version 3 (\S+)`) var hostGroupRE = regexp.MustCompile(`(?i)host-group`) func (server *SNMPServer) parse(s, zone, ip string) error { server.IfName = zone server.IpAddress = ip matchVer := versionRE.FindStringSubmatch(s) if len(matchVer) > 0 { server.Version = matchVer[1] } matchPort := udpPortRE.FindStringSubmatch(s) if len(matchPort) > 0 { i, err := strconv.Atoi(matchPort[1]) if err != nil { return err } server.UDPPort = i } matchCommunity := communityRE.FindStringSubmatch(s) if len(matchCommunity) > 0 { server.Community = matchCommunity[1] } matchUser := v3UserRE.FindStringSubmatch(s) if len(matchUser) == 2 { server.User = matchUser[1] } server.Poll = pollRE.MatchString(s) server.Trap = trapRE.MatchString(s) server.HostGroup = hostGroupRE.MatchString(s) return nil } /* #ASA sample 'sh run' lines #v2 host: snmp-server host outside 10.12.109.70 community ***** version 2c #v3 group: (priv can be auth/noauth/priv) snmp-server group ZENOSS v3 priv #v3 user: (1st ZEN is user, 2nd is group... encrypted optional, auth=md5 or sha, priv=3des,aes(128/192/256),des) snmp-server user ZENOSS ZENOSS v3 encrypted auth sha 62:0c:05:f2:32:17:5e:dc:2f:28:82:a0:c3:39:35:0f:bf:ea:e3:a0 priv aes 128 91:da:1a:6e:43:9e:01:9c:b9:e4:95:5c:f9:a3:f3:d6 #v3 host: snmp-server host outside 10.7.109.68 poll version 3 ZENOSS udp-port 162 */ var snmpServerHostRE = regexp.MustCompile(`^snmp-server host(?:-group)? (\S+) (\S+)`) var snmpTrapsLineRE = regexp.MustCompile(`^snmp-server enable traps (\S+) (.*)`) var snmpLocationRE = regexp.MustCompile(`snmp-server location (\S+)`) var snmpEnableRE = regexp.MustCompile(`^snmp-server enable`) var snmpListenRE = regexp.MustCompile(`^snmp-server listen-port (\d+)`) var snmpContactRE = regexp.MustCompile(`^snmp-server contact (.*)`) var snmpGroupRE = regexp.MustCompile(`^snmp-server group (\S+) v(\d+) (auth|noauth|priv)`) var snmpUserRE = regexp.MustCompile(`^snmp-server user (\S+) (\S+) v(\d+)`) var snmpUserEncryptedRE = regexp.MustCompile(`(?i)(encrypted)`) var snmpUserAuthRE = regexp.MustCompile(`auth (md5|sha) (\S+)`) var snmpUserPrivRE = regexp.MustCompile(`priv ((?:3?)des|aes \d+) (\S+)`) func (config *SNMPConfig) Parse(raw string) error { config.Traps = make(map[string][]string) splitLines := strings.Split(raw, "\n") for _, line := range splitLines { // Host line serverMatch := snmpServerHostRE.FindStringSubmatch(line) // Hosts require more-system-running output to see the community string. if len(serverMatch) > 0 { server := new(SNMPServer) if err := server.parse(line, serverMatch[1], serverMatch[2]); err != nil { return err } config.SnmpServers = append(config.SnmpServers, server) continue } // Enabled traps line trapsMatch := snmpTrapsLineRE.FindStringSubmatch(line) if len(trapsMatch) > 0 { split := strings.Split(trapsMatch[2], " ") config.Traps[trapsMatch[1]] = split continue } listenMatch := snmpListenRE.FindStringSubmatch(line) if len(listenMatch) > 0 { i, err := strconv.Atoi(listenMatch[1]) if err != nil { return err } config.ListenPort = i } locationMatch := snmpLocationRE.FindStringSubmatch(line) if len(locationMatch) > 0 { config.Location = locationMatch[1] continue } contactMatch := snmpContactRE.FindStringSubmatch(line) if len(contactMatch) > 0 { config.Contact = contactMatch[1] continue } if snmpEnableRE.MatchString(line) { config.Enabled = true continue } //v3 groups and users groupsMatch := snmpGroupRE.FindStringSubmatch(line) if len(groupsMatch) == 4 { group := new(SNMPGroup) group.Name = groupsMatch[1] group.Version = groupsMatch[2] group.Security = groupsMatch[3] config.SnmpGroups = append(config.SnmpGroups, group) continue } usersMatch := snmpUserRE.FindStringSubmatch(line) if len(usersMatch) == 4 { user := new(SNMPUser) user.Name = usersMatch[1] user.Group = usersMatch[2] user.Version = usersMatch[3] user.Encrypted = snmpUserEncryptedRE.MatchString(line) authMatch := snmpUserAuthRE.FindStringSubmatch(line) if len(authMatch) == 3 { user.AuthType = authMatch[1] user.AuthPassword = authMatch[2] } privMatch := snmpUserPrivRE.FindStringSubmatch(line) if len(privMatch) == 3 { user.PrivType = privMatch[1] user.PrivPassword = privMatch[2] } config.SnmpUsers = append(config.SnmpUsers, user) continue } } return nil }