├── .gitattributes ├── .gitignore ├── AccessGroup.py ├── AccessList.py ├── AccessListSubRule.py ├── CryptoMapObject.py ├── DeviceObject.py ├── IcmpObject.py ├── InterfaceObject.py ├── NetworkObject.py ├── ObjectGroup.py ├── ObjectNetwork.py ├── PortObject.py ├── ProtocolObject.py ├── README.md ├── ServiceObject.py ├── TunnelGroupObject.py ├── conf.ini ├── defFile.py └── main.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /AccessGroup.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Aug 18, 2013 3 | 4 | @author: mred 5 | ''' 6 | 7 | class AccessGroup: 8 | aclApplied = 'unknown' 9 | direction = 'unknown' 10 | interfaceAppliedTO = 'unknown' 11 | 12 | def __init__(self,line): 13 | ruleSplit = line.split() 14 | if ruleSplit[2] == 'global': 15 | self.aclApplied = ruleSplit[1] 16 | self.direction = 'unknown' 17 | self.interfaceAppliedTo = 'global' 18 | else: 19 | self.aclApplied = ruleSplit[1] 20 | self.direction = ruleSplit[2] 21 | self.interfaceAppliedTo = ruleSplit[4] -------------------------------------------------------------------------------- /AccessList.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 22, 2013 3 | 4 | @author: MrEd 5 | ''' 6 | from AccessListSubRule import * 7 | 8 | 9 | class AccessList: 10 | name = 'unknown' 11 | listOfRules = [] 12 | expandedRuleList = [] 13 | accessListSubRuleList = [] #has broken down objects 14 | 15 | def __init__(self,lineList): 16 | self.name = lineList[1] 17 | self.listOfRules = [] 18 | self.expandedRuleList = [] 19 | self.accessListSubRuleList = [] 20 | 21 | def printVar(self): 22 | print "ACL Name=",self.name," type=",self.type 23 | 24 | def printClean(self): 25 | print "PRINT CLEAN" 26 | 27 | def printBareBones(self): 28 | print "PRINT BAREBONES" 29 | -------------------------------------------------------------------------------- /AccessListSubRule.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 26, 2013 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class AccessListSubRule: 8 | protocol = 'unknown' #ip tcp udp icmp networkobject 9 | protocolIsOG = False 10 | protocolIsO = False 11 | fullLine = 'unknown' #Doesnt exsist 12 | accessListType = 'unknown' #extended remark standard 13 | typeOfAccess = 'unknown' #permit deny 14 | source = 'unknown' 15 | sourceIsOG = False 16 | sourceIsO = False 17 | source_operator = 'unknown' 18 | source_port = 'unknown' 19 | source_portIsOG = False 20 | source_portIsO = False 21 | dest = 'unknown' 22 | destIsOG = False 23 | destIsO = False 24 | dest_operator = 'unknown' 25 | dest_port= 'unknown' 26 | dest_portIsOG = False 27 | dest_portIsO = False 28 | icmp_type = 'unkown' 29 | accessListName = 'unknown' 30 | specialCaseType = 'unknown' 31 | protocol_expanded = [] 32 | source_ip_expanded = [] 33 | source_port_expanded = [] 34 | dest_ip_expanded = [] 35 | dest_port_expanded = [] 36 | 37 | 38 | 39 | def __init__(self,line): 40 | ruleSplit = line.split() 41 | indexLimit = len(ruleSplit) -1 42 | self.fullLine = line 43 | if (indexLimit > 0): 44 | self.accessListName = ruleSplit[1] 45 | if (indexLimit > 1): 46 | self.accessListType = ruleSplit[2] 47 | specialCase = False 48 | if self.accessListType == 'remark': 49 | specialCase = True 50 | specialCaseType = 'remark' 51 | if ruleSplit[-1] == 'inactive': 52 | specialCase = True 53 | specialCaseType = 'inactive' 54 | if ruleSplit[2] == 'standard': 55 | specialCase = True 56 | specialCaseType = 'standard' 57 | self.accessListType = 'standard' 58 | self.typeOfAccess = ruleSplit[3] 59 | protoCols = 0 60 | sourceCols = 0 61 | destCols = 0 62 | destPortCols = 0 63 | basePos = 3 64 | sourcePortCols = 0 65 | 66 | # START PROCESSING PROTOCOL SECTION 67 | if not specialCase: 68 | if (ruleSplit[4] == 'ip' or ruleSplit[4] == 'tcp' or ruleSplit[4] == 'udp' or ruleSplit[4] == 'icmp'): 69 | protoCols = 1 70 | elif (ruleSplit[4] == 'object-group'): 71 | protoCols = 2 72 | self.protocolIsOG = True 73 | elif (ruleSplit[4] == 'object'): 74 | protoCols = 2 75 | self.protocolIsO = True 76 | else: 77 | protoCols = 1 78 | 79 | self.protocol = ruleSplit[basePos+protoCols] 80 | 81 | # START PROCESSING SOURCE SECTION 82 | if (ruleSplit[basePos+protoCols+1] == 'any' or ruleSplit[basePos+protoCols+1] == 'any4'): 83 | sourceCols = 1 84 | self.source = ruleSplit[basePos+protoCols+1] 85 | elif (ruleSplit[basePos+protoCols+1] == 'host'): 86 | sourceCols = 2 87 | self.source = ruleSplit[basePos+protoCols+1+1] + " 255.255.255.255" 88 | elif (ruleSplit[basePos+protoCols+1] == 'object-group'): 89 | sourceCols = 2 90 | self.sourceIsOG = True 91 | self.source = ruleSplit[basePos+protoCols+1+1] 92 | elif (ruleSplit[basePos+protoCols+1] == 'object'): 93 | sourceCols = 2 94 | self.sourceIsO = True 95 | self.source = ruleSplit[basePos+protoCols+1+1] 96 | else: #Assuming it now a Network Based source, Be nice to have a check if its a network IP 97 | sourceCols = 2 98 | self.source = ruleSplit[basePos+protoCols+1] + " " + ruleSplit[basePos+protoCols+1+1] 99 | 100 | #Process Source Port section 'lt | gt | eq | neq | range port number or range 101 | modBasePos = basePos + protoCols + sourceCols 102 | if (indexLimit > modBasePos): 103 | if (ruleSplit[modBasePos+1] == 'lt' or ruleSplit[modBasePos+1] == 'gt' or ruleSplit[modBasePos+1] == 'eq' or ruleSplit[modBasePos+1] == 'neq'): 104 | sourcePortCols = 2 105 | self.source_operator = ruleSplit[modBasePos+1] 106 | self.source_port = ruleSplit[modBasePos+1+1] 107 | #Following 4 lines will NOT work. Left in to make sure I don't try to make it work. 108 | #elif (ruleSplit[modBasePos+1] == 'object-group'): 109 | # sourcePortCols = 2 110 | # self.source_portIsOG = True 111 | # self.source_port = ruleSplit[modBasePos+1+1] 112 | elif (ruleSplit[modBasePos+1] == 'range'): 113 | sourcePortCols = 3 114 | self.source_operator = ruleSplit[modBasePos+1] 115 | self.source_port = ruleSplit[modBasePos+1+1] + ruleSplit[modBasePos+1+1+1] 116 | #Not Good Here either. 117 | #else: #Assuming its a ICMP Type 118 | # sourcePortCols = 1 119 | # self.icmp_type = ruleSplit[modBasePos+1] 120 | # FILL ME IN! 121 | 122 | #START PROCESSING DEST SECTION - Should be exactly the same as source processing 123 | modBasePos = basePos + protoCols + sourceCols + sourcePortCols 124 | if (indexLimit > modBasePos): 125 | if (ruleSplit[modBasePos+1] == 'any' or ruleSplit[modBasePos+1] == 'any4' ): 126 | destCols = 1 127 | self.dest = ruleSplit[modBasePos+1] 128 | elif (ruleSplit[modBasePos+1] == 'host'): 129 | destCols = 2 130 | self.dest = ruleSplit[modBasePos+1+1] + " 255.255.255.255" 131 | elif (ruleSplit[modBasePos+1] == 'object-group'): 132 | destCols = 2 133 | self.destIsOG = True 134 | self.dest = ruleSplit[modBasePos+1+1] 135 | elif (ruleSplit[modBasePos+1] == 'object'): 136 | destCols = 2 137 | self.destIsO = True 138 | self.dest = ruleSplit[modBasePos+1+1] 139 | else: #Assuming it now a Network Based source, Be nice to have a check if its a network IP 140 | destCols = 2 141 | self.dest = ruleSplit[modBasePos+1] + " " + ruleSplit[modBasePos+1+1] 142 | 143 | #Process Dest Port Section 'lt | gt | eq | neq | range port number or range' 144 | modBasePos = basePos + protoCols + sourceCols + sourcePortCols + destCols 145 | if (indexLimit > modBasePos): 146 | if (ruleSplit[modBasePos+1] == 'lt' or ruleSplit[modBasePos+1] == 'gt' or ruleSplit[modBasePos+1] == 'eq' or ruleSplit[modBasePos+1] == 'neq'): 147 | destPortCols = 2 148 | self.dest_operator = ruleSplit[modBasePos+1] 149 | self.dest_port = ruleSplit[modBasePos+1+1] 150 | elif (ruleSplit[modBasePos+1] == 'object-group'): 151 | destPortCols = 2 152 | self.dest_portIsOG = True 153 | self.dest_port = ruleSplit[modBasePos+1+1] 154 | elif (ruleSplit[modBasePos+1] == 'range'): 155 | destPortCols = 3 156 | self.dest_operator = ruleSplit[modBasePos+1] 157 | self.dest_port = ruleSplit[modBasePos+1+1] + ruleSplit[modBasePos+1+1+1] 158 | else: #Assuming its a ICMP Type 159 | destPortCols = 1 160 | self.icmp_type = ruleSplit[modBasePos+1] 161 | 162 | 163 | if specialCase: 164 | if specialCaseType == 'standard': 165 | self.typeOfAccess = ruleSplit[3] 166 | if len(ruleSplit) == 6: 167 | self.source = ruleSplit[4] + " " + ruleSplit[5] 168 | if len(ruleSplit) == 5: 169 | self.source = ruleSplit[4] + " 255.255.255.255" 170 | donothing = 1 171 | #print specialCaseType 172 | 173 | 174 | def writeToDebugLog(self,outputFileDebugDump): 175 | outputFileDebugDump.write("accessListName ="+self.accessListName +" accessListType="+self.accessListType+" typeOfAccess="+self.typeOfAccess+" specialCaseType="+self.specialCaseType+"\n") 176 | outputFileDebugDump.write("protocol="+self.protocol+" protocolIsOG="+str(self.protocolIsOG)+" protocolIsO="+str(self.protocolIsO)+" icmp_type="+self.icmp_type+"\n") 177 | outputFileDebugDump.write("source="+self.source+" sourceIsOG="+str(self.sourceIsOG)+" sourceIsO="+str(self.sourceIsO)+" source_operator="+self.source_operator+" source_port="+self.source_port+" source_portIsOG="+str(self.source_portIsOG)+" source_portIsO"+str(self.source_portIsO)+"\n") 178 | outputFileDebugDump.write("dest="+self.dest+" destIsOG="+str(self.destIsOG)+" destIsO="+str(self.destIsO)+" dest_operator="+self.dest_operator+" dest_port="+self.dest_port+" dest_portIsOG="+str(self.dest_portIsOG)+" dest_portIsO"+str(self.dest_portIsO)+"\n") 179 | outputFileDebugDump.write("protocol_expanded=") 180 | outputFileDebugDump.writelines("%s " % x for x in self.protocol_expanded) 181 | outputFileDebugDump.write("\n") 182 | outputFileDebugDump.write("source_ip_expanded=") 183 | outputFileDebugDump.writelines("%s " % x for x in self.source_ip_expanded) 184 | outputFileDebugDump.write("\n") 185 | outputFileDebugDump.write("source_port_expanded=") 186 | outputFileDebugDump.writelines("%s " % x for x in self.source_port_expanded) 187 | outputFileDebugDump.write("\n") 188 | outputFileDebugDump.write("dest_ip_expanded=") 189 | outputFileDebugDump.writelines("%s " % x for x in self.dest_ip_expanded) 190 | outputFileDebugDump.write("\n") 191 | outputFileDebugDump.write("dest_port_expanded=") 192 | outputFileDebugDump.writelines("%s " % x for x in self.dest_port_expanded) 193 | outputFileDebugDump.write("\n") 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /CryptoMapObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Apr 6, 2014 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class CryptoMapObject: 8 | ''' 9 | classdocs 10 | ''' 11 | name = 'unknown' 12 | peer = 'unknown' 13 | matchAddressACL = 'unknown' 14 | priority = 0 15 | 16 | 17 | def __init__(self,line): 18 | lineSplit = line.split() 19 | self.name = lineSplit[2] 20 | 21 | 22 | def setPeer(self,peer): 23 | self.peer = peer 24 | 25 | def setMatchAddressACL(self,matchAddressACL): 26 | self.peer = matchAddressACL 27 | 28 | def setPriority(self,priority): 29 | self.priority = priority 30 | 31 | def printVar(self): 32 | print "name="+self.name+" peer="+str(self.peer)+" matchAddressACL="+str(self.matchAddressACL)+" priority="+str(self.priority) 33 | 34 | def writeToDebugLog(self,outputFileDebugDump): 35 | outputFileDebugDump.write("name="+self.name+" peer="+str(self.peer)+" matchAddressACL="+str(self.matchAddressACL)+" priority="+str(self.priority)+"\n") 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /DeviceObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on June 26, 2015 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class DeviceObject: 8 | hostname = 'unknown' 9 | ntpServers = [] 10 | model = 'unknown' 11 | 12 | def __init__(self,line): 13 | lineSplit = line.split() 14 | 15 | 16 | 17 | def addNTPServer(self,ntpServer): 18 | self.ntpServers.append(ntpServer) 19 | 20 | 21 | def writeToDebugLog(self,outputFileDebugDump): 22 | outputFileDebugDump.write("hostname="+self.hostname+"\n") 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /IcmpObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 8, 2013 3 | 4 | @author: murphyj 5 | ''' 6 | class IcmpObject: 7 | icmpType = 'unknown' 8 | fullLine = 'unknown' 9 | 10 | def __init__(self,lineList,line): 11 | self.fullLine = line 12 | self.icmpType = lineList[1] 13 | 14 | 15 | def printVar(self): 16 | print "ICMP Object ",self.icmpType 17 | 18 | def printClean(self): 19 | buildString = 'icmp-object' 20 | if self.icmpType != 'unknown': 21 | buildString = buildString + ' ' + self.icmpType 22 | print buildString 23 | 24 | def returnClean(self): 25 | buildString = '' 26 | if self.icmpType != 'unknown': 27 | buildString = buildString + ' ' + self.icmpType 28 | return buildString 29 | 30 | def writeToDebugLog(self,outputFileDebugDump): 31 | outputFileDebugDump.write("icmpType="+self.icmpType+"\n") -------------------------------------------------------------------------------- /InterfaceObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Nov 29, 2013 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class InterfaceObject: 8 | interface = 'unknown' 9 | accessVlan = 0 10 | voiceVlan = 0 11 | spanningtreePortfastEnabled = False 12 | switchportMode = 'unknown' 13 | 14 | def __init__(self,line): 15 | lineSplit = line.split() 16 | self.interface = lineSplit[1] 17 | 18 | 19 | 20 | def setAccessVlan(self,accessVlan): 21 | self.accessVlan = accessVlan 22 | 23 | def setVoiceVlan(self,voiceVlan): 24 | self.voiceVlan = voiceVlan 25 | 26 | def setSpanningtreePortfastEnabled(self,spanningtreePortfastEnabled): 27 | self.spanningtreePortfastEnabled = spanningtreePortfastEnabled 28 | 29 | def setSwitchportMode(self,switchportMode): 30 | self.switchportMode = switchportMode 31 | 32 | def parseLine(self,line): 33 | lineSplit = line.split() 34 | 35 | def printVar(self): 36 | print "interface="+self.interface+" accessVlan="+str(self.accessVlan)+" voiceVlan="+str(self.voiceVlan)+" spanningtreePortfastEnabled="+str(self.spanningtreePortfastEnabled)+" switchportMode="+self.switchportMode 37 | 38 | def writeToDebugLog(self,outputFileDebugDump): 39 | outputFileDebugDump.write("interface="+self.interface+" accessVlan="+str(self.accessVlan)+" voiceVlan="+str(self.voiceVlan)+" spanningtreePortfastEnabled="+str(self.spanningtreePortfastEnabled)+" switchportMode="+self.switchportMode+"\n") 40 | 41 | def printClean(self): 42 | print self.interface 43 | print self.accessVlan 44 | print self.voiceVlan 45 | print self.spanningtreePortfastEnabled 46 | print self.switchportMode 47 | 48 | def printBareBones(self): 49 | print self.interface 50 | 51 | def returnClean(self): 52 | return self.interface 53 | 54 | -------------------------------------------------------------------------------- /NetworkObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jun 29, 2013 3 | 4 | @author: MrEd 5 | 6 | 7 | ''' 8 | class NetworkObject: 9 | isHost = False 10 | isNetwork = False 11 | ipAddy = "0.0.0.0" 12 | subnet = "255.255.255.255" 13 | fullLine = 'unknown' 14 | name = 'unknown' 15 | natSourceInterface = 'unknown' 16 | natDestInterface = 'unknown' 17 | natType = 'unknown' 18 | natTranslation = 'unknown' 19 | natLineNum = 0 20 | 21 | def __init__(self,typeOfObject,lineList,line): 22 | ruleSplit = line.split() 23 | 24 | if ruleSplit[0] == 'network-object': 25 | self.parseLine(typeOfObject,lineList,line) 26 | elif ruleSplit[1] == 'network': 27 | self.name = ruleSplit[2] 28 | 29 | def parseLine(self,typeOfObject,lineList,line): 30 | self.typeOfObject = typeOfObject 31 | self.fullLine = line 32 | if typeOfObject == 'network host': 33 | self.isHost = True 34 | self.ipAddy = lineList[1] 35 | 36 | if typeOfObject == 'host': 37 | self.isHost = True 38 | self.ipAddy = lineList[2] 39 | if typeOfObject == 'network': 40 | self.isNetwork = True 41 | self.ipAddy = lineList[1] 42 | self.subnet = lineList[2] 43 | 44 | def setNatSourceInterface(self,var1): 45 | self.natSourceInterface = var1 46 | def setNatDestInterface(self,var1): 47 | self.natDestInterface = var1 48 | def setNatType(self,var1): 49 | self.natType = var1 50 | def setNatTranslation(self,var1): 51 | self.natTranslation = var1 52 | def setNatLineNum(self,var1): 53 | self.natLineNum = var1 54 | 55 | def printVar(self): 56 | print "isHost=",self.isHost ," isNetwork=",self.isNetwork," IP= ",self.ipAddy," Subnet=",self.subnet 57 | 58 | def writeToDebugLog(self,outputFileDebugDump): 59 | outputFileDebugDump.write("name="+self.name+" isHost="+str(self.isHost)+" isNetwork="+str(self.isNetwork)+" IP="+self.ipAddy+" Subnet="+self.subnet+"\n") 60 | outputFileDebugDump.write(" natType="+self.natType+" natSourceInt="+self.natSourceInterface+" natDestInt="+self.natDestInterface+" natTranslation="+self.natTranslation+"\n") 61 | def printClean(self): 62 | print self.ipAddy + " " + self.subnet 63 | 64 | def printBareBones(self): 65 | print self.ipAddy + " " + self.subnet 66 | 67 | def returnClean(self): 68 | return self.ipAddy + " " + self.subnet 69 | 70 | 71 | -------------------------------------------------------------------------------- /ObjectGroup.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 2, 2013 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class ObjectGroup: 8 | fullLine = 'unknown' 9 | listOfNetworkObjects = [] 10 | listOfServiceObjects = [] 11 | listOfObjectGroups = [] 12 | listOfIcmpObjects = [] 13 | listOfPortObjects = [] 14 | listOfProtocolObjects =[] 15 | description = 'unknown' 16 | typeOfObjectGroup = 'unknown' 17 | name = 'unknown' 18 | typeOfServiceGroup = 'unknown' 19 | 20 | def __init__(self,lineList,line): 21 | self.fullLine = line 22 | self.typeOfObjectGroup = lineList[1] 23 | self.name = lineList[2] 24 | self.listOfNetworkObjects = [] 25 | self.listOfServiceObjects = [] 26 | self.listOfObjectGroups = [] 27 | self.listOfIcmpObjects = [] 28 | self.listOfPortObjects = [] 29 | self.listOfProtocolObjects = [] 30 | self.description = 'unknown' 31 | self.typeOfServiceGroup = 'unknown' 32 | if lineList[1] == 'service' and len(lineList) == 4: 33 | self.typeOfServiceGroup = lineList[3] 34 | 35 | def printVar(self): 36 | if self.typeOfServiceGroup == 'service': 37 | print self.name + " " + self.typeOfServiceGroup 38 | else: 39 | print self.name + " " + self.description 40 | for x in self.listOfNetworkObjects: 41 | x.printClean() 42 | for x in self.listOfServiceObjects: 43 | x.printVar() 44 | for x in self.listOfIcmpObjects: 45 | x.printVar() 46 | for x in self.listOfPortObjects: 47 | x.printVar() 48 | for x in self.listOfProtocolObjects: 49 | x.printVar() 50 | for x in self.listOfObjectGroups: 51 | print x 52 | #for x in self.listOfObjectGroups: 53 | # x.printVar() 54 | 55 | def printClean(self): 56 | if self.typeOfServiceGroup == 'service': 57 | print self.name + " " + self.typeOfServiceGroup 58 | else: 59 | print self.name + " " + self.description 60 | for x in self.listOfNetworkObjects: 61 | x.printClean() 62 | for x in self.listOfServiceObjects: 63 | x.printClean() 64 | for x in self.listOfIcmpObjects: 65 | x.printClean() 66 | for x in self.listOfPortObjects: 67 | x.printClean() 68 | for x in self.listOfProtocolObjects: 69 | x.printClean() 70 | for x in self.listOfObjectGroups: 71 | print x 72 | 73 | def printDirectItemsOnly(self): 74 | for x in self.listOfNetworkObjects: 75 | x.printClean() 76 | for x in self.listOfServiceObjects: 77 | x.printClean() 78 | for x in self.listOfIcmpObjects: 79 | x.printClean() 80 | for x in self.listOfPortObjects: 81 | x.printClean() 82 | for x in self.listOfProtocolObjects: 83 | x.printClean() 84 | 85 | def returnClean(self): 86 | returnList = [] 87 | for x in self.listOfNetworkObjects: 88 | returnList.append(x.returnClean()) 89 | for x in self.listOfServiceObjects: 90 | returnList.append(x.returnClean()) 91 | for x in self.listOfIcmpObjects: 92 | returnList.append(x.returnClean()) 93 | for x in self.listOfPortObjects: 94 | returnList.append(x.returnClean()) 95 | for x in self.listOfProtocolObjects: 96 | returnList.append(x.returnClean()) 97 | return returnList 98 | 99 | def returnProtocolAttributes(self): 100 | returnList = [] 101 | for x in self.listOfServiceObjects: 102 | returnList.append(x.returnProtocolAttributes()) 103 | return returnList 104 | 105 | def returnDestPorts(self): 106 | returnList =[] 107 | for x in self.listOfServiceObjects: 108 | returnList.append(x.returnDestPorts()) 109 | return returnList 110 | 111 | 112 | def printListCounts(self): 113 | print self.name," NetworkObjects= ",len(self.listOfNetworkObjects), " ServiceObjects= ",len(self.listOfServiceObjects),\ 114 | " PortObjects= ",len(self.listOfPortObjects)," ICMP= ",len(self.listOfIcmpObjects)," Proto= ",len(self.listOfProtocolObjects) 115 | 116 | def writeToDebugLogDirectItemsOnly(self,outputFileDebugDump): 117 | if self.typeOfServiceGroup == 'service': 118 | outputFileDebugDump.write("name="+self.name+" typeOfServiceGroup="+self.typeOfServiceGroup+"\n") 119 | else: 120 | outputFileDebugDump.write("name= "+self.name+" description="+self.description+"\n") 121 | for x in self.listOfNetworkObjects: 122 | outputFileDebugDump.write(" ") 123 | x.writeToDebugLog(outputFileDebugDump) 124 | for x in self.listOfServiceObjects: 125 | outputFileDebugDump.write(" ") 126 | x.writeToDebugLog(outputFileDebugDump) 127 | for x in self.listOfIcmpObjects: 128 | outputFileDebugDump.write(" ") 129 | x.writeToDebugLog(outputFileDebugDump) 130 | for x in self.listOfPortObjects: 131 | outputFileDebugDump.write(" ") 132 | x.writeToDebugLog(outputFileDebugDump) 133 | for x in self.listOfProtocolObjects: 134 | outputFileDebugDump.write(" ") 135 | x.writeToDebugLog(outputFileDebugDump) 136 | for x in self.listOfObjectGroups: 137 | outputFileDebugDump.write(" ") 138 | outputFileDebugDump.write("nameOfGroup= "+ x + "\n") 139 | 140 | 141 | -------------------------------------------------------------------------------- /ObjectNetwork.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Aug 10, 2013 3 | 4 | @author: MrEd 5 | 6 | This is created from lines of "object network xxxxx" 7 | Not be confused with network-object objects. Later ASA versions started using "object network" 8 | ''' 9 | class ObjectNetwork: 10 | name = 'unknown' 11 | isHost = False 12 | isNetwork = False 13 | isServiceObject = False 14 | ipAddy = "0.0.0.0" 15 | subnet = "255.255.255.255" 16 | fullLine = 'unknown' 17 | natSourceInterface = 'unknown' 18 | natDestInterface = 'unknown' 19 | natType = 'unknown' 20 | natTranslation = 'unknown' 21 | natLineNum = 0 22 | 23 | def __init__(self,lineList,line): 24 | self.fullLine = line 25 | self.name = lineList[2] 26 | 27 | def setNatSourceInterface(self,var1): 28 | self.natSourceInterface = var1 29 | def setNatDestInterface(self,var1): 30 | self.natDestInterface = var1 31 | def setNatType(self,var1): 32 | self.natType = var1 33 | def setNatTranslation(self,var1): 34 | self.natTranslation = var1 35 | def setNatLineNum(self,var1): 36 | self.natLineNum = var1 37 | 38 | def printVar(self): 39 | if self.isHost or self.isNetwork: 40 | print "name",self.name,"isHost=",self.isHost ," isNetwork=",self.isNetwork," IP= ",self.ipAddy," Subnet=",self.subnet 41 | 42 | def printClean(self): 43 | print self.ipAddy + " " + self.subnet 44 | 45 | def printBareBones(self): 46 | print self.ipAddy + " " + self.subnet 47 | 48 | def returnClean(self): 49 | return self.ipAddy + " " + self.subnet -------------------------------------------------------------------------------- /PortObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 3, 2013 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class PortObject: 8 | operator = 'unknown' 9 | port = 'unknown' 10 | startRange = 'unknown' 11 | stopRange = 'unknown' 12 | fullLine = 'unknown' 13 | 14 | def __init__(self,lineList,line): 15 | self.fullLine = line 16 | self.operator = lineList[1] 17 | if self.operator == 'eq' or self.operator == 'gt' or self.operator=='lt' or self.operator=='neq': 18 | self.port = lineList[2] 19 | if self.operator == 'range': 20 | self.startRange = lineList[2] 21 | self.stopRange = lineList[3] 22 | 23 | def printVar(self): 24 | print "PortObject ",self.operator,self.port,self.startRange,self.stopRange 25 | 26 | def printClean(self): 27 | buildString = 'port-object' 28 | if self.operator != 'unknown': 29 | buildString = buildString + ' ' + self.operator 30 | if self.port != 'unknown': 31 | buildString = buildString + ' ' + self.port 32 | if self.startRange != 'unknown': 33 | buildString = buildString + ' ' + self.startRange 34 | if self.stopRange != 'unknown': 35 | buildString = buildString + ' ' + self.stopRange 36 | print buildString 37 | 38 | def returnClean(self): 39 | buildString = '' 40 | if self.operator != 'unknown': 41 | buildString = buildString + ' ' + self.operator 42 | if self.port != 'unknown': 43 | buildString = buildString + ' ' + self.port 44 | if self.startRange != 'unknown': 45 | buildString = buildString + ' ' + self.startRange 46 | if self.stopRange != 'unknown': 47 | buildString = buildString + ' ' + self.stopRange 48 | return buildString 49 | 50 | def writeToDebugLog(self,outputFileDebugDump): 51 | outputFileDebugDump.write("operator="+self.operator+" port="+self.port+" startRange="+self.startRange+" stopRange="+self.stopRange+"\n") 52 | -------------------------------------------------------------------------------- /ProtocolObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 6, 2013 3 | 4 | @author: MurphyJ 5 | ''' 6 | class ProtocolObject: 7 | protocol = 'unknown' 8 | fullLine = 'unknown' 9 | 10 | def __init__(self,lineList,line): 11 | self.fullLine = line 12 | self.protocol = lineList[1] 13 | 14 | 15 | def printVar(self): 16 | print "Protocol Object ",self.protocol 17 | 18 | def printClean(self): 19 | buildString = 'protocol-object' 20 | if self.protocol != 'unknown': 21 | buildString = buildString + ' ' + self.protocol 22 | print buildString 23 | 24 | def returnClean(self): 25 | buildString = '' 26 | if self.protocol != 'unknown': 27 | buildString = buildString + ' ' + self.protocol 28 | return buildString 29 | 30 | def writeToDebugLog(self,outputFileDebugDump): 31 | outputFileDebugDump.write("protocol="+self.protocol+"\n") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 4/14 the section of code for this function "def addressInNetwork(ip,net):" was taken from http://stackoverflow.com/questions/819355/how-can-i-check-if-an-ip-is-in-a-network-in-python by the handle named "Johnson". 3 | I have NOT fully tested it but it appeared to work enough for my current purpose. Long term is to use the netaddr module, but coudn't right now. 4 | 5 | 4/1 - for the localcompare option I forgot to compare the required network/service objects to be merged with the orginal list in the primary firewall. Sure they would merge naturally into a live running ASA BUT there is an issue if service group objects ends in a tcp/udp/tcp-dup or not. 6 | If this exists; 7 | object-group service TESTGROUP-TCP (You can add service-objects to this, NOT port-objects) 8 | And you try to add this; 9 | object-group service TESTGROUP-TCP tcp (You can add port-objects to this, NOT service-objects) 10 | This will happen;.. causing the following exit to exit the configuration mode 11 | TESTASA(config)# object-group service TESTGROUP tcp 12 | An object-group with the same id but different type (service) exists 13 | 14 | 3/18 - I'll be updating the section soon since its horriable and the code needs some explaining. 15 | 16 | CiscoConfigParser 17 | ================= 18 | 19 | To parse though Cisco IOS and ASA configs to pull information out and into a text file or DB. 20 | 21 | Very little exception catching :) 22 | 23 | WARNING-You MUST have values for all values in the confi.ini (even if they are gibberish)
24 | WARNING-The file needs to be Cisco formatted. Extra blank lines can be an issue. Some config backup programs add extra lines to the beginning or end of the file. Haven't gotten around to accounting for those issues.
25 | 26 | Required configuration file in same location as main.py = conf.ini 27 | ``` 28 | [Basic] 29 | #Mode Options - Just use "All" for now. Work in progress 30 | #All = Ask alot of questions 31 | #Local = All Local All the time 32 | Mode=All 33 | 34 | #Directory Locations require a trailing slash 35 | InstalledDir=C:\dev\Projects\CiscoConfigParser\ 36 | LogDir=C:\dev\Projects\CiscoConfigParser\logs\ 37 | TempDir=C:\dev\Projects\CiscoConfigParser\tempdir\ 38 | OutputDir=C:\dev\Projects\CiscoConfigParser\output\ 39 | 40 | [Database] 41 | DBuser=exampleuser 42 | DBpassword=examplepassword 43 | DBhost=examplehost 44 | DBschema=exampleschema 45 | 46 | [SVNconfig] 47 | SVNrealm=EXAMPLE.COM 48 | SVNrepo=https://svn.example.com/example/CVS/networking/configs/ 49 | SVNuser=examplesvnuser 50 | SVNpassword=examplesvnpassword 51 | ``` 52 | ``` 53 | 54 | ---------------------------------------------------------------------------------- 55 | Sample Run (Only input lines are shown below) 56 | python main.py 57 | do a debug dump? y/n :y 58 | Should I push data to SQL DB? y/n :n 59 | Where to get file from? local/remote/rancidlist/localcompare : localcompare 60 | Enter local filename one: gwefwc2.txt 61 | Enter local filename two: gwnfwc2.txt 62 | Enter Device Type[cisco_asa / cisco_switch: cisco_asa 63 | ACL Choices on Primary Config: outside-in inside-out netmgmt PCAP 64 | Enter Primary Config ACL to compare with: outside-in 65 | ACL Choices on Secondary Config: outside inside mgt PCAP 66 | Enter Secondary Config ACL to compare against Primary: outside 67 | Enter the value to append to conflict ace/objects: -MERGEDIN 68 | ------------------------------------------------------------------------------ 69 | 70 | Primary = The first file inputted and is the config you will be merging into. 71 | Secondary = The second file inputted and is the config you will be merging from. 72 | 73 | ACL_100_Match_List_Dump.txt 74 | A list of the ACEs that match (Content) between the 2 ACL's compared. 75 | ACL_Match_List.txt 76 | A list of ACEs in the secondary that have a matching (by content) ACE in the primary. 77 | ACL_NO_Match_List.txt 78 | List of ACEs in the secondary that have NO matching (by content) ACE in the primary. Minus the first line this is copy and pastable into a running config, granted the required objects already exist. 79 | ACLNoMatchListAppended.txt 80 | List of ACEs in the secondary that have NO matching (by content) ACE in the primary. There is also a value (Manually inputted during runtime) that is appended to the end of every Object Group used in the ACEs. This is copy and pastable into a running config, granted the required objects already exist. The intent is to avoid accidently merging or modifying objects in the primary that are named the same but are used for something else. 81 | debugDump.txt 82 | Print out of all the lists and objects created during the inital parsing of a configuration. if 'localcompare' option is used than this would be the primary firewall. 83 | output.txt (Fun fact: this was the orginal reason for this tool) 84 | Prints out a human readable columnar formatted break down of all the ACEs for all the ACLs in a config. It will expand out any object groups and nested object groups. 85 | output-LargeACLs.txt 86 | Prints out an expanded list of all the ACEs across all the ACLs. Useful if your porting to another cisco device that doesn't support object-groups. Most cisco routers/switches don't. 87 | output-LargeACLs-CopyPaste.txt 88 | Prints out an expanded list of all the ACEs across all the ACLs. But this time its in a format that you can copy and paste into a running config. 89 | ReqObjectGroupCopyPaste.txt 90 | Prints out all the Object Groups that are required from the secondary config to make all the ACEs listed in ACL_NO_Match_List.txt valid. This is copy and pastable into a running config. 91 | ReqObjectGroupNoExits.txt 92 | Same as above but without exit statements. NOT Copy and pastable into a running config. 93 | ReqObjectGroupCopyPasteAppended.txt 94 | Prints out all the Object Groups(with an appended value) that are required from the secondary config to make all the ACEs listed in ACLNoMatchListAppended.txt valid. This is copy and pastable into a running config. 95 | ReqObjectGroupNoExitsAppended.txt 96 | Same as above but without exit statements. NOT Copy and pastable into a running config. 97 | ReqObjectGroupCopyPasteAppendedDebug.txt 98 | Similar to ReqObjectGroupCopyPasteAppended.txt but with extra information and is NOT copy and pastable. 99 | ReqObjectGroupCopyPasteModified.txt 100 | ReqObjectGroupCopyPaste.txt minus ReqObjectsNameConflicts.txt. 101 | Prints out all the Object Groups that are required from the secondary config to make all the ACEs listed in ACL_NO_Match_List.txt valid BUT minus the object groups in the output ReqObjectsNameConflicts.txt. This is copy and pastable into a running config. There is potential for object group name conflicts when it involves service or port objects. Refer to "Name Conflict Issue" below. 102 | ReqObjectGroupNoExitsModified.txt 103 | Same as above but without exit statements. NOT Copy and pastable into a running config. 104 | ReqObjectGroupCopyPasteModifiedDebug.txt 105 | Similar to ReqObjectGroupCopyPasteModifiedDebug.txt but with additional information and is NOT copy and pastable. 106 | ReqObjectGroupDebug.txt 107 | Similar to ReqObjectGroupCopyPaste.txt but with additional information and is NOT copy and pastable. 108 | ReqObjectsExactFullLineMatch.txt 109 | Print out of all the Objects in the secondary config that have a match in the primary based on fullLine value. Minus the first line this is copy and pastable. 'fullLine' is a variable for many of the objects that contains the full line from the configuration. Created to help identify potential "Name Conflict Issues" (see below) and to eventually compare like named objects to see if the content is vastly different. You don't want to misuse an object that was named the same but was created for a different reason. 110 | ReqObjectsExactFullLineMatchNoExits.txt 111 | Same as above but without exit statements. NOT Copy and pastable into a running config. 112 | ReqObjectsExactFullLineMatchDebug.txt 113 | Similar to ReqObjectsExactFullLineMatch.txt but with additional information and is NOT copy and pastable. 114 | ReqObjectsNameConflicts.txt 115 | All Objects in the Secondary config that have a name conflict in the Primary based on fullLine value. Refer to "Name Conflict Issue" below. These are conflicts that must be resolved. if you attempted to paste these into a running config it would fail. 116 | ReqObjectsNameConflictsNoExits.txt 117 | Same as above but without exit statements. NOT Copy and pastable into a running config. 118 | ReqObjectsNameConflictsDebug.txt 119 | Similar to ReqObjectsNameConflicts.txt but with more information. 120 | SECOND-debugDump.txt 121 | Print out of all the lists and objects created during the initial parsing of a configuration. if 'localcompare' option is used than this would be the secondary firewall. 122 | SECOND-output.txt 123 | Prints out a human readable columnar formatted break down of all the ACEs for all the ACLs in a config. It will expand out any object groups and nested object groups. 124 | SECOND-output-LargeACLs.txt 125 | Prints out an expanded list of all the ACEs across all the ACLs. Useful if your porting to another cisco device that doesn't support object-groups. Most cisco routers/switches don't. 126 | SECOND-output-LargeACLs-CopyPaste.txt 127 | Prints out an expanded list of all the ACEs across all the ACLs. But this time its in a format that you can copy and paste into a running config. 128 | 129 | 130 | 131 | ------------------------------------------------------------ 132 | "Name Conflict Issue". Both object groups below are valid but only one type can exist on a firewall. 133 | object-group service NAME-OF-OBJECT 134 | Can contain 'service-object' objects. 135 | object-group service NAME-OF-OBJECT tcp 136 | Can contain 'port-object' objects. 137 | ASA01/act(config)# object-group service NAME-OF-OBJECT 138 | ASA01/act(config-service-object-group)# ? 139 | description Specify description text 140 | group-object Configure an object group as an object 141 | help Help for service object-group configuration commands 142 | no Remove an object or description from object-group 143 | service-object Configure a service object 144 | 145 | ASA01/act(config-service-object-group)# object-group service NAME-OF-OBJECT 146 | ASA01/act(config-service-object-group)# ? 147 | description Specify description text 148 | group-object Configure an object group as an object 149 | help Help for service object-group configuration commands 150 | no Remove an object or description from object-group 151 | port-object Configure a port object 152 | ------------------------------------------------------------ 153 | ``` 154 | -------------------------------------------------------------------------------- /ServiceObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jun 29, 2013 3 | 4 | @author: MrEd 5 | ''' 6 | class ServiceObject: 7 | protocol = 'unknown' 8 | operator = 'unknown' 9 | port = 'unknown' #NOT USED - marked for clean up 10 | dest_startRange = 'unknown' 11 | dest_stopRange = 'unknown' 12 | fullLine = 'unknown' 13 | icmpType = 'unknown' 14 | 15 | sourceIsOG = False 16 | source_operator = 'unknown' 17 | source_port = 'unknown' 18 | source_portIsOG = False 19 | source_startRange = 'unknown' 20 | source_stopRange = 'unknown' 21 | 22 | destIsOG = False 23 | dest_operator = 'unknown' 24 | dest_port= 'unknown' 25 | dest_portIsOG = False 26 | 27 | name = 'unknown' 28 | 29 | 30 | 31 | def __init__(self,line): 32 | ruleSplit = line.split() 33 | 34 | if ruleSplit[0] == 'service-object': 35 | self.parseLine(line) 36 | elif ruleSplit[1] == 'service': 37 | self.name = ruleSplit[2] 38 | elif ruleSplit[0] == 'protocol-object': 39 | self.protocol = ruleSplit[1] 40 | 41 | def parseLine(self,line): 42 | ruleSplit = line.split() 43 | self.protocol = ruleSplit[1] 44 | indexLimit = len(ruleSplit) -1 45 | self.fullLine = line 46 | 47 | specialCase = False 48 | 49 | protoCols = 0 50 | 51 | sourcePortCols = 0 52 | 53 | destPortCols = 0 54 | basePos = 0 55 | # START PROCESSING PROTOCOL SECTION 56 | if not specialCase: 57 | if (ruleSplit[basePos+1] == 'tcp-udp' or ruleSplit[basePos+1] == 'tcp' or ruleSplit[basePos+1] == 'udp'): 58 | protoCols = 1 59 | 60 | if (ruleSplit[basePos+1] == 'object-group'): 61 | self.protocol = 'OBJECTGROUP' 62 | protoCols = 2 63 | self.protocolIsOG = True 64 | 65 | 66 | # START PROCESSING SOURCE PORT SECTION 67 | #Only Process If after the proto section the next word is source 68 | modBasePos = basePos+protoCols+1 69 | if (indexLimit > modBasePos): 70 | 71 | if (ruleSplit[modBasePos] == 'source'): 72 | #print "STARTED SERVICE OBJECT SOURCE PORT SECTION" 73 | if (ruleSplit[modBasePos+1] == 'object-group'): 74 | sourcePortCols = 3 75 | self.sourceIsOG = True 76 | self.source = ruleSplit[modBasePos+2] 77 | elif (ruleSplit[modBasePos+1] == 'lt' or ruleSplit[modBasePos+1] == 'gt' or ruleSplit[modBasePos+1] == 'eq' or ruleSplit[modBasePos+1] == 'neq'): 78 | sourcePortCols = 3 79 | self.source_operator = ruleSplit[modBasePos+1] 80 | self.source_port = ruleSplit[modBasePos+1+1] 81 | elif (ruleSplit[modBasePos+1] == 'range'): 82 | sourcePortCols = 4 83 | self.source_operator = ruleSplit[modBasePos+1] 84 | self.source_startRange = ruleSplit[modBasePos+1+1] 85 | self.source_stopRange = ruleSplit[modBasePos+1+1+1] 86 | else: #Assuming its a ICMP Type 87 | sourcePortCols = 2 88 | self.icmp_type = ruleSplit[modBasePos+1] 89 | 90 | #Process Dest Port Section 'lt | gt | eq | neq | range port number or range' 91 | modBasePos = basePos + protoCols + sourcePortCols + 1 92 | if (indexLimit > modBasePos): 93 | if (ruleSplit[modBasePos] == 'destination' or 1 == 1): 94 | #print "STARTED SERVICE OBJECT DEST PORT SECTION" 95 | #Need to accoutn for Config lines that dont use "destination" in it 96 | if ruleSplit[modBasePos] != 'destination': 97 | modBasePos = modBasePos -1 98 | if (ruleSplit[modBasePos+1] == 'object-group'): 99 | destPortCols = 3 100 | self.destIsOG = True 101 | self.dest = ruleSplit[modBasePos+2] 102 | elif (ruleSplit[modBasePos+1] == 'lt' or ruleSplit[modBasePos+1] == 'gt' or ruleSplit[modBasePos+1] == 'eq' or ruleSplit[modBasePos+1] == 'neq'): 103 | destPortCols = 3 104 | self.dest_operator = ruleSplit[modBasePos+1] 105 | self.dest_port = ruleSplit[modBasePos+1+1] 106 | elif (ruleSplit[modBasePos+1] == 'range'): 107 | destPortCols = 4 108 | self.dest_operator = ruleSplit[modBasePos+1] 109 | self.dest_startRange = ruleSplit[modBasePos+1+1] 110 | self.dest_stopRange = ruleSplit[modBasePos+1+1+1] 111 | else: #Assuming its a ICMP Type 112 | destPortCols = 2 113 | self.icmp_type = ruleSplit[modBasePos+1] 114 | 115 | 116 | if specialCase: 117 | donothing = 1 118 | #print specialCaseType 119 | 120 | #WAS ORGINAL SECTION BUT HAD PROBELMS WITH NEW VERSION OF ASA CONFIGS 121 | #if self.protocol == 'tcp' or self.protocol == 'udp' or self.protocol == 'tcp-udp': 122 | # self.operator = lineList[2] 123 | # if self.operator == 'eq' or self.operator == 'gt' or self.operator=='lt' or self.operator=='neq': 124 | # self.port = lineList[3] 125 | # if self.operator == 'range': 126 | # self.startRange = lineList[3] 127 | # self.stopRange = lineList[4] 128 | 129 | 130 | if self.protocol == 'icmp' or self.protocol =='icmp6': 131 | if len(ruleSplit) > 2: 132 | self.icmpType = ruleSplit[2] 133 | 134 | def printVar(self): 135 | print "Name ", self.name 136 | print "Service Object ", self.protocol,self.icmpType,self.dest_operator,self.dest_port,self.dest_startRange,self.dest_stopRange 137 | 138 | def printClean(self): 139 | buildString = 'service-object' 140 | if self.protocol != 'unknown': 141 | buildString = buildString + ' ' + self.protocol 142 | if self.icmpType != 'unknown': 143 | buildString = buildString + ' ' + self.icmpType 144 | if self.operator != 'unknown': 145 | buildString = buildString + ' ' + self.dest_operator 146 | if self.dest_port != 'unknown': 147 | buildString = buildString + ' ' + self.dest_port 148 | if self.startRange != 'unknown': 149 | buildString = buildString + ' ' + self.dest_startRange 150 | if self.stopRange != 'unknown': 151 | buildString = buildString + ' ' + self.dest_stopRange 152 | print buildString 153 | 154 | def returnClean(self): 155 | buildString = '' 156 | if self.protocol != 'unknown': 157 | buildString = buildString + self.protocol 158 | if self.icmpType != 'unknown': 159 | buildString = buildString + ' ' + self.icmpType 160 | if self.operator != 'unknown': 161 | buildString = buildString + ' ' + self.dest_operator 162 | if self.dest_port != 'unknown': 163 | buildString = buildString + ' ' + self.dest_port 164 | if self.dest_startRange != 'unknown': 165 | buildString = buildString + ' ' + self.dest_startRange 166 | if self.dest_stopRange != 'unknown': 167 | buildString = buildString + ' ' + self.dest_stopRange 168 | return buildString 169 | 170 | def returnProtocolAttributes(self): 171 | buildString = '' 172 | if self.protocol != 'unknown': 173 | buildString = buildString + self.protocol 174 | return buildString 175 | 176 | def returnDestPorts(self): 177 | buildString = '' 178 | if self.operator != 'unknown': 179 | buildString = buildString + ' ' + self.dest_operator 180 | if self.dest_port != 'unknown': 181 | buildString = buildString + ' ' + self.dest_port 182 | if self.dest_startRange != 'unknown': 183 | buildString = buildString + ' ' + self.dest_startRange 184 | if self.dest_stopRange != 'unknown': 185 | buildString = buildString + ' ' + self.dest_stopRange 186 | return buildString 187 | 188 | 189 | 190 | def writeToDebugLog(self,outputFileDebugDump): 191 | outputFileDebugDump.write("name="+self.name+" protocol="+self.protocol+" operator="+self.operator+" icmpType="+self.icmpType+"\n") 192 | outputFileDebugDump.write("destIsOG="+str(self.destIsOG)+" dest_operator="+self.dest_operator+" dest_port="+self.dest_port+" dest_portIsOG="+str(self.dest_portIsOG)+" dest_startRange="+self.dest_startRange+" dest_stopRange="+self.dest_stopRange+"\n") 193 | outputFileDebugDump.write("sourceIsOG="+str(self.sourceIsOG)+" source_operator="+self.source_operator+" source_port="+self.source_port+" source_portIsOG="+str(self.source_portIsOG)+" source_startRange="+self.source_startRange+" source_stopRange="+self.source_stopRange+"\n") 194 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /TunnelGroupObject.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Apr 6, 2014 3 | 4 | @author: MrEd 5 | ''' 6 | 7 | class TunnelGroupObject: 8 | ''' 9 | classdocs 10 | ''' 11 | peer = 'unknown' 12 | type = 'unknown' 13 | groupPolicy = 'unknown' 14 | 15 | def __init__(self,line): 16 | lineSplit = line.split() 17 | self.peer = lineSplit[1] 18 | if lineSplit[2] == 'type': 19 | self.type = lineSplit[3] 20 | 21 | def setGroupPolicy(self,groupPolicy): 22 | self.groupPolicy = groupPolicy 23 | 24 | def printVar(self): 25 | print "peer="+self.peer+" type="+str(self.type)+" groupPolicy="+str(self.groupPolicy) 26 | 27 | def writeToDebugLog(self,outputFileDebugDump): 28 | outputFileDebugDump.write("peer="+self.peer+" type="+str(self.type)+" groupPolicy="+str(self.groupPolicy)+"\n") 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /conf.ini: -------------------------------------------------------------------------------- 1 | [Basic] 2 | Mode=All 3 | InstalledDir=./ 4 | LogDir=./ 5 | TempDir=./ 6 | OutputDir=./ 7 | 8 | [Database] 9 | DBuser=exampleuser 10 | DBpassword=examplepassword 11 | DBhost=examplehost 12 | DBschema=exampleschema 13 | 14 | [SVNconfig] 15 | SVNrealm=EXAMPLE.COM 16 | SVNrepo=https://svn.example.com/example/CVS/networking/configs/ 17 | SVNuser=examplesvnuser 18 | SVNpassword=examplesvnpassword 19 | 20 | 21 | -------------------------------------------------------------------------------- /defFile.py: -------------------------------------------------------------------------------- 1 | from NetworkObject import * 2 | from ServiceObject import * 3 | from PortObject import * 4 | from ProtocolObject import * 5 | from ObjectGroup import * 6 | from IcmpObject import * 7 | from AccessList import * 8 | from AccessGroup import * 9 | 10 | 11 | #This will return a list[] of a ACL line expanded to every combination. It can be rather large 12 | #list contains entries like: access-list outside_access_in extended permit tcp 192.168.101.0 255.255.255.0 10.150.130.144 255.255.255.255 eq https 13 | def ExpandRule(rule): 14 | global listOfObjectGroups, tempObjectGroupExpanded 15 | global listOfAccessLists 16 | tempExpandedRules = [] 17 | tempExpandedRulesContainsOG = [] 18 | tempExpandedRules2 = [] 19 | 20 | ruleSplit = rule.split() 21 | ruleName = ruleSplit[1] 22 | foundObjectGroup = False 23 | countUsedObjectGroups = 0 24 | objectGroupIndexLocation = 0 25 | for x in ruleSplit: 26 | if x == 'object-group': 27 | foundObjectGroup = True 28 | break 29 | objectGroupIndexLocation += 1 30 | if foundObjectGroup: 31 | objectGroupName = ruleSplit[objectGroupIndexLocation+1] 32 | tempObjectGroupExpanded = [] 33 | ExpandObjectGroup(objectGroupName) 34 | firstPart = '' 35 | for i in range(0,objectGroupIndexLocation): 36 | firstPart = firstPart + ruleSplit[i] + ' ' 37 | lastPart = '' 38 | for i in range(objectGroupIndexLocation+2,len(ruleSplit)): 39 | lastPart = lastPart + ruleSplit[i] + ' ' 40 | for x in tempObjectGroupExpanded: 41 | tempString = firstPart + x + " " + lastPart 42 | if 'object-group' in tempString: 43 | tempExpandedRulesContainsOG.append(tempString) 44 | else: 45 | tempExpandedRules.append(tempString) 46 | 47 | #Have some rules with OG's still most process them 48 | while (len(tempExpandedRulesContainsOG) > 0): 49 | ruleSplit = tempExpandedRulesContainsOG.pop(-1).split() 50 | objectGroupIndexLocation = 0 51 | for x in ruleSplit: 52 | if x == 'object-group': 53 | foundObjectGroup = True 54 | break 55 | objectGroupIndexLocation += 1 56 | if foundObjectGroup: 57 | objectGroupName = ruleSplit[objectGroupIndexLocation+1] 58 | tempObjectGroupExpanded = [] 59 | ExpandObjectGroup(objectGroupName) 60 | firstPart = '' 61 | for i in range(0,objectGroupIndexLocation): 62 | firstPart = firstPart + ruleSplit[i] + ' ' 63 | lastPart = '' 64 | for i in range(objectGroupIndexLocation+2,len(ruleSplit)): 65 | lastPart = lastPart + ruleSplit[i] + ' ' 66 | for x in tempObjectGroupExpanded: 67 | tempString = firstPart + x + " " + lastPart 68 | if 'object-group' in tempString: 69 | tempExpandedRulesContainsOG.append(tempString) 70 | else: 71 | tempExpandedRules.append(tempString) 72 | 73 | #Now Go through the tempExpandedRules array and swap out any "object" stuff. Could be multiples per line 74 | for x in tempExpandedRules: 75 | ruleSplit = x.split() 76 | objectIndexLocation = 0 77 | for x in ruleSplit: 78 | if x == 'object': 79 | foundObject = True 80 | break 81 | objectGroupIndexLocation += 1 82 | if foundObjectGroup: 83 | objectName = ruleSplit[objectIndexLocation+1] 84 | 85 | #Test Print 86 | #for x in tempExpandedRules: 87 | # print x 88 | return tempExpandedRules 89 | 90 | 91 | 92 | 93 | #print rule 94 | #print ruleSplit[objectGroupIndexLocation] 95 | 96 | 97 | 98 | 99 | 100 | def ExpandACL(rootACL): 101 | global listOfObjectGroups 102 | #For Each rule in the ACL we to start the expansion process 103 | 104 | 105 | def ExpandObjectGroup(name): 106 | global listOfObjectGroups 107 | global tempObjectGroupExpanded 108 | for x in listOfObjectGroups: 109 | if x.name == name: 110 | break 111 | #x.printDirectItemsOnly() 112 | tempObjectGroupExpanded = tempObjectGroupExpanded + x.returnClean() 113 | #objectGroupExpanded.append() 114 | for y in x.listOfObjectGroups: 115 | ExpandObjectGroup(y) 116 | 117 | 118 | 119 | 120 | def LineParser(commandName,lineList,line): 121 | global networkObjectCount, serviceObjectCount, portObjectCount,accessListCount, protocolObjectCount,currentOpenRootCommandLine,currentOpenSubCommandLine \ 122 | ,currentOpenSubSubCommandLine, objectGroupCount, currentOpenRootCommand, currentOpenSubCommand, currentOpenSubSubCommand, \ 123 | listOfHosts,listOfServiceObjects,listOfPortObjects,listOfProtocolObjects,listOfObjectGroups,listOfIcmpObjects,listOfAccessLists,icmpObjectCount, listOfObjects \ 124 | ,listOfAccessGroups, hostname 125 | 126 | 127 | objectExists = False 128 | 129 | 130 | #Handle Command access-group 131 | if commandName == 'access-group': 132 | tempAccessGroup = AccessGroup(line) 133 | listOfAccessGroups.append(tempAccessGroup) 134 | 135 | #Handle Command network-object 136 | if commandName == 'network-object': 137 | 138 | #print commandName +" "+ lineList[1] +" "+ lineList[2] 139 | if lineList[1] == 'host': 140 | #tempNetworkObject = NetworkObject(lineList[1]) 141 | #Check if a network-object host already exists 142 | for x in listOfHosts: 143 | if x.ipAddy == lineList[2]: 144 | objectExists = True 145 | if currentOpenRootCommand == 'object-group': 146 | #print "add to object-group ",listOfObjectGroups[-1].name 147 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject(lineList[1],lineList,line)) 148 | if objectExists == False: 149 | listOfHosts.append(NetworkObject(lineList[1],lineList,line)) 150 | networkObjectCount += 1 151 | if currentOpenRootCommand == 'object-group': 152 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject(lineList[1],lineList,line)) 153 | #listOfHosts.append(tempNetworkObject)) 154 | #else: 155 | # print "OBJECT EXISTS", lineList 156 | elif lineList[1] == 'object': 157 | #Find the network object and add it to the groups list 158 | for x in listOfHosts: 159 | if x.name == lineList[2]: 160 | if currentOpenRootCommand == 'object-group': 161 | listOfObjectGroups[-1].listOfNetworkObjects.append(x) 162 | #assumin a network and subnet for older ASA versions 163 | else: 164 | #Check if a network-object host already exists 165 | for x in listOfHosts: 166 | if x.ipAddy == lineList[1] and x.subnet == lineList[2]: 167 | objectExists = True 168 | if currentOpenRootCommand == 'object-group': 169 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject('network',lineList,line)) 170 | if objectExists == False: 171 | listOfHosts.append(NetworkObject('network',lineList,line)) 172 | networkObjectCount += 1 173 | if currentOpenRootCommand == 'object-group': 174 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject('network',lineList,line)) 175 | #listOfHosts.append(tempNetworkObject)) 176 | #else: 177 | # print "OBJECT EXISTS", lineList 178 | #IF this is part of a larger Object-Group we must add it to that 179 | elif commandName == 'object': 180 | if currentOpenRootCommand == 'object': 181 | for o in listOfHosts: 182 | if o.name == lineList[2]: 183 | objectExists = True 184 | if objectExists == False: 185 | if lineList[1] == 'network': 186 | listOfHosts.append(NetworkObject('placeholder',lineList,line)) 187 | networkObjectCount += 1 188 | if lineList[1] == 'service': 189 | listOfServiceObjects.append(ServiceObject(line)) 190 | serviceObjectCount += 1 191 | #Assumes this command is nested under the 'object' command 192 | #Highly correlated to service-objects 193 | elif commandName == 'service': 194 | if currentOpenRootCommand == 'object': 195 | listOfServiceObjects[-1].parseLine(line) 196 | 197 | 198 | #Assumes this command is nested under the 'object' command 199 | #Assumes format of "subnet x.x.x.x y.y.y.y' 200 | elif commandName == 'subnet': 201 | if currentOpenRootCommand == 'object': 202 | listOfHosts[-1].parseLine('network',lineList,line) 203 | 204 | 205 | #Assumes this command is nested under the 'object' command 206 | #Assumes format of "host x.x.x.x y.y.y.y' 207 | elif commandName == 'host': 208 | if currentOpenRootCommand == 'object': 209 | listOfHosts[-1].parseLine('network host',lineList,line) 210 | 211 | elif commandName == 'service-object': 212 | #the 2nd column is protocol which will affect the parsing 213 | #Check if a service-object host already exists 214 | #I don't think we really care if service-objects are doubles 215 | #for x in listOfServiceObjects: 216 | # if x.fullLine == line: 217 | # objectExists = True 218 | # #print "check ", x.fullLine, "TO ", line 219 | # #print "ServiceObject Exists " + line 220 | # else: 221 | # objectExists = False 222 | objectExists = False 223 | if lineList[1] == 'object': 224 | #Find the network object and add it to the groups list 225 | for x in listOfServiceObjects: 226 | if x.name == lineList[2]: 227 | objectExists = True 228 | if currentOpenRootCommand == 'object-group': 229 | listOfObjectGroups[-1].listOfServiceObjects.append(x) 230 | if currentOpenRootCommand == 'object-group': 231 | if objectExists == False: 232 | listOfServiceObjects.append(ServiceObject(line)) 233 | serviceObjectCount += 1 234 | listOfObjectGroups[-1].listOfServiceObjects.append(ServiceObject(line)) 235 | 236 | elif commandName == 'port-object': 237 | for x in listOfPortObjects: 238 | if x.fullLine ==line: 239 | objectExists = True 240 | else: 241 | objectExists = False 242 | if objectExists == False: 243 | listOfPortObjects.append(PortObject(lineList,line)) 244 | portObjectCount += 1 245 | if currentOpenRootCommand == 'object-group': 246 | listOfObjectGroups[-1].listOfPortObjects.append(PortObject(lineList,line)) 247 | 248 | 249 | elif commandName == 'protocol-object': 250 | for x in listOfProtocolObjects: 251 | if x.fullLine ==line: 252 | objectExists = True 253 | else: 254 | objectExists = False 255 | if objectExists == False: 256 | listOfProtocolObjects.append(ProtocolObject(lineList,line)) 257 | protocolObjectCount += 1 258 | if currentOpenRootCommand == 'object-group': 259 | listOfObjectGroups[-1].listOfProtocolObjects.append(ProtocolObject(lineList,line)) 260 | 261 | elif commandName == 'icmp-object': 262 | for x in listOfProtocolObjects: 263 | if x.fullLine ==line: 264 | objectExists = True 265 | 266 | else: 267 | objectExists = False 268 | if objectExists == False: 269 | listOfIcmpObjects.append(IcmpObject(lineList,line)) 270 | icmpObjectCount += 1 271 | if currentOpenRootCommand == 'object-group': 272 | listOfObjectGroups[-1].listOfIcmpObjects.append(IcmpObject(lineList,line)) 273 | 274 | 275 | elif commandName == 'object-group': 276 | objectGroupCount += 1 277 | listOfObjectGroups.append(ObjectGroup(lineList,line)) 278 | 279 | elif commandName == 'group-object': 280 | if currentOpenRootCommand == 'object-group': 281 | listOfObjectGroups[-1].listOfObjectGroups.append(lineList[1]) 282 | 283 | elif commandName == 'description': 284 | splitLineRemoveFirstWord = line.split(' ',2)[2] #might be a problem for commands with deeper whitespace 285 | if currentOpenRootCommand == 'object-group': 286 | listOfObjectGroups[-1].description = splitLineRemoveFirstWord 287 | 288 | elif commandName == 'access-list': 289 | accessListCount += 1 290 | skip = False 291 | if lineList[2] == 'remark': 292 | skip = True 293 | 294 | for x in listOfAccessLists: 295 | if lineList[1] == x.name: 296 | objectExists = True 297 | break 298 | else: 299 | objectExists = False 300 | if objectExists == False and not skip: 301 | listOfAccessLists.append(AccessList(lineList)) 302 | listOfAccessLists[-1].listOfRules.append(line) 303 | 304 | if objectExists == True and not skip: 305 | x.listOfRules.append(line) 306 | 307 | elif commandName == 'hostname': 308 | hostname = lineList[1] 309 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jun 29, 2013 3 | 4 | @author: MrEd 5 | 6 | 7 | ''' 8 | 9 | from ConfigParser import SafeConfigParser 10 | #import pysvn 11 | import getpass 12 | #import MySQLdb 13 | import re 14 | import csv 15 | from NetworkObject import * 16 | from ServiceObject import * 17 | from PortObject import * 18 | from ProtocolObject import * 19 | from ObjectGroup import * 20 | from IcmpObject import * 21 | from AccessList import * 22 | from AccessListSubRule import * 23 | from ObjectNetwork import * 24 | from AccessGroup import * 25 | from InterfaceObject import * 26 | from TunnelGroupObject import * 27 | from CryptoMapObject import * 28 | from DeviceObject import * 29 | from operator import pos 30 | from copy import deepcopy 31 | 32 | def ParseMe(inputFile, options): 33 | #This are the Commands for Cisco ASA Firewalls 34 | listOfCommands = ['hostname', 'name', 'interface', 'object-group', 'network-object', 'description', 'service-object', 'port-object', 'group-object', 'access-list', 'nat', 'static', \ 35 | 'access-group', 'crypto','domain-name','protocol-object','icmp-object', 'object', 'subnet', 'host', 'service','tunnel-group','default-group-policy','ntp'] 36 | listOfCiscoSwitchCommands = ['hostname', 'interface', 'switchport', 'spanning-tree', 'nat','ntp'] 37 | StartOfNewCommandObject = True 38 | linesIgnored = 0 39 | linesProcessed = 0 40 | linesTotal = 0 41 | networkObjectCount = 0 42 | serviceObjectCount = 0 43 | portObjectCount = 0 44 | objectGroupCount = 0 45 | protocolObjectCount = 0 46 | icmpObjectCount = 0 47 | accessListCount = 0 48 | objectExists = False 49 | currentWhiteSpaceLevel = 0 50 | previousLineWhiteSpace = 0 51 | currentOpenRootCommandLine = 'empty' 52 | currentOpenRootCommand = 'empty' 53 | currentOpenSubCommandLine = 'empty' 54 | currentOpenSubCommand = 'empty' 55 | currentOpenSubSubCommandLine = 'empty' 56 | currentOpenSubSubCommand = 'empty' 57 | 58 | 59 | listOfHosts = [] 60 | listOfServiceObjects = [] 61 | listOfPortObjects = [] 62 | listOfProtocolObjects = [] 63 | listOfObjectGroups = [] 64 | listOfIcmpObjects = [] 65 | listOfAccessLists = [] 66 | listOfObjects = [] 67 | tempObjectGroupExpanded = [] 68 | listOfAccessGroups = [] 69 | listOfInterfaces = [] 70 | listOfTunnelGroups = [] 71 | listOfCryptoMaps = [] 72 | hostname = [] 73 | deviceRepoName = 'unknown' 74 | deviceRepoRevisionNumber = 0 75 | doSQLStuff = False 76 | #inputFile = open('exampleConfig.cfg', 'r') 77 | #inputFile = open('ash.cfg', 'r') 78 | #outputFile = open('output.txt', 'w') 79 | #outputFileLargeACLs = open('output-LargeACLs.txt', 'w') #these are super expanded ACL lists 80 | #outputFileLargeACLsForCopyAndPaste = open('output-LargeACLs-CopyPaste.txt','w') 81 | #outputFileDebugDump = open('debugDump.txt','w') 82 | #outputFileLogging = open('LogFile.txt','w') 83 | 84 | 85 | #Use options Dict being passed in 86 | outputFile = open(options['outputFile'], 'w') 87 | outputFileLargeACLs = open(options['outputFileLargeACLs'], 'w') #these are super expanded ACL lists 88 | outputFileLargeACLsForCopyAndPaste = open(options['outputFileLargeACLsForCopyAndPaste'],'w') 89 | outputFileDebugDump = open(options['outputFileDebugDump'],'w') 90 | outputFileLogging = open(options['outputFileLogging'],'a') 91 | DBhost = options['DBhost'] 92 | DBschema = options['DBschema'] 93 | DBuser = options['DBuser'] 94 | DBpassword = options['DBpassword'] 95 | doDebugDump = options['doDebugDump'] 96 | doSQLStuff = options['doSQLStuff'] 97 | deviceConfig = options['deviceConfig'] 98 | deviceRepoRevisionNumber = options['deviceRepoRevisionNumber'] 99 | getFileFrom = options['getFileFrom'] 100 | deviceType = options['deviceType'] 101 | installedDir = options['installedDir'] 102 | 103 | #This will return a list[] of a ACL line expanded to every combination. It can be rather large 104 | #list contains entries like: access-list outside_access_in extended permit tcp 192.168.101.0 255.255.255.0 10.150.130.144 255.255.255.255 eq https 105 | def ExpandRule(rule,listOfObjectGroups,listOfAccessLists): 106 | global tempObjectGroupExpanded 107 | tempExpandedRules = [] 108 | tempExpandedRulesContainsOG = [] 109 | tempExpandedRules2 = [] 110 | 111 | ruleSplit = rule.split() 112 | ruleName = ruleSplit[1] 113 | foundObjectGroup = False 114 | countUsedObjectGroups = 0 115 | objectGroupIndexLocation = 0 116 | for x in ruleSplit: 117 | if x == 'object-group': 118 | foundObjectGroup = True 119 | break 120 | objectGroupIndexLocation += 1 121 | if foundObjectGroup: 122 | objectGroupName = ruleSplit[objectGroupIndexLocation+1] 123 | tempObjectGroupExpanded = [] 124 | tempObjectGroupExpanded = ExpandObjectGroup(objectGroupName,listOfObjectGroups) 125 | firstPart = '' 126 | for i in range(0,objectGroupIndexLocation): 127 | firstPart = firstPart + ruleSplit[i] + ' ' 128 | lastPart = '' 129 | for i in range(objectGroupIndexLocation+2,len(ruleSplit)): 130 | lastPart = lastPart + ruleSplit[i] + ' ' 131 | for x in tempObjectGroupExpanded: 132 | tempString = firstPart + x + " " + lastPart 133 | if 'object-group' in tempString: 134 | tempExpandedRulesContainsOG.append(tempString) 135 | else: 136 | tempExpandedRules.append(tempString) 137 | 138 | #Have some rules with OG's still most process them 139 | while (len(tempExpandedRulesContainsOG) > 0): 140 | ruleSplit = tempExpandedRulesContainsOG.pop(-1).split() 141 | objectGroupIndexLocation = 0 142 | for x in ruleSplit: 143 | if x == 'object-group': 144 | foundObjectGroup = True 145 | break 146 | objectGroupIndexLocation += 1 147 | if foundObjectGroup: 148 | objectGroupName = ruleSplit[objectGroupIndexLocation+1] 149 | tempObjectGroupExpanded = [] 150 | tempObjectGroupExpanded = ExpandObjectGroup(objectGroupName,listOfObjectGroups) 151 | firstPart = '' 152 | for i in range(0,objectGroupIndexLocation): 153 | firstPart = firstPart + ruleSplit[i] + ' ' 154 | lastPart = '' 155 | for i in range(objectGroupIndexLocation+2,len(ruleSplit)): 156 | lastPart = lastPart + ruleSplit[i] + ' ' 157 | for x in tempObjectGroupExpanded: 158 | tempString = firstPart + x + " " + lastPart 159 | if 'object-group' in tempString: 160 | tempExpandedRulesContainsOG.append(tempString) 161 | else: 162 | tempExpandedRules.append(tempString) 163 | 164 | #Now Go through the tempExpandedRules array and swap out any "object" stuff. Could be multiples per line 165 | for x in tempExpandedRules: 166 | ruleSplit = x.split() 167 | objectIndexLocation = 0 168 | for x in ruleSplit: 169 | if x == 'object': 170 | foundObject = True 171 | break 172 | objectGroupIndexLocation += 1 173 | return tempExpandedRules 174 | 175 | 176 | def ExpandObjectGroup(name,listOfObjectGroups): 177 | listOfObjectGroups 178 | global tempObjectGroupExpanded 179 | #tempObjectGroupExpanded = [] 180 | for x in listOfObjectGroups: 181 | if x.name == name: 182 | break 183 | #x.printDirectItemsOnly() 184 | tempObjectGroupExpanded = tempObjectGroupExpanded + x.returnClean() 185 | #objectGroupExpanded.append() 186 | for y in x.listOfObjectGroups: 187 | ExpandObjectGroup(y,listOfObjectGroups) 188 | return tempObjectGroupExpanded 189 | 190 | 191 | def ExpandObjectGroupForProtocolAttributes(name,listOfObjectGroups): 192 | global tempObjectGroupExpanded 193 | #tempObjectGroupExpanded = [] 194 | for x in listOfObjectGroups: 195 | if x.name == name: 196 | break 197 | tempObjectGroupExpanded = tempObjectGroupExpanded + x.returnProtocolAttributes() 198 | for y in x.listOfObjectGroups: 199 | ExpandObjectGroupForProtocolAttributes(y,listOfObjectGroups) 200 | return tempObjectGroupExpanded 201 | 202 | def ExpandObjectGroupForDestPorts(name,listOfObjectGroups): 203 | global tempObjectGroupExpanded 204 | #tempObjectGroupExpanded = [] 205 | for x in listOfObjectGroups: 206 | if x.name == name: 207 | break 208 | tempObjectGroupExpanded = tempObjectGroupExpanded + x.returnDestPorts() 209 | for y in x.listOfObjectGroups: 210 | ExpandObjectGroupForDestPorts(y,listOfObjectGroups) 211 | return tempObjectGroupExpanded 212 | 213 | def LineParser(commandName,lineList,line): 214 | networkObjectCount = 0 215 | serviceObjectCount = 0 216 | portObjectCount = 0 217 | accessListCount = 0 218 | protocolObjectCount = 0 219 | objectGroupCount = 0 220 | icmpObjectCount = 0 221 | interfaceObjectCount = 0 222 | 223 | currentOpenRootCommandLine 224 | currentOpenSubCommandLine 225 | currentOpenSubSubCommandLine 226 | currentOpenRootCommand 227 | currentOpenSubCommand 228 | currentOpenSubSubCommand 229 | listOfHosts 230 | listOfServiceObjects 231 | listOfPortObjects 232 | listOfProtocolObjects 233 | listOfObjectGroups 234 | listOfIcmpObjects 235 | listOfAccessLists 236 | listOfObjects 237 | listOfInterfaces 238 | listOfTunnelGroups 239 | listOfCryptoMaps 240 | objectExists = False 241 | 242 | 243 | #Handle Command access-group 244 | if commandName == 'access-group': 245 | tempAccessGroup = AccessGroup(line) 246 | listOfAccessGroups.append(tempAccessGroup) 247 | 248 | #Handle Command network-object 249 | if commandName == 'network-object': 250 | if lineList[1] == 'host': 251 | #Check if a network-object host already exists 252 | for x in listOfHosts: 253 | if x.ipAddy == lineList[2] and x.subnet == '255.255.255.255': 254 | objectExists = True 255 | if currentOpenRootCommand == 'object-group': 256 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject(lineList[1],lineList,line)) 257 | if objectExists == False: 258 | listOfHosts.append(NetworkObject(lineList[1],lineList,line)) 259 | networkObjectCount += 1 260 | if currentOpenRootCommand == 'object-group': 261 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject(lineList[1],lineList,line)) 262 | elif lineList[1] == 'object': 263 | #Find the network object and add it to the groups list 264 | for x in listOfHosts: 265 | if x.name == lineList[2]: 266 | if currentOpenRootCommand == 'object-group': 267 | listOfObjectGroups[-1].listOfNetworkObjects.append(x) 268 | #assuming a network and subnet for older ASA versions 269 | else: 270 | #Check if a network-object host already exists 271 | for x in listOfHosts: 272 | if x.ipAddy == lineList[1] and x.subnet == lineList[2]: 273 | objectExists = True 274 | if currentOpenRootCommand == 'object-group': 275 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject('network',lineList,line)) 276 | if objectExists == False: 277 | listOfHosts.append(NetworkObject('network',lineList,line)) 278 | networkObjectCount += 1 279 | if currentOpenRootCommand == 'object-group': 280 | listOfObjectGroups[-1].listOfNetworkObjects.append(NetworkObject('network',lineList,line)) 281 | #listOfHosts.append(tempNetworkObject)) 282 | #IF this is part of a larger Object-Group we must add it to that 283 | elif commandName == 'object': 284 | if currentOpenRootCommand == 'object': 285 | for o in listOfHosts: 286 | if o.name == lineList[2]: 287 | objectExists = True 288 | if objectExists == False: 289 | if lineList[1] == 'network': 290 | listOfHosts.append(NetworkObject('placeholder',lineList,line)) 291 | networkObjectCount += 1 292 | if lineList[1] == 'service': 293 | listOfServiceObjects.append(ServiceObject(line)) 294 | serviceObjectCount += 1 295 | #Assumes this command is nested under the 'object' command 296 | #Highly correlated to service-objects 297 | elif commandName == 'service': 298 | if currentOpenRootCommand == 'object': 299 | listOfServiceObjects[-1].parseLine(line) 300 | #Assumes this command is nested under the 'object' command 301 | #Assumes format of "subnet x.x.x.x y.y.y.y' 302 | elif commandName == 'subnet': 303 | if currentOpenRootCommand == 'object': 304 | listOfHosts[-1].parseLine('network',lineList,line) 305 | #Assumes this command is nested under the 'object' command 306 | #Assumes format of "host x.x.x.x y.y.y.y' 307 | elif commandName == 'host': 308 | if currentOpenRootCommand == 'object': 309 | listOfHosts[-1].parseLine('network host',lineList,line) 310 | elif commandName == 'service-object': 311 | #the 2nd column is protocol which will affect the parsing 312 | #Check if a service-object host already exists 313 | #I don't think we really care if service-objects are doubles 314 | objectExists = False 315 | if lineList[1] == 'object': 316 | #Find the network object and add it to the groups list 317 | for x in listOfServiceObjects: 318 | if x.name == lineList[2]: 319 | objectExists = True 320 | if currentOpenRootCommand == 'object-group': 321 | listOfObjectGroups[-1].listOfServiceObjects.append(x) 322 | if currentOpenRootCommand == 'object-group': 323 | if objectExists == False: 324 | listOfServiceObjects.append(ServiceObject(line)) 325 | serviceObjectCount += 1 326 | listOfObjectGroups[-1].listOfServiceObjects.append(ServiceObject(line)) 327 | 328 | elif commandName == 'port-object': 329 | for x in listOfPortObjects: 330 | if x.fullLine ==line: 331 | objectExists = True 332 | else: 333 | objectExists = False 334 | if objectExists == False: 335 | listOfPortObjects.append(PortObject(lineList,line)) 336 | portObjectCount += 1 337 | if currentOpenRootCommand == 'object-group': 338 | listOfObjectGroups[-1].listOfPortObjects.append(PortObject(lineList,line)) 339 | 340 | elif commandName == 'protocol-object': 341 | for x in listOfProtocolObjects: 342 | if x.fullLine ==line: 343 | objectExists = True 344 | else: 345 | objectExists = False 346 | if objectExists == False: 347 | listOfProtocolObjects.append(ProtocolObject(lineList,line)) 348 | protocolObjectCount += 1 349 | if currentOpenRootCommand == 'object-group': 350 | listOfObjectGroups[-1].listOfServiceObjects.append(ServiceObject(line)) 351 | 352 | elif commandName == 'icmp-object': 353 | for x in listOfProtocolObjects: 354 | if x.fullLine ==line: 355 | objectExists = True 356 | else: 357 | objectExists = False 358 | if objectExists == False: 359 | listOfIcmpObjects.append(IcmpObject(lineList,line)) 360 | icmpObjectCount += 1 361 | if currentOpenRootCommand == 'object-group': 362 | listOfObjectGroups[-1].listOfIcmpObjects.append(IcmpObject(lineList,line)) 363 | 364 | elif commandName == 'object-group': 365 | objectGroupCount += 1 366 | listOfObjectGroups.append(ObjectGroup(lineList,line)) 367 | 368 | elif commandName == 'group-object': 369 | if currentOpenRootCommand == 'object-group': 370 | listOfObjectGroups[-1].listOfObjectGroups.append(lineList[1]) 371 | 372 | elif commandName == 'description': 373 | splitLineRemoveFirstWord = line.split(' ',2)[2] #might be a problem for commands with deeper whitespace 374 | if currentOpenRootCommand == 'object-group': 375 | listOfObjectGroups[-1].description = splitLineRemoveFirstWord 376 | 377 | elif commandName == 'access-list': 378 | accessListCount += 1 379 | skip = False 380 | if lineList[2] == 'remark': 381 | skip = True 382 | 383 | for x in listOfAccessLists: 384 | if lineList[1] == x.name: 385 | objectExists = True 386 | break 387 | else: 388 | objectExists = False 389 | if objectExists == False and not skip: 390 | listOfAccessLists.append(AccessList(lineList)) 391 | listOfAccessLists[-1].listOfRules.append(line) 392 | 393 | if objectExists == True and not skip: 394 | x.listOfRules.append(line) 395 | 396 | elif commandName == 'hostname': 397 | hostname.append(lineList[1]) 398 | #Handle interface command 399 | elif commandName == 'interface': 400 | for x in listOfInterfaces: 401 | if x.interface == lineList[1]: 402 | objectExists = True 403 | else: 404 | objectExists = False 405 | if objectExists == False: 406 | listOfInterfaces.append(InterfaceObject(line)) 407 | interfaceObjectCount += 1 408 | #Handle switchport command. probably nested 409 | elif commandName == 'spanning-tree': 410 | if currentOpenRootCommand == 'interface': 411 | if lineList[1] == 'portfast': 412 | listOfInterfaces[-1].setSpanningtreePortfastEnabled(True) 413 | elif commandName == 'switchport': 414 | if currentOpenRootCommand == 'interface' and (len(lineList) > 1): 415 | if lineList[1] == 'mode': 416 | listOfInterfaces[-1].setSwitchportMode(lineList[2]) 417 | if lineList[1] == 'access': 418 | if lineList[2] == 'vlan': 419 | listOfInterfaces[-1].setAccessVlan(lineList[3]) 420 | if lineList[1] == 'voice': 421 | if lineList[2] == 'vlan': 422 | listOfInterfaces[-1].setVoiceVlan(lineList[3]) 423 | #Did not verify parsing with ASA docs, only with our configs 424 | elif commandName == 'tunnel-group': 425 | #Check if a tunnel-group object already exists with same peer ID 426 | for x in listOfTunnelGroups: 427 | if x.peer == lineList[1]: 428 | objectExists = True 429 | else: 430 | objectExists = False 431 | if objectExists == False: 432 | listOfTunnelGroups.append(TunnelGroupObject(line)) 433 | 434 | elif commandName == 'default-group-policy': 435 | holder = 1+1 436 | elif commandName == 'crypto': 437 | holder = 1+1 438 | elif commandName == 'nat': 439 | natSourceInterface ='not-set' 440 | natDestInterface = 'not-set' 441 | natType = 'not-set' 442 | natTranslation ='not-set' 443 | 444 | if currentOpenRootCommand == 'object': 445 | #break down the line. 446 | #Common sample nat (sourceInt,destInt) static TranslatedNat 447 | natType = lineList[2] 448 | natTranslation = lineList[3] 449 | natLineNum = linesTotal 450 | tempStrip = lineList[1].strip('()') 451 | #print tempStrip 452 | tempSplit = tempStrip.split(',') 453 | #print tempSplit[0] 454 | #print tempSplit[1] 455 | natSourceInterface = tempSplit[0] 456 | natDestInterface = tempSplit[1] 457 | #We need to find what networkobject to apply these nats to 458 | currentOpenRootCommandLineList = currentOpenRootCommandLine.split() 459 | findObjectNamed = currentOpenRootCommandLineList[2] 460 | pos = 0 461 | for o in listOfHosts: 462 | if o.name == findObjectNamed: 463 | listOfHosts[pos].setNatSourceInterface(natSourceInterface) 464 | listOfHosts[pos].setNatDestInterface(natDestInterface) 465 | listOfHosts[pos].setNatType(natType) 466 | listOfHosts[pos].setNatTranslation(natTranslation) 467 | listOfHosts[pos].setNatLineNum(natLineNum) 468 | else: 469 | pos += 1 470 | 471 | #This is for parsing static NATs in older ASA versions 472 | elif commandName == 'static': 473 | natSourceInterface ='not-set' 474 | natDestInterface = 'not-set' 475 | natType = 'not-set' 476 | natTranslation ='not-set' 477 | 478 | if currentOpenRootCommand == 'static': 479 | #break down the line. 480 | #Common sample static (dmz1,outside) 207.200.48.43 192.168.18.100 netmask 255.255.255.255 481 | natType = lineList[0] 482 | natTranslation = lineList[2] 483 | tempStrip = lineList[1].strip('()') 484 | #print tempStrip 485 | tempSplit = tempStrip.split(',') 486 | #print tempSplit[0] 487 | #print tempSplit[1] 488 | natSourceInterface = tempSplit[0] 489 | natDestInterface = tempSplit[1] 490 | #We need to find what networkobject to apply these nats to 491 | #This will be older ASA version so its most likely an IP, so lets look for that 492 | findObjectNamed = lineList[3] 493 | pos = 0 494 | for o in listOfHosts: 495 | if o.ipAddy == findObjectNamed: 496 | listOfHosts[pos].setNatSourceInterface(natSourceInterface) 497 | listOfHosts[pos].setNatDestInterface(natDestInterface) 498 | listOfHosts[pos].setNatType(natType) 499 | listOfHosts[pos].setNatTranslation(natTranslation) 500 | listOfHosts[pos].setNatLineNum(natLineNum) 501 | else: 502 | pos += 1 503 | elif commandName == 'ntp': 504 | #Temp ghetto job, dump to a file for ntp config lines 505 | outputNTPFile = open(installedDir+"NTPsettings", 'a') 506 | outputNTPFile.write(hostname[0]+" " + line) 507 | 508 | #Fun stuff below here. 509 | 510 | #Load Into SQL DB 511 | def SqlUploadInterfaces(interfaceObject,cur,hostname,listOfInterfaces): 512 | interface = interfaceObject.interface 513 | access_vlan = interfaceObject.accessVlan 514 | voice_vlan = interfaceObject.voiceVlan 515 | spanningtree_portfast_enabled = interfaceObject.spanningtreePortfastEnabled 516 | switchport_mode = interfaceObject.switchportMode 517 | with con: 518 | cur.execute("INSERT INTO interfaces (device_repo_name,revision_number,hostname,interface,access_vlan,voice_vlan,spanningtree_portfast_enabled,switchport_mode)\ 519 | values ('%s','%d','%s','%s','%s','%s','%d','%s')" % (deviceConfig,deviceRepoRevisionNumber,hostname,interface,access_vlan,voice_vlan,spanningtree_portfast_enabled,switchport_mode)) 520 | def SqlUploadAclSubrules(aclSubRule,cur,listOfHosts,listOfObjectGroups,hostname): 521 | global tempObjectGroupExpanded 522 | list1 = [] 523 | list2 = [] 524 | list3 = [] 525 | list4 = [] 526 | list5 = [] 527 | #PROTO 528 | #if aclSubRule.protocolIsOG == True: 529 | # #c1longest = len(aclSubRule.protocol) + len(' object-group') 530 | # tempObjectGroupExpanded = [] 531 | # tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.protocol,listOfObjectGroups) 532 | # list1 = tempObjectGroupExpanded 533 | if aclSubRule.protocolIsO == True: 534 | for x in listOfServiceObjects: 535 | if x.name == aclSubRule.protocol: 536 | break 537 | list1 = [x.protocol] 538 | tempStr = x.dest_operator 539 | if tempStr == 'range': 540 | tempStr = tempStr + " " + x.dest_startRange + " " + x.dest_stopRange 541 | else: 542 | tempStr = tempStr + " " + x.dest_port 543 | list5 = [tempStr] 544 | elif aclSubRule.protocolIsOG == True: 545 | tempObjectGroupExpanded = [] 546 | tempObjectGroupExpanded = ExpandObjectGroupForProtocolAttributes(aclSubRule.protocol,listOfObjectGroups) 547 | list1 = tempObjectGroupExpanded 548 | tempObjectGroupExpanded = [] 549 | tempObjectGroupExpanded = ExpandObjectGroupForDestPorts(aclSubRule.protocol,listOfObjectGroups) 550 | list5 = tempObjectGroupExpanded 551 | elif aclSubRule.protocol != 'unknown': 552 | list1 = [aclSubRule.protocol] 553 | #SOURCE 554 | if aclSubRule.sourceIsOG == True: 555 | #c2longest = len(aclSubRule.source) + len(' object-group') 556 | tempObjectGroupExpanded = [] 557 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.source,listOfObjectGroups) 558 | list2 = tempObjectGroupExpanded 559 | elif aclSubRule.sourceIsO == True: 560 | #look up the network object 561 | for o in listOfHosts: 562 | if o.name == aclSubRule.source: 563 | tempStr = o.ipAddy + " " + o.subnet 564 | list2 = [tempStr] 565 | else: 566 | if aclSubRule.source != 'unknown': 567 | list2 = [aclSubRule.source] 568 | #SOURCE PORTS 569 | if aclSubRule.source_portIsOG == True: 570 | tempObjectGroupExpanded = [] 571 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.source_port,listOfObjectGroups) 572 | list3 = tempObjectGroupExpanded 573 | else: 574 | if aclSubRule.source_port !='unknown': 575 | list3 = [aclSubRule.source_port] 576 | #DEST 577 | if aclSubRule.destIsOG == True: 578 | #c4longest = len(aclSubRule.dest) + len(' object-group') 579 | tempObjectGroupExpanded = [] 580 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.dest,listOfObjectGroups) 581 | list4 = tempObjectGroupExpanded 582 | elif aclSubRule.destIsO == True: 583 | #look up the network object 584 | for o in listOfHosts: 585 | if o.name == aclSubRule.dest: 586 | tempStr = o.ipAddy + " " + o.subnet 587 | list4 = [tempStr] 588 | else: 589 | if aclSubRule.dest != 'unknown': 590 | list4 = [aclSubRule.dest] 591 | #DEST PORTS 592 | if aclSubRule.dest_portIsOG == True: 593 | tempObjectGroupExpanded = [] 594 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.dest_port,listOfObjectGroups) 595 | list5 = tempObjectGroupExpanded 596 | else: 597 | if aclSubRule.dest_port != 'unknown': 598 | list5 = [aclSubRule.dest_port] 599 | 600 | #Create SQL queries to load list1 - list5 into the databse 601 | ex_list1 = '' 602 | n = len(list1) 603 | m = 0 604 | for a in list1: 605 | m += 1 606 | if m == n: 607 | ex_list1 = ex_list1 + a 608 | else: 609 | ex_list1 = ex_list1 + a + "," 610 | ex_list2 = '' 611 | n = len(list2) 612 | m = 0 613 | for a in list2: 614 | m += 1 615 | if m == n: 616 | ex_list2 = ex_list2 + a 617 | else: 618 | ex_list2 = ex_list2 + a + "," 619 | ex_list3 = '' 620 | n = len(list3) 621 | m = 0 622 | for a in list3: 623 | m += 1 624 | if m == n: 625 | ex_list3 = ex_list3 + a 626 | else: 627 | ex_list3 = ex_list3 + a + "," 628 | ex_list4 = '' 629 | n = len(list4) 630 | m = 0 631 | for a in list4: 632 | m += 1 633 | if m == n: 634 | ex_list4 = ex_list4 + a 635 | else: 636 | ex_list4 = ex_list4 + a + "," 637 | ex_list5 = '' 638 | n = len(list5) 639 | m = 0 640 | for a in list5: 641 | m += 1 642 | if m == n: 643 | ex_list5 = ex_list5 + a 644 | else: 645 | ex_list5 = ex_list5 + a + "," 646 | 647 | with con: 648 | #cur = con.curser() 649 | cur.execute("INSERT INTO access_list_subrules (device_repo_name,revision_number,hostname,access_list_name,full_line,access_list_type,type_of_access,protocol,source,source_operator,source_port,dest,dest_operator,dest_port,icmp_type,protocol_expanded_group\ 650 | ,source_expanded_group,dest_expanded_group,source_port_expanded_group,dest_port_expanded_group) values ('%s','%d','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')"\ 651 | % (deviceConfig,deviceRepoRevisionNumber,hostname,aclSubRule.accessListName,aclSubRule.fullLine,\ 652 | aclSubRule.accessListType,aclSubRule.typeOfAccess,aclSubRule.protocol,\ 653 | aclSubRule.source,aclSubRule.source_operator,aclSubRule.source_port,aclSubRule.dest,aclSubRule.dest_operator,aclSubRule.dest_port,aclSubRule.icmp_type,ex_list1,ex_list2,ex_list4,ex_list3,ex_list5)) 654 | 655 | def ExpandExtendedAclForHuman(aclSubRule,listOfHosts,listOfObjectGroups,listOfServiceObjects): 656 | global tempObjectGroupExpanded 657 | list1 = [] 658 | list2 = [] 659 | list3 = [] 660 | list4 = [] 661 | list5 = [] 662 | c1 = '' 663 | c2 = '' 664 | c3 = '' 665 | c4 = '' 666 | c5 = '' 667 | c1longest,c2longest,c3longest,c4longest,c5longest = 0,0,0,0,0 668 | if aclSubRule.protocol == 'unknown': 669 | c1longest = 0 670 | else: c1longest = 8 671 | if aclSubRule.source == 'unknown': 672 | c2longest = 0 673 | else: c2longest = 10 674 | if aclSubRule.source_port == 'unknown': 675 | c3longest = 0 676 | else: c3longest = 12 677 | if aclSubRule.dest == 'unknown': 678 | c4longest = 0 679 | else: c4longest = 15 680 | if aclSubRule.dest_port == 'unknown': 681 | c5longest = 0 682 | else: c5longest = 17 683 | outputFile.write(aclSubRule.fullLine) 684 | 685 | if aclSubRule.protocolIsO == True: 686 | for x in listOfServiceObjects: 687 | if x.name == aclSubRule.protocol: 688 | break 689 | list1 = [x.protocol] 690 | tempStr = x.dest_operator 691 | if tempStr == 'range': 692 | tempStr = tempStr + " " + x.dest_startRange + " " + x.dest_stopRange 693 | else: 694 | tempStr = tempStr + " " + x.dest_port 695 | list5 = [tempStr] 696 | elif aclSubRule.protocolIsOG == True: 697 | tempObjectGroupExpanded = [] 698 | tempObjectGroupExpanded = ExpandObjectGroupForProtocolAttributes(aclSubRule.protocol,listOfObjectGroups) 699 | list1 = tempObjectGroupExpanded 700 | tempObjectGroupExpanded = [] 701 | tempObjectGroupExpanded = ExpandObjectGroupForDestPorts(aclSubRule.protocol,listOfObjectGroups) 702 | list5 = tempObjectGroupExpanded 703 | elif aclSubRule.protocol != 'unknown': 704 | list1 = [aclSubRule.protocol] 705 | #SOURCE 706 | if aclSubRule.sourceIsOG == True: 707 | #c2longest = len(aclSubRule.source) + len(' object-group') 708 | tempObjectGroupExpanded = [] 709 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.source,listOfObjectGroups) 710 | list2 = tempObjectGroupExpanded 711 | elif aclSubRule.sourceIsO == True: 712 | #look up the network object 713 | for o in listOfHosts: 714 | if o.name == aclSubRule.source: 715 | tempStr = o.ipAddy + " " + o.subnet 716 | #print tempStr 717 | list2 = [tempStr] 718 | else: 719 | if aclSubRule.source != 'unknown': 720 | list2 = [aclSubRule.source] 721 | #c2longest = len(aclSubRule.source) + len(' 255.255.255.255') 722 | #SOURCE PORTS 723 | if aclSubRule.source_portIsOG == True: 724 | #c3longest = len(aclSubRule.source_port) + len(' object-group') 725 | tempObjectGroupExpanded = [] 726 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.source_port,listOfObjectGroups) 727 | list3 = tempObjectGroupExpanded 728 | else: 729 | if aclSubRule.source_port !='unknown': 730 | list3 = [aclSubRule.source_port] 731 | #DEST 732 | if aclSubRule.destIsOG == True: 733 | #c4longest = len(aclSubRule.dest) + len(' object-group') 734 | tempObjectGroupExpanded = [] 735 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.dest,listOfObjectGroups) 736 | list4 = tempObjectGroupExpanded 737 | elif aclSubRule.destIsO == True: 738 | #look up the network object 739 | for o in listOfHosts: 740 | if o.name == aclSubRule.dest: 741 | tempStr = o.ipAddy + " " + o.subnet 742 | list4 = [tempStr] 743 | else: 744 | if aclSubRule.dest != 'unknown': 745 | list4 = [aclSubRule.dest] 746 | #c4longest = len(aclSubRule.dest) + len(' 255.255.255.255') 747 | #DEST PORTS 748 | if aclSubRule.dest_portIsOG == True: 749 | #c5longest = len(aclSubRule.dest_port) + len(' object-group') 750 | tempObjectGroupExpanded = [] 751 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.dest_port,listOfObjectGroups) 752 | list5 = tempObjectGroupExpanded 753 | 754 | else: 755 | if aclSubRule.dest_port != 'unknown': 756 | list5 = [aclSubRule.dest_port] 757 | #Find the longest length in each column in the lists 758 | for n in list1: 759 | if len(n) > c1longest: 760 | c1longest = len(n) 761 | for n in list2: 762 | if len(n) > c2longest: 763 | c2longest = len(n) 764 | for n in list3: 765 | if len(n) > c3longest: 766 | c3longest = len(n) 767 | for n in list4: 768 | if len(n) > c4longest: 769 | c4longest = len(n) 770 | for n in list5: 771 | if len(n) > c5longest: 772 | c5longest = len(n) 773 | c1PadMe,c2PadMe,c3PadMe,c4PadMe,c5PadMe = 0,0,0,0,0 774 | #Find Longest List so we know max rows 775 | x = len(list1) 776 | if len(list2) > x: x = len(list2) 777 | if len(list3) > x: x = len(list3) 778 | if len(list4) > x: x = len(list4) 779 | if len(list5) > x: x = len(list5) 780 | 781 | #FIRST LINE ONLY 782 | s0 = 'access-list' 783 | s1 = aclSubRule.accessListName 784 | s2 = aclSubRule.accessListType 785 | s3 = aclSubRule.typeOfAccess 786 | sFirst = s0 + ' ' + s1 + ' ' + s2 + ' ' + s3 787 | sFirstPad = (' ' * len(sFirst)) 788 | #Add Column Names at the top, but only if they have values 789 | if aclSubRule.protocol == 'unknown': 790 | topCol1 = '' 791 | else: 792 | topCol1 = 'Protocol ' 793 | #if c1longest < 9: c1longest = 9 794 | c1PadMe = c1longest - 9 795 | if aclSubRule.source == 'unknown': 796 | topCol2 = '' 797 | else: 798 | topCol2 = 'Source-IPs ' 799 | #if c1longest < 11: c1longest = 11 800 | c2PadMe = c2longest - 11 801 | if aclSubRule.source_port == 'unknown': 802 | topCol3 = '' 803 | else: 804 | topCol3 = 'Source-Ports ' 805 | #if c1longest < 13: c1longest = 13 806 | c3PadMe = c3longest - 13 807 | if aclSubRule.dest == 'unknown': 808 | topCol4 = '' 809 | else: 810 | topCol4 = 'Destination-IPs ' 811 | #if c4longest < 16: c4longest = 16 812 | c4PadMe = c4longest - 16 813 | if aclSubRule.dest_port == 'unknown': 814 | topCol5 = '' 815 | else: 816 | topCol5 = 'Destination-Ports ' 817 | #if c1longest < 18: c1longest = 18 818 | c5PadMe = c5longest - 18 819 | topRowPad1 = (' ' * c1PadMe) 820 | topRowPad2 = (' ' * c2PadMe) 821 | topRowPad3 = (' ' * c3PadMe) 822 | topRowPad4 = (' ' * c4PadMe) 823 | topRowPad5 = (' ' * c5PadMe) 824 | c1,c2,c3,c4,c5 = '','','','','' 825 | fpad1,fpad2,fpad3,fpad4,fpad5 = '','','','','' 826 | if len(list1) > 0: 827 | c1 = list1.pop(0) 828 | fpad1 = ' ' 829 | c1PadMe = c1longest - len(c1) 830 | if len(list2) > 0: 831 | c2 = list2.pop(0) 832 | fpad2 = ' ' 833 | c2PadMe = c2longest - len(c2) 834 | if len(list3) > 0: 835 | c3 = list3.pop(0) 836 | fpad3 = ' ' 837 | c3PadMe = c3longest - len(c3) 838 | if len(list4) > 0: 839 | c4 = list4.pop(0) 840 | fpad4 = ' ' 841 | c4PadMe = c4longest - len(c4) 842 | if len(list5) > 0: 843 | c5 = list5.pop(0) 844 | fpad5 = ' ' 845 | c5PadMe = c5longest - len(c5) 846 | x = x - 1 847 | pad1 = (' ' * c1PadMe) 848 | pad2 = (' ' * c2PadMe) 849 | pad3 = (' ' * c3PadMe) 850 | pad4 = (' ' * c4PadMe) 851 | pad5 = (' ' * c5PadMe) 852 | pad0 = (' ' * len(sFirst)) 853 | string1 = pad0 +' '+c1+pad1+fpad2+c2+pad2+fpad3+c3+pad3+fpad4+c4+pad4+fpad5+c5+pad5+'\n' 854 | topRow = sFirst +' '+topCol1+topRowPad1+fpad2+topCol2+topRowPad2+fpad3+topCol3+topRowPad3+fpad4+topCol4+topRowPad4+fpad5+topCol5+'\n' 855 | outputFile.write(topRow) 856 | outputFile.write(string1) 857 | # THE REST OF LINES 858 | while x > 0: 859 | fpad1,fpad2,fpad3,fpad4,fpad5 = '','','','','' 860 | c1,c2,c3,c4,c5 = '','','','','' 861 | if len(list1) > 0: 862 | c1 = list1.pop(0) 863 | fpad2 = ' ' 864 | c1PadMe = c1longest - len(c1) 865 | else: 866 | if c1longest != 0: c1PadMe = c1longest +1 867 | if len(list2) > 0: 868 | c2 = list2.pop(0) 869 | fpad3 = ' ' 870 | c2PadMe = c2longest - len(c2) 871 | else: 872 | if c2longest != 0: c2PadMe = c2longest +1 873 | if len(list3) > 0: 874 | c3 = list3.pop(0) 875 | fpad4 = ' ' 876 | c3PadMe = c3longest - len(c3) 877 | else: 878 | if c3longest != 0: c3PadMe = c3longest +1 879 | if len(list4) > 0: 880 | c4 = list4.pop(0) 881 | fpad5 = ' ' 882 | c4PadMe = c4longest - len(c4) 883 | else: 884 | if c4longest != 0: c4PadMe = c4longest +1 885 | if len(list5) > 0: 886 | c5 = list5.pop(0) 887 | #fpad5 = ' ' 888 | c5PadMe = c5longest - len(c5) 889 | else: 890 | if c5longest != 0: c5PadMe = c5longest +1 891 | x = x - 1 892 | pad1 = (' ' * c1PadMe) 893 | pad2 = (' ' * c2PadMe) 894 | pad3 = (' ' * c3PadMe) 895 | pad4 = (' ' * c4PadMe) 896 | pad5 = (' ' * c5PadMe) 897 | string1 = sFirstPad+' '+c1+pad1+fpad2+c2+pad2+fpad3+c3+pad3+fpad4+c4+pad4+fpad5+c5+pad5+'\n' 898 | outputFile.write(string1) 899 | 900 | def ExpandExtendedAclForObject(aclSubRule,listOfHosts,listOfObjectGroups,listOfServiceObjects): 901 | global tempObjectGroupExpanded 902 | list1 = [] 903 | list2 = [] 904 | list3 = [] 905 | list4 = [] 906 | list5 = [] 907 | if aclSubRule.protocolIsO == True: 908 | for x in listOfServiceObjects: 909 | if x.name == aclSubRule.protocol: 910 | break 911 | list1 = [x.protocol] 912 | tempStr = x.dest_operator 913 | if tempStr == 'range': 914 | tempStr = tempStr + " " + x.dest_startRange + " " + x.dest_stopRange 915 | else: 916 | tempStr = tempStr + " " + x.dest_port 917 | list5 = [tempStr] 918 | elif aclSubRule.protocolIsOG == True: 919 | tempObjectGroupExpanded = [] 920 | tempObjectGroupExpanded = ExpandObjectGroupForProtocolAttributes(aclSubRule.protocol,listOfObjectGroups) 921 | list1 = tempObjectGroupExpanded 922 | tempObjectGroupExpanded = [] 923 | tempObjectGroupExpanded = ExpandObjectGroupForDestPorts(aclSubRule.protocol,listOfObjectGroups) 924 | list5 = tempObjectGroupExpanded 925 | elif aclSubRule.protocol != 'unknown': 926 | list1 = [aclSubRule.protocol] 927 | #SOURCE 928 | if aclSubRule.sourceIsOG == True: 929 | #c2longest = len(aclSubRule.source) + len(' object-group') 930 | tempObjectGroupExpanded = [] 931 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.source,listOfObjectGroups) 932 | list2 = tempObjectGroupExpanded 933 | elif aclSubRule.sourceIsO == True: 934 | #look up the network object 935 | for o in listOfHosts: 936 | if o.name == aclSubRule.source: 937 | tempStr = o.ipAddy + " " + o.subnet 938 | #print tempStr 939 | list2 = [tempStr] 940 | else: 941 | if aclSubRule.source != 'unknown': 942 | list2 = [aclSubRule.source] 943 | #c2longest = len(aclSubRule.source) + len(' 255.255.255.255') 944 | #SOURCE PORTS 945 | if aclSubRule.source_portIsOG == True: 946 | #c3longest = len(aclSubRule.source_port) + len(' object-group') 947 | tempObjectGroupExpanded = [] 948 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.source_port,listOfObjectGroups) 949 | list3 = tempObjectGroupExpanded 950 | else: 951 | if aclSubRule.source_port !='unknown': 952 | list3 = [aclSubRule.source_port] 953 | #DEST 954 | if aclSubRule.destIsOG == True: 955 | #c4longest = len(aclSubRule.dest) + len(' object-group') 956 | tempObjectGroupExpanded = [] 957 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.dest,listOfObjectGroups) 958 | list4 = tempObjectGroupExpanded 959 | elif aclSubRule.destIsO == True: 960 | #look up the network object 961 | for o in listOfHosts: 962 | if o.name == aclSubRule.dest: 963 | tempStr = o.ipAddy + " " + o.subnet 964 | list4 = [tempStr] 965 | else: 966 | if aclSubRule.dest != 'unknown': 967 | list4 = [aclSubRule.dest] 968 | #c4longest = len(aclSubRule.dest) + len(' 255.255.255.255') 969 | #DEST PORTS 970 | if aclSubRule.dest_portIsOG == True: 971 | #c5longest = len(aclSubRule.dest_port) + len(' object-group') 972 | tempObjectGroupExpanded = [] 973 | tempObjectGroupExpanded = ExpandObjectGroup(aclSubRule.dest_port,listOfObjectGroups) 974 | list5 = tempObjectGroupExpanded 975 | 976 | else: 977 | if aclSubRule.dest_port != 'unknown': 978 | list5 = [aclSubRule.dest_port] 979 | 980 | #Load lists 1-5 back into object 981 | aclSubRule.protocol_expanded = list1 982 | aclSubRule.source_ip_expanded = list2 983 | aclSubRule.source_port_expanded = list3 984 | aclSubRule.dest_ip_expanded = list4 985 | aclSubRule.dest_port_expanded = list5 986 | 987 | def PrintStandardAclForHuman(aclSubRule): 988 | outputFile.write(aclSubRule.fullLine) 989 | 990 | #Checks if an address is in a network, returns True or False 991 | def addressInNetwork(ip,net): 992 | ipaddr = struct.unpack('!L',socket.inet_aton(ip))[0] 993 | netaddr,bits = net.split('/') 994 | netaddr = struct.unpack('!L',socket.inet_aton(netaddr))[0] 995 | netmask = ((1<<(32-int(bits))) - 1)^0xffffffff 996 | return ipaddr & netmask == netaddr & netmask 997 | 998 | 999 | print "****************START PARSING CONFIG****************************" 1000 | #START PARSING THE inputFile 1001 | for line in inputFile: 1002 | linesProcessed += 1 1003 | linesTotal += 1 1004 | lineList = line.split() 1005 | #print line 1006 | #print currentOpenRootCommand 1007 | whiteSpace = len(line) - len(line.lstrip()) 1008 | #print whiteSpace 1009 | if line == '\n': 1010 | if doDebugDump: 1011 | outputFileDebugDump.write("BLANK LINE!\n Line# "+str(linesTotal)) 1012 | elif '::' in line: 1013 | if doDebugDump: 1014 | outputFileDebugDump.write("has '::', could be IPV6 related. Line# "+str(linesTotal)) 1015 | elif len(lineList) == 0: 1016 | if doDebugDump: 1017 | outputFileDebugDump.write("LineList array is zero: Line# "+str(linesTotal)) 1018 | elif line[0] != ' ': 1019 | currentWhiteSpaceLevel = 0 1020 | currentOpenRootCommandLine = line 1021 | currentOpenRootCommand = lineList[0] 1022 | #print "NO Whitespace - Start of new command CWL=",currentWhiteSpaceLevel," ",line 1023 | if lineList[0] in listOfCommands and deviceType == 'cisco_asa': 1024 | LineParser(lineList[0],lineList,line) 1025 | elif lineList[0] in listOfCiscoSwitchCommands and deviceType == 'cisco_switch': 1026 | LineParser(lineList[0],lineList,line) 1027 | else: 1028 | linesIgnored += 1 1029 | linesTotal += 1 1030 | elif whiteSpace > 0 and currentWhiteSpaceLevel == 0: 1031 | currentWhiteSpaceLevel += 1 1032 | currentOpenSubCommandLine = line 1033 | currentOpenSubCommandLine = lineList[0] 1034 | if lineList[0] in listOfCommands and deviceType == 'cisco_asa': 1035 | LineParser(lineList[0],lineList,line) 1036 | elif lineList[0] in listOfCiscoSwitchCommands and deviceType == 'cisco_switch': 1037 | LineParser(lineList[0],lineList,line) 1038 | else: 1039 | linesIgnored += 1 1040 | linesTotal += 1 1041 | 1042 | elif whiteSpace > 0 and whiteSpace == previousLineWhiteSpace: 1043 | currentWhiteSpaceLevel = currentWhiteSpaceLevel 1044 | currentOpenSubCommandLine = line 1045 | currentOpenSubCommandLine = lineList[0] 1046 | if lineList[0] in listOfCommands and deviceType == 'cisco_asa': 1047 | LineParser(lineList[0],lineList,line) 1048 | elif lineList[0] in listOfCiscoSwitchCommands and deviceType == 'cisco_switch': 1049 | LineParser(lineList[0],lineList,line) 1050 | else: 1051 | linesIgnored += 1 1052 | linesTotal += 1 1053 | 1054 | elif whiteSpace > 0 and whiteSpace > previousLineWhiteSpace: 1055 | currentWhiteSpaceLevel += 1 1056 | currentOpenSubSubCommandLine = line 1057 | currentOpenSubSubCommandLine = lineList[0] 1058 | if lineList[0] in listOfCommands and deviceType == 'cisco_asa': 1059 | LineParser(lineList[0],lineList,line) 1060 | elif lineList[0] in listOfCiscoSwitchCommands and deviceType == 'cisco_switch': 1061 | LineParser(lineList[0],lineList,line) 1062 | else: 1063 | linesIgnored += 1 1064 | linesTotal += 1 1065 | #outputFileDebugDump.write("4th if CURRENT WHITE SPACE LEVEL= ", str(currentWhiteSpaceLevel) + "\n") 1066 | previousLineWhiteSpace = whiteSpace 1067 | 1068 | #Break down each AccessList Rule into object based Sub Rules 1069 | for tempACL in listOfAccessLists: #Each ACL 1070 | for ruleInACL in tempACL.listOfRules: # each rule part of the ACL 1071 | #print ruleInACL 1072 | tempSubRuleObject = AccessListSubRule(ruleInACL) 1073 | tempACL.accessListSubRuleList.append(tempSubRuleObject) 1074 | #ABOVE here is required code for processing a config 1075 | 1076 | #Break down ACL's and add into the aclSubRule objects. Similar to the SQL load or pretty human printing 1077 | count = 0 1078 | #Break down the objects from listOfAccessLists and back to the same objects 1079 | for x in listOfAccessLists: 1080 | for y in x.accessListSubRuleList: 1081 | ExpandExtendedAclForObject(y,listOfHosts,listOfObjectGroups,listOfServiceObjects) 1082 | 1083 | #Start SQLDB LOADING STUFF 1084 | if doSQLStuff == True: 1085 | isAlreadyInDB = False 1086 | isLastestRevisionNumberFoundInDB = False 1087 | #isNewDevice = True 1088 | con = MySQLdb.connect(host=DBhost,user=DBuser,passwd=DBpassword,db=DBschema) 1089 | cur = con.cursor() 1090 | #Check what the last revision number parsed is 1091 | cur.execute("SELECT last_parsed_revision FROM parsed_revisions where device_repo_name=%s",(deviceConfig)) 1092 | numberRows = int(cur.rowcount) 1093 | if numberRows > 0: 1094 | isAlreadyInDB = True 1095 | lastestRevisionNumberFoundInDB = 0 1096 | for i in range(numberRows): 1097 | row=cur.fetchone() 1098 | if row[0] > lastestRevisionNumberFoundInDB: 1099 | lastestRevisionNumberFoundInDB = row[0] 1100 | print "latest revision in DB is " + str(lastestRevisionNumberFoundInDB) #A long value 1101 | print "Device Repo revision number is " + str(deviceRepoRevisionNumber) #an int value 1102 | outputFileLogging.write(deviceConfig +": Latest revision number found in Database is " + str(lastestRevisionNumberFoundInDB) + "\n") 1103 | outputFileLogging.write(deviceConfig +": Revision number for parsed config is " + str(deviceRepoRevisionNumber) + "\n") 1104 | #If this is a local file we want to force a higher new revision number so it updates the DB 1105 | if getFileFrom == 'local': 1106 | deviceRepoRevisionNumber = lastestRevisionNumberFoundInDB + 1 1107 | outputFileLogging.write(deviceConfig +": Local file load : force revision increment to " + str(deviceRepoRevisionNumber) + "\n") 1108 | if (lastestRevisionNumberFoundInDB == deviceRepoRevisionNumber): 1109 | print "Latest revision number found in DB is equal to the device repo version: No Upload to DB" 1110 | outputFileLogging.write(deviceConfig +": Latest revision is in the DB : No Upload to DB \n") 1111 | isLastestRevisionNumberFoundInDB = True 1112 | else: 1113 | print "Latest revision is not found in the DB : proceed with DB update" 1114 | outputFileLogging.write(deviceConfig +": Latest revision is not found in the DB : proceed with DB update \n") 1115 | 1116 | #Load stuff in the Database 1117 | count = 0 1118 | countInterfaces = 0 1119 | if (isLastestRevisionNumberFoundInDB == False or isAlreadyInDB == False): 1120 | #Load the objects from listOfAccessLists into the DB 1121 | for x in listOfAccessLists: 1122 | for y in x.accessListSubRuleList: 1123 | SqlUploadAclSubrules(y,cur,listOfHosts,listOfObjectGroups,hostname[0]) 1124 | count = count + 1 1125 | print str(count) + " ACLs SQL UPLOADED" 1126 | outputFileLogging.write(deviceConfig + ": " + str(count) + " ACLs SQL UPLOADED\n") 1127 | #Load the objects from the listOfInterfaces 1128 | for x in listOfInterfaces: 1129 | SqlUploadInterfaces(x,cur,hostname[0],listOfInterfaces) 1130 | countInterfaces = countInterfaces + 1 1131 | print str(countInterfaces) + " Interfaces SQL UPLOADED" 1132 | outputFileLogging.write(deviceConfig + ": " + str(countInterfaces) + " Interfaces SQL UPLOADED\n") 1133 | 1134 | 1135 | if isAlreadyInDB: 1136 | print "The Device is already in DB, updating the revision numbers to " + str(deviceRepoRevisionNumber) 1137 | #cur.execute("UPDATE parsed_revisions SET last_parsed_revision=44 WHERE device_repo_name='10.45.6.10' " ) 1138 | cur.execute("UPDATE parsed_revisions SET last_parsed_revision=%s WHERE device_repo_name='%s' " % (deviceRepoRevisionNumber,deviceConfig)) 1139 | print cur.rowcount 1140 | con.commit() 1141 | else: 1142 | print "Device Not found in DB - Adding it" 1143 | cur.execute("INSERT INTO parsed_revisions (device_repo_name,last_parsed_revision) values ('%s','%d')" % (deviceConfig,deviceRepoRevisionNumber)) 1144 | con.commit() 1145 | if count > 0: 1146 | print "Clean Up DB for old revisions" 1147 | #print deviceConfig 1148 | with con: 1149 | cur.execute("DELETE FROM "+DBschema+".access_list_subrules where device_repo_name = %s AND revision_number < %s",(deviceConfig,deviceRepoRevisionNumber)) 1150 | outputFileLogging.write(deviceConfig + ": " + str(cur.rowcount)+" Rows Deleted From ACL Table\n") 1151 | print "Deleted " + str(cur.rowcount) + " Rows From ACL Table" 1152 | with con: 1153 | cur.execute("DELETE FROM "+DBschema+".interfaces where device_repo_name = %s AND revision_number < %s",(deviceConfig,deviceRepoRevisionNumber)) 1154 | outputFileLogging.write(deviceConfig + ": " + str(cur.rowcount)+" Rows Deleted From Interfaces Table\n") 1155 | print "Deleted " + str(cur.rowcount) + " Rows From Interfaces Table" 1156 | 1157 | if doDebugDump == True: 1158 | outputFileDebugDump.write('STARTING DEBUG DUMP') 1159 | 1160 | #Test Dumping Access Groups 1161 | outputFile.write('******ACL Applied to each Interface******\n') 1162 | for x in listOfAccessGroups: 1163 | outputFile.write('Interface: '+x.interfaceAppliedTo+' '+x.direction+' ACL: '+x.aclApplied+'\n') 1164 | 1165 | #Test for dumping all ACL sub rules for human readable 1166 | for x in listOfAccessLists: 1167 | outputFile.write('*********************START OF ACL************************\n') 1168 | #Check if this AccessList is applied to an interface 1169 | for z in listOfAccessGroups: 1170 | if z.aclApplied == x.name: 1171 | outputFile.write('*********************Applied to interface: '+z.interfaceAppliedTo+' '+z.direction+'*********************\n') 1172 | for y in x.accessListSubRuleList: 1173 | if y.accessListType == 'extended': 1174 | ExpandExtendedAclForHuman(y,listOfHosts,listOfObjectGroups,listOfServiceObjects) 1175 | outputFile.write ("\n") 1176 | #outputFile.write('**********************END OF ACL*************************\n') 1177 | elif y.accessListType == 'standard': 1178 | #outputFile.write('*********************START OF ACL************************\n') 1179 | PrintStandardAclForHuman(y) 1180 | outputFile.write('**********************END OF ACL*************************\n') 1181 | 1182 | #Print all network objects 1183 | outputFileDebugDump.write("=================------------------DUMP listOfHosts[]--------------===================\n") 1184 | for x in listOfHosts: 1185 | outputFileDebugDump.write("******************\n") 1186 | outputFileDebugDump.write(x.fullLine) 1187 | x.writeToDebugLog(outputFileDebugDump) 1188 | outputFileDebugDump.write("=================------------------DUMP listOfServiceObjects[]--------------===================\n") 1189 | #Print all service objects 1190 | for x in listOfServiceObjects: 1191 | outputFileDebugDump.write("******************\n") 1192 | outputFileDebugDump.write(x.fullLine) 1193 | x.writeToDebugLog(outputFileDebugDump) 1194 | #Print all accessListSubRules - These are each ACE in a ACL broken down into an object 1195 | outputFileDebugDump.write("=================------------------DUMP listOfAccessLists[] and each accessListSubRuleList[]--------------===================\n") 1196 | for x in listOfAccessLists: 1197 | for y in x.accessListSubRuleList: 1198 | outputFileDebugDump.write("******************\n") 1199 | outputFileDebugDump.write(y.fullLine) 1200 | y.writeToDebugLog(outputFileDebugDump) 1201 | #Print all Prototcol objects in the listOfProtocolObjects[] 1202 | outputFileDebugDump.write("=================------------------DUMP listOfPortObjects[]--------------===================\n") 1203 | for x in listOfPortObjects: 1204 | outputFileDebugDump.write("******************\n") 1205 | outputFileDebugDump.write(x.fullLine) 1206 | x.writeToDebugLog(outputFileDebugDump) 1207 | #Print all Prototcol objects in the listOfProtocolObjects[] 1208 | outputFileDebugDump.write("=================------------------DUMP listOfIcmpObjects[]--------------===================\n") 1209 | for x in listOfIcmpObjects: 1210 | outputFileDebugDump.write("******************\n") 1211 | outputFileDebugDump.write(x.fullLine) 1212 | x.writeToDebugLog(outputFileDebugDump) 1213 | #Print all Prototcol objects in the listOfProtocolObjects[] 1214 | outputFileDebugDump.write("=================------------------DUMP listOfProtocolObjects[]--------------===================\n") 1215 | for x in listOfProtocolObjects: 1216 | outputFileDebugDump.write("******************\n") 1217 | outputFileDebugDump.write(x.fullLine) 1218 | x.writeToDebugLog(outputFileDebugDump) 1219 | #Print all the object groups in the listOfObjectGroups[] 1220 | outputFileDebugDump.write("=================------------------DUMP listOfObjectGroups[] One Level--------------===================\n") 1221 | for x in listOfObjectGroups: 1222 | outputFileDebugDump.write("******************\n") 1223 | x.writeToDebugLogDirectItemsOnly(outputFileDebugDump) 1224 | outputFileDebugDump.write("=================------------------DUMP listOfInterfaces[]---------------======================\n") 1225 | for x in listOfInterfaces: 1226 | x.writeToDebugLog(outputFileDebugDump) 1227 | outputFileDebugDump.write("=================------------------DUMP listOfTunnelGroups[]------------========================\n") 1228 | for x in listOfTunnelGroups: 1229 | x.writeToDebugLog(outputFileDebugDump) 1230 | 1231 | #TESTING FOR super expanding all ACLs 1232 | outputFileLargeACLs.write('******ACL Applied to each Interface******\n') 1233 | for x in listOfAccessGroups: 1234 | outputFileLargeACLs.write('Interface: '+x.interfaceAppliedTo+' '+x.direction+' ACL: '+x.aclApplied+'\n') 1235 | outputFileLargeACLs.write('*****END ACL Applied to each Interface*******\n') 1236 | for x in listOfAccessLists: 1237 | for z in listOfAccessGroups: 1238 | if z.aclApplied == x.name: 1239 | outputFileLargeACLs.write('*********************Applied to interface: '+z.interfaceAppliedTo+' '+z.direction+'*********************\n') 1240 | outputFileLargeACLs.write('******ACL Name: ' + x.name + '\n') 1241 | for y in x.listOfRules: 1242 | tempExpandedRules = ExpandRule(y,listOfObjectGroups,listOfAccessLists) 1243 | for z in tempExpandedRules: 1244 | outputFileLargeACLs.write(z + '\n') 1245 | outputFileLargeACLs.write('\n') 1246 | 1247 | #Super Expand all ACL's for copy and paste into Routers/Switches without network objects 1248 | outputFileLargeACLsForCopyAndPaste.write('******ACL Applied to each Interface******\n') 1249 | for x in listOfAccessGroups: 1250 | outputFileLargeACLsForCopyAndPaste.write('Interface: '+x.interfaceAppliedTo+' '+x.direction+' ACL: '+x.aclApplied+'\n') 1251 | outputFileLargeACLsForCopyAndPaste.write('*****END ACL Applied to each Interface*******\n') 1252 | for x in listOfAccessLists: 1253 | for z in listOfAccessGroups: 1254 | if z.aclApplied == x.name: 1255 | outputFileLargeACLsForCopyAndPaste.write('*********************Applied to interface: '+z.interfaceAppliedTo+' '+z.direction+'*********************\n') 1256 | outputFileLargeACLsForCopyAndPaste.write('******ACL Name: ' + x.name + '\n') 1257 | #WE need to print the command to create the IP list ex: ip access-list extended aclname 1258 | #Get the first AccessListSubRule in the listOfRules.accessListSubRuleList to pull the values 1259 | tempS1 = x.accessListSubRuleList[0].accessListType 1260 | commandStartACL = "ip access-list " + tempS1 + " " + x.name 1261 | outputFileLargeACLsForCopyAndPaste.write(commandStartACL+"\n") 1262 | #print x.name 1263 | for y in x.listOfRules: 1264 | tempExpandedRules = ExpandRule(y,listOfObjectGroups,listOfAccessLists) 1265 | for z in tempExpandedRules: 1266 | pattern = re.compile('(deny|permit)[^/]*$', re.IGNORECASE) 1267 | #pattern = re.compile('permit', re.IGNORECASE) 1268 | match = pattern.search(z) 1269 | #print match.group() 1270 | if match: 1271 | outputFileLargeACLsForCopyAndPaste.write(" " + match.group() + '\n') 1272 | outputFileLargeACLsForCopyAndPaste.write('\n') 1273 | 1274 | print "Hostname = " + hostname[0] 1275 | print "Lines Processed = " + str(linesProcessed) 1276 | print "Lines Ignored = " + str(linesIgnored) 1277 | print "lines total = " + str(linesTotal) 1278 | print "****************STOP PARSING CONFIG****************" 1279 | return(listOfAccessGroups,listOfHosts,listOfObjectGroups,listOfServiceObjects,listOfPortObjects,listOfProtocolObjects,listOfIcmpObjects,listOfAccessLists,listOfInterfaces,listOfTunnelGroups) 1280 | 1281 | def CompareProtocolExpandedLists(list1,list2): 1282 | set1 = set(list1) 1283 | set2 = set(list2) 1284 | if set1 == set2: 1285 | return 100 1286 | else: 1287 | return 0 1288 | 1289 | def CompareSourceIpExpandedLists(list1,list2): 1290 | set1 = set(list1) 1291 | set2 = set(list2) 1292 | if set1 == set2: 1293 | return 100 1294 | else: 1295 | return 0 1296 | 1297 | def CompareSourcePortExpandedLists(list1,list2): 1298 | set1 = set(list1) 1299 | set2 = set(list2) 1300 | if set1 == set2: 1301 | return 100 1302 | else: 1303 | return 0 1304 | 1305 | def CompareDestIpExpandedLists(list1,list2): 1306 | set1 = set(list1) 1307 | set2 = set(list2) 1308 | if set1 == set2: 1309 | return 100 1310 | else: 1311 | return 0 1312 | 1313 | def CompareDestPortExpandedLists(list1,list2): 1314 | set1 = set(list1) 1315 | set2 = set(list2) 1316 | if set1 == set2: 1317 | return 100 1318 | else: 1319 | return 0 1320 | 1321 | def CompareRuleType(aceOne,aceTwo): 1322 | if aceOne.typeOfAccess == aceTwo.typeOfAccess: 1323 | return 100 1324 | else: 1325 | return 0 1326 | 1327 | def printCopyAndPasteOfSingleObject(fileWrite,fileWriteDebug,object,boolean): 1328 | doDebugDump = boolean 1329 | fileReqObjectGroupDebugDump = fileWriteDebug 1330 | fileReqObjectGroupCopyPaste = fileWrite 1331 | y = object 1332 | if doDebugDump == True: 1333 | fileReqObjectGroupDebugDump.write("Name of retreived object " + y.name + "\n") 1334 | fileReqObjectGroupDebugDump.write("fullLine of object: " + y.fullLine) 1335 | fileReqObjectGroupDebugDump.write("listOfNetworkObjects Length: "+str(len(y.listOfNetworkObjects))+"\n") 1336 | fileReqObjectGroupDebugDump.write("listOfServiceObjects Length: "+str(len(y.listOfServiceObjects))+"\n") 1337 | fileReqObjectGroupDebugDump.write("listOfObjectGroups Length: "+str(len(y.listOfObjectGroups))+"\n") 1338 | fileReqObjectGroupDebugDump.write("listOfIcmpObjects Length: "+str(len(y.listOfIcmpObjects))+"\n") 1339 | fileReqObjectGroupDebugDump.write("listOfPortObjects Length: "+str(len(y.listOfPortObjects))+"\n") 1340 | fileReqObjectGroupDebugDump.write("listOfProtocolObjects Length: "+str(len(y.listOfProtocolObjects))+"\n") 1341 | fileReqObjectGroupCopyPaste.write(y.fullLine) 1342 | if doDebugDump == True: 1343 | fileReqObjectGroupDebugDump.write(y.fullLine) 1344 | if len(y.listOfNetworkObjects) > 0: 1345 | for z in y.listOfNetworkObjects: 1346 | fileReqObjectGroupCopyPaste.write(z.fullLine) 1347 | if doDebugDump == True: 1348 | fileReqObjectGroupDebugDump.write(z.fullLine) 1349 | if len(y.listOfServiceObjects) > 0: 1350 | for z in y.listOfServiceObjects: 1351 | fileReqObjectGroupCopyPaste.write(z.fullLine) 1352 | if doDebugDump == True: 1353 | fileReqObjectGroupDebugDump.write(z.fullLine) 1354 | if len(y.listOfIcmpObjects) > 0: 1355 | for z in y.listOfIcmpObjects: 1356 | fileReqObjectGroupCopyPaste.write(z.fullLine) 1357 | if doDebugDump == True: 1358 | fileReqObjectGroupDebugDump.write(z.fullLine) 1359 | if len(y.listOfPortObjects) > 0: 1360 | for z in y.listOfPortObjects: 1361 | fileReqObjectGroupCopyPaste.write(z.fullLine) 1362 | if doDebugDump == True: 1363 | fileReqObjectGroupDebugDump.write(z.fullLine) 1364 | if len(y.listOfProtocolObjects) > 0: 1365 | for z in y.listOfProtocolObjects: 1366 | fileReqObjectGroupCopyPaste.write(z.fullLine) 1367 | if doDebugDump == True: 1368 | fileReqObjectGroupDebugDump.write(z.fullLine) 1369 | #Add Sub groups to the object group 1370 | if len(y.listOfObjectGroups) > 0: 1371 | for z in y.listOfObjectGroups: 1372 | fileReqObjectGroupCopyPaste.write(" group-object "+z+"\n") 1373 | if doDebugDump == True: 1374 | fileReqObjectGroupDebugDump.write(" group-object "+z+"\n") 1375 | #Must end in an exit for copy and past to work 1376 | if doDebugDump == True: 1377 | fileReqObjectGroupCopyPaste.write("exit\n") 1378 | fileReqObjectGroupDebugDump.write("exit\n") 1379 | 1380 | def printCopyAndPasteOfObject(name,allObjectGroups,allPrintedObjects,fileWrite,fileWriteDebug,doDebugDump): 1381 | for x in allObjectGroups: 1382 | if x.name == name: 1383 | break 1384 | #IF has object groups cycle through them. 1385 | if len(x.listOfObjectGroups)>0: 1386 | for t in x.listOfObjectGroups: 1387 | for r in allObjectGroups: 1388 | if r.name == t: 1389 | printCopyAndPasteOfObject(t,allObjectGroups,allPrintedObjects,fileWrite,fileWriteDebug,doDebugDump) 1390 | #elif : #Has no object groups so we hit bottom, so print me 1391 | if name not in allPrintedObjects: 1392 | printCopyAndPasteOfSingleObject(fileWrite,fileWriteDebug,x,doDebugDump) 1393 | allPrintedObjects.add(name) 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | def main(): 1400 | 1401 | 1402 | #PYSVN RELATED 1403 | def ssl_server_trust_prompt(trust_dict ): 1404 | retcode = True 1405 | accepted_failures = trust_dict['failures'] 1406 | save = False 1407 | return retcode, accepted_failures, save 1408 | 1409 | def get_login(realm, username, may_save): 1410 | try: 1411 | svnRealm = configParser.get('SVNconfig','SVNrealm') 1412 | except: 1413 | print "Something bad happened when reading conf.ini SVNConfig section. Just throwing my hands up" 1414 | retcode = True 1415 | realm = svnRealm 1416 | username = raw_input("Enter username: ") 1417 | password = getpass.getpass() 1418 | save = False 1419 | return retcode,username,password,save 1420 | 1421 | def get_login2(realm, username, may_save): 1422 | try: 1423 | rancidUser = configParser.get('SVNconfig','SVNuser') 1424 | rancidPassword = configParser.get('SVNconfig','SVNpassword') 1425 | svnRealm = configParser.get('SVNconfig','SVNrealm') 1426 | except: 1427 | print "Something bad happened when reading conf.ini SVNConfig section. Just throwing my hands up" 1428 | retcode = True 1429 | realm = svnRealm 1430 | username = rancidUser 1431 | password = rancidPassword 1432 | save = False 1433 | return retcode,username,password,save 1434 | 1435 | 1436 | 1437 | 1438 | configParser = SafeConfigParser() 1439 | try: 1440 | configParser.read('conf.ini') 1441 | programMode = configParser.get('Basic','Mode') 1442 | installedDir = configParser.get('Basic','InstalledDir') 1443 | logDir = configParser.get('Basic','LogDir') 1444 | tempDir = configParser.get('Basic','TempDir') 1445 | outputDir = configParser.get('Basic','outputDir') 1446 | DBhost = configParser.get('Database','DBhost') 1447 | DBschema = configParser.get('Database','DBschema') 1448 | DBuser = configParser.get('Database','DBuser') 1449 | DBpassword = configParser.get('Database','DBpassword') 1450 | 1451 | except: 1452 | print "Something bad happened when reading conf.ini. Failing to local mode" 1453 | programMode = 'Local' 1454 | 1455 | options = {} 1456 | 1457 | outputFile = outputDir+'output.txt' 1458 | outputFileLargeACLs = outputDir+'output-LargeACLs.txt' 1459 | outputFileLargeACLsForCopyAndPaste = outputDir+'output-LargeACLs-CopyPaste.txt' 1460 | outputFileDebugDump = outputDir+'debugDump.txt' 1461 | outputFileLogging = logDir+'LogFile.txt' 1462 | 1463 | 1464 | 1465 | 1466 | options['DBhost'] = DBhost 1467 | options['DBschema'] = DBschema 1468 | options['DBuser'] = DBuser 1469 | options['DBpassword'] = DBpassword 1470 | 1471 | #Based on programMode in conf.ini set or ask controlling variables. 1472 | if programMode == 'All': 1473 | debugDump = raw_input('do a debug dump? y/n :') 1474 | if debugDump == 'y': 1475 | doDebugDump = True 1476 | else: doDebugDump = False 1477 | pushToSQL = raw_input("Should I push data to SQL DB? y/n :") 1478 | if pushToSQL == 'y': 1479 | doSQLStuff = True 1480 | import MySQLdb #If not libaries not available, we will crash 1481 | else: doSQLStuff = False 1482 | getFileFrom = raw_input("Where to get file from? local/remote/rancidlist/localcompare : ") 1483 | elif programMode == 'Local': 1484 | debugDump = raw_input('do a debug dump? y/n :') 1485 | if debugDump == 'y': 1486 | doDebugDump = True 1487 | else: doDebugDump = False 1488 | getFileFrom = 'local' 1489 | pushToSQL = False 1490 | 1491 | options['getFileFrom'] = getFileFrom 1492 | options['doDebugDump'] = doDebugDump 1493 | options['doSQLStuff'] = doSQLStuff 1494 | 1495 | 1496 | 1497 | # Based On set program control variables do some stuff 1498 | if getFileFrom == 'local': 1499 | input1 = raw_input("Enter local filename: ") 1500 | inputFile = open(installedDir+input1 , 'r') 1501 | options['deviceConfig'] = input1 1502 | deviceType = raw_input("Enter Device Type[cisco_asa / cisco_switch: ") 1503 | options['deviceType'] = deviceType 1504 | deviceRepoRevisionNumber = 0 1505 | if getFileFrom == 'localpoc': 1506 | input1 = raw_input("Enter local filename: ") 1507 | inputFile = open(installedDir+input1 , 'r') 1508 | options['deviceConfig'] = input1 1509 | deviceType = raw_input("Enter Device Type[cisco_asa / cisco_switch: ") 1510 | options['deviceType'] = deviceType 1511 | deviceRepoRevisionNumber = 0 1512 | if getFileFrom == 'localcompare': 1513 | input1 = raw_input("Enter local filename one: ") 1514 | inputFile = open(installedDir+input1 , 'r') 1515 | options['deviceConfig'] = input1 1516 | input2 = raw_input("Enter local filename two: ") 1517 | secondInputFile = open(installedDir+input2 , 'r') 1518 | options['deviceConfig2'] = input2 1519 | deviceType = raw_input("Enter Device Type[cisco_asa / cisco_switch: ") 1520 | options['deviceType'] = deviceType 1521 | deviceRepoRevisionNumber = 0 1522 | elif getFileFrom == 'remote': 1523 | import pysvn #libaries better be available, or we will crash 1524 | try: 1525 | svnRepo = configParser.get('SVNconfig','SVNrepo') 1526 | except: 1527 | print "Something bad happened when reading conf.ini SVNconfig Section. Just throwing my hands up" 1528 | #PYSVN Stuff 1529 | deviceConfig = raw_input("Device IP Address: ") 1530 | options['deviceConfig'] = deviceConfig 1531 | deviceType = raw_input("Enter Device Type[cisco_asa / cisco_switch: ") 1532 | options['deviceType'] = deviceType 1533 | client = pysvn.Client() 1534 | client.callback_ssl_server_trust_prompt = ssl_server_trust_prompt 1535 | client.callback_get_login = get_login 1536 | #Gets the Entire RepoList and Prints it out 1537 | #repoList = client.list(svnRepo) 1538 | ##print dir(pysvn.depth) 1539 | #print repoList 1540 | #for x in repoList: 1541 | # for y in x: 1542 | # if y: 1543 | # print y["repos_path"] 1544 | ##Get Directory Revision Number 1545 | #headRevision = client.revpropget("revision", url=svnRepo+deviceConfig) 1546 | #clientInfo = client.info2(svnRepo+deviceConfig,revision=pysvn.Revision(pysvn.opt_revision_kind.head), recurse=False) 1547 | #print clientInfo[0][1]['rev'].number 1548 | rev = pysvn.Revision(pysvn.opt_revision_kind.head) 1549 | info = client.info2(svnRepo+deviceConfig,revision=rev,recurse=False) 1550 | revno = info[0][1].last_changed_rev.number 1551 | #revno = info[0][1].rev.number # revision number as an integer 1552 | print "lastChange Revision Number = " + str(revno) 1553 | deviceRepoRevisionNumber = revno 1554 | #Pull the device config into a temporary file for parsing 1555 | client.export(svnRepo+deviceConfig, installedDir+"tempConfigFile"+deviceConfig+".tmp") 1556 | inputFile = open(installedDir+"tempConfigFile"+deviceConfig+".tmp",'r') 1557 | outputFile = outputDir+deviceConfig+".txt" 1558 | elif getFileFrom == "rancidlist": 1559 | #Check a local file for a list of configs to download from the SVN Repo 1560 | configListFile = open('configList.conf','r') 1561 | deviceRepoRevisionNumber = 0 1562 | #elif getFileFrom == "AUTO": 1563 | # inputFile = passedFromControlScript 1564 | 1565 | 1566 | options['deviceRepoRevisionNumber'] = deviceRepoRevisionNumber 1567 | options['outputFile'] = outputFile 1568 | options['outputFileLargeACLs'] = outputFileLargeACLs 1569 | options['outputFileLargeACLsForCopyAndPaste'] = outputFileLargeACLsForCopyAndPaste 1570 | options['outputFileDebugDump'] = outputFileDebugDump 1571 | options['outputFileLogging'] = outputFileLogging 1572 | options['installedDir'] = installedDir 1573 | 1574 | #Parse the inputFile with the options from the dict 1575 | if getFileFrom == 'local' or getFileFrom == 'remote': 1576 | print "Running as local" 1577 | ParseMe(inputFile, options) 1578 | 1579 | #Parse the inputFile with the options from the dict 1580 | if getFileFrom == 'localpoc': 1581 | import socket,struct 1582 | print "Running as localPOC" 1583 | listOfAccessGroups,listOfHosts,listOfObjectGroups,listOfServiceObjects,listOfPortObjects,listOfProtocolObjects,listOfIcmpObjects,listOfAccessLists,listOfInterfaces,listOfTunnelGroups = ParseMe(inputFile, options) 1584 | #File to write out ACE config line and the POC to contact 1585 | outputFileSubnetToPOC = outputDir+'SubnetToPOC.txt' 1586 | fileSubnetToPOC = open(outputFileSubnetToPOC,'w') 1587 | outputFileSubnetToPOCdebug = outputDir+'SubnetToPOCdebug.txt' 1588 | fileSubnetToPOCdebug = open(outputFileSubnetToPOCdebug,'w') 1589 | #Load in the CSV File 1590 | with open('POC.csv') as csvfile: 1591 | pocDict = csv.DictReader(csvfile) 1592 | #for row in pocDict: 1593 | #print(row['ip'], row['subnet'], row['poc']) 1594 | 1595 | 1596 | #Will have to cycle through all the ACE's in the ACL's and lookup against the imported CSV file 1597 | expandedSplit = [] 1598 | for acl in listOfAccessLists: 1599 | for ace in acl.accessListSubRuleList: 1600 | #Print out the ACE we are working on 1601 | if doDebugDump == True: 1602 | fileSubnetToPOCdebug.write(ace.fullLine+"\n") 1603 | #For the Dest Section - Come back to this 1604 | if doDebugDump == True: 1605 | fileSubnetToPOCdebug.write("DEST SECTION LOOKUP\n") 1606 | #print "*********\n" 1607 | for x in ace.dest_ip_expanded: 1608 | if doDebugDump == True: 1609 | fileSubnetToPOCdebug.write(x+"\n")#TEMP THING 1610 | expandedSplit = x.split() 1611 | try: 1612 | if expandedSplit[1] == "255.255.255.255": 1613 | if doDebugDump == True: 1614 | fileSubnetToPOCdebug.write("IT's A HOST!\n") 1615 | if expandedSplit[1] != "255.255.255.255": 1616 | if doDebugDump == True: 1617 | fileSubnetToPOCdebug.write("IT's A SUBNET!\n") 1618 | 1619 | 1620 | except IndexError: 1621 | print "Index Error, skipping " + x 1622 | if doDebugDump == True: 1623 | fileSubnetToPOCdebug.write("Can't Parse, skipping '" + x + "'\n") 1624 | 1625 | #For the Source Section 1626 | if doDebugDump == True: 1627 | fileSubnetToPOCdebug.write("SOURCE SECTION LOOKUP\n") 1628 | for x in ace.source_ip_expanded: 1629 | if doDebugDump == True: 1630 | fileSubnetToPOCdebug.write(x+"\n")#TEMP THING 1631 | expandedSplit = x.split() 1632 | try: 1633 | if expandedSplit[1] == "255.255.255.255": 1634 | if doDebugDump == True: 1635 | fileSubnetToPOCdebug.write("IT's A HOST!\n") 1636 | if expandedSplit[1] != "255.255.255.255": 1637 | if doDebugDump == True: 1638 | fileSubnetToPOCdebug.write("IT's A SUBNET!\n") 1639 | 1640 | 1641 | except IndexError: 1642 | print "Index Error, skipping " + x 1643 | if doDebugDump == True: 1644 | fileSubnetToPOCdebug.write("Can't Parse, skipping '" + x + "'\n") 1645 | #End of ACE processing 1646 | if doDebugDump == True: 1647 | fileSubnetToPOCdebug.write("-----------------------------------------------------\n") 1648 | 1649 | #Parse the inputFile with the options from the dict 1650 | if getFileFrom == 'localcompare': 1651 | print "Running as localcompare" 1652 | #Line below is the orginal basic parse 1653 | #ParseMe(inputFile, options) 1654 | #Changing ParseMe to return multiple lists 1655 | listOfAccessGroups1,listOfHosts1,listOfObjectGroups1,listOfServiceObjects1,listOfPortObjects1,listOfProtocolObjects1,listOfIcmpObjects1,listOfAccessLists1,listOfInterfaces1,listOfTunnelGroups1 = ParseMe(inputFile, options) 1656 | # Changing options for the second file outputs and inputs 1657 | outputFile = outputDir+"SECOND-output.txt" 1658 | outputFileLargeACLs = outputDir+'SECOND-output-LargeACLs.txt' 1659 | outputFileLargeACLsForCopyAndPaste = outputDir+'SECOND-output-LargeACLs-CopyPaste.txt' 1660 | outputFileDebugDump = outputDir+'SECOND-debugDump.txt' 1661 | outputFileLogging = logDir+'SECOND-LogFile.txt' 1662 | outputFileAclComparisonDebugDump = outputDir+'ACLComparisonDebug.txt' 1663 | outputFileAclMatchList = outputDir+'ACL_Match_List.txt' 1664 | outputFileAclNoMatchList = outputDir+'ACL_NO_Match_List.txt' 1665 | outputFileAcl100MatchList = outputDir+'ACL_100_Match_List_Dump.txt' 1666 | outputFileReqObjectGroupDebugDump = outputDir+'ReqObjectGroupDebug.txt' 1667 | outputFileReqObjectGroupCopyPaste = outputDir+'ReqObjectGroupCopyPaste.txt' 1668 | options['deviceConfig'] = input2 1669 | #print options['deviceConfig'] 1670 | options['outputFile'] = outputFile 1671 | options['deviceRepoRevisionNumber'] = deviceRepoRevisionNumber 1672 | options['outputFileLargeACLs'] = outputFileLargeACLs 1673 | options['outputFileLargeACLsForCopyAndPaste'] = outputFileLargeACLsForCopyAndPaste 1674 | options['outputFileDebugDump'] = outputFileDebugDump 1675 | options['outputFileLogging'] = outputFileLogging 1676 | options['deviceType'] = deviceType 1677 | options['installedDir'] = installedDir 1678 | fileAclComparisonDebugDump = open(outputFileAclComparisonDebugDump,'w') 1679 | fileAclMatchList = open(outputFileAclMatchList,'w') 1680 | fileAclNoMatchList = open(outputFileAclNoMatchList,'w') 1681 | fileAcl100MatchList = open(outputFileAcl100MatchList,'w') 1682 | fileReqObjectGroupDebugDump = open(outputFileReqObjectGroupDebugDump,'w') 1683 | fileReqObjectGroupCopyPaste = open(outputFileReqObjectGroupCopyPaste,'w') 1684 | listOfAccessGroups2,listOfHosts2,listOfObjectGroups2,listOfServiceObjects2,listOfPortObjects2,listOfProtocolObjects2,listOfIcmpObjects2,listOfAccessLists2,listOfInterfaces2,listOfTunnelGroups2 = ParseMe(secondInputFile, options) 1685 | print "Count for listOfAccessGroups: ", len(listOfAccessGroups1) 1686 | print "Count for listOfHosts: ", len(listOfHosts1) 1687 | print "Count for listOfObjectGroups: ", len(listOfObjectGroups1) 1688 | print "Count for listOfServiceObjects: ", len(listOfServiceObjects1) 1689 | print "Count for listOfPortObjects: ", len(listOfPortObjects1) 1690 | print "Count for listOfProtocolObjects: ", len(listOfProtocolObjects1) 1691 | print "Count for listOfIcmpObjects: ", len(listOfIcmpObjects1) 1692 | print "Count for listOfAccessLists: ", len(listOfAccessLists1) 1693 | print "Count for listOfInterfaces: ", len(listOfInterfaces1) 1694 | print "Count for listOfTunnelGroups: ", len(listOfTunnelGroups1) 1695 | print "Count for listOfAccessGroups2: ", len(listOfAccessGroups2) 1696 | print "Count for listOfHosts2: ", len(listOfHosts2) 1697 | print "Count for listOfObjectGroups2: ", len(listOfObjectGroups2) 1698 | print "Count for listOfServiceObjects2: ", len(listOfServiceObjects2) 1699 | print "Count for listOfPortObjects2: ", len(listOfPortObjects2) 1700 | print "Count for listOfProtocolObjects2: ", len(listOfProtocolObjects2) 1701 | print "Count for listOfIcmpObjects2: ", len(listOfIcmpObjects2) 1702 | print "Count for listOfAccessLists2: ", len(listOfAccessLists2) 1703 | print "Count for listOfInterfaces2: ", len(listOfInterfaces2) 1704 | print "Count for listOfTunnelGroups2: ", len(listOfTunnelGroups2) 1705 | 1706 | print "---===BEGIN ACL COMPARISON===---" 1707 | 1708 | primaryConfigACL = '' 1709 | secondaryConfigACL = '' 1710 | for x in listOfAccessLists1: 1711 | primaryConfigACL = primaryConfigACL + x.name + " " 1712 | for x in listOfAccessLists2: 1713 | secondaryConfigACL = secondaryConfigACL + x.name + " " 1714 | print("ACL Choices on Primary Config: " + primaryConfigACL) 1715 | input3 = raw_input("Enter Primary Config ACL to compare with: ") 1716 | print("ACL Choices on Secondary Config: " + secondaryConfigACL) 1717 | input4 = raw_input("Enter Secondary Config ACL to compare against Primary: ") 1718 | input5 = raw_input("Enter the value to append to conflict ace/objects: ") 1719 | aceMatchList = [] 1720 | aceNoMatchList = [] 1721 | primaryACL = [] 1722 | secondaryACL = [] 1723 | for x in listOfAccessLists1: 1724 | if x.name == input3: 1725 | primaryACL = x 1726 | for x in listOfAccessLists2: 1727 | if x.name == input4: 1728 | secondaryACL = x 1729 | 1730 | #TEMP REMOVE LATER 1731 | #for aceOneTemp in primaryACL.accessListSubRuleList: 1732 | # print "(DUMP PRIMARY ACL)AceOneTemp= " + aceOneTemp.fullLine 1733 | #for aceTwoTemp in secondaryACL.accessListSubRuleList: 1734 | # print "(DUMP SECONDARY ACL)AceTwoTemp= " + aceTwoTemp.fullLine 1735 | 1736 | #Start comparing all the ACLs to each other 1737 | for aceOneTemp in primaryACL.accessListSubRuleList: 1738 | #for aceTwoTemp in aceMatchList: 1739 | #print "(outerloop)AceOneTemp= " + aceOneTemp.fullLine 1740 | #GO AWAY for aceTwoTemp in aceNoMatchList: 1741 | i = 0 1742 | while i < len(aceNoMatchList): 1743 | aceTwoTemp = aceNoMatchList[i] 1744 | #print "(innerLoop)(aceNoMatchList)AceTwoTemp= " + aceTwoTemp.fullLine 1745 | protocolCompareValue = CompareProtocolExpandedLists(aceOneTemp.protocol_expanded,aceTwoTemp.protocol_expanded) 1746 | sourceIpCompareValue = CompareSourceIpExpandedLists(aceOneTemp.source_ip_expanded,aceTwoTemp.source_ip_expanded) 1747 | sourcePortCompareValue = 100 #Forcing a match until I verify soure port extractions 1748 | #sourcePortCompareValue = CompareSourcePortExpandedLists(aceOneTemp.source_port_expanded,aceTwoTemp.source_port_expanded) #STUB OR COMMENT THIS 1749 | destIpCompareValue = CompareDestIpExpandedLists(aceOneTemp.dest_ip_expanded,aceTwoTemp.dest_ip_expanded) 1750 | destPortCompareValue = CompareDestPortExpandedLists(aceOneTemp.dest_port_expanded,aceTwoTemp.dest_port_expanded) 1751 | typeOfAccessCompareValue = CompareRuleType(aceOneTemp,aceTwoTemp) 1752 | #Combine the values for a total match value 1753 | totalMatchValue = (protocolCompareValue + sourceIpCompareValue + sourcePortCompareValue + destIpCompareValue + destPortCompareValue + typeOfAccessCompareValue) / 6 1754 | if doDebugDump == True: 1755 | fileAclComparisonDebugDump.write("---===ACL COMPARISON TESTING===---\n") 1756 | fileAclComparisonDebugDump.write("*****COMPARING SUMMARY BELOW*****\n") 1757 | fileAclComparisonDebugDump.write("I'M IN THE NO MATCH LIST\n") 1758 | fileAclComparisonDebugDump.write("Primary Config ACE : "+ aceOneTemp.fullLine) 1759 | fileAclComparisonDebugDump.write("Secondary Config ACE: " + aceTwoTemp.fullLine) 1760 | fileAclComparisonDebugDump.write("protocolCompareValue: " + str(protocolCompareValue) + "\n") 1761 | fileAclComparisonDebugDump.write("sourceIpCompareValue: " + str(sourceIpCompareValue) + "\n") 1762 | fileAclComparisonDebugDump.write("sourcePortCompareValue: " + str(sourcePortCompareValue) + "\n") 1763 | fileAclComparisonDebugDump.write("destIpCompareValue: " + str(destIpCompareValue) + "\n") 1764 | fileAclComparisonDebugDump.write("destPortCompareValue" + str(destPortCompareValue) + "\n") 1765 | fileAclComparisonDebugDump.write("typeOfAccessCompareValue" + str(typeOfAccessCompareValue) + "\n") 1766 | fileAclComparisonDebugDump.write("totalMatchValue" + str(totalMatchValue) + "\n") 1767 | 1768 | if totalMatchValue == 100: 1769 | fileAcl100MatchList.write("******MATCHING PAIR BELOW*****\n") 1770 | fileAcl100MatchList.write("Primary ACE : "+ aceOneTemp.fullLine) 1771 | fileAcl100MatchList.write("Secondary ACe: "+ aceTwoTemp.fullLine) 1772 | #Do Match stuff. Move ACE from No Match list to Match list 1773 | #print "MATCH!" 1774 | aceMatchList.append(aceTwoTemp) 1775 | aceNoMatchList.remove(aceTwoTemp) 1776 | #DONT increment i 1777 | elif totalMatchValue < 100: 1778 | i += 1 1779 | #print "NO MATCH!" 1780 | #Do Nothing since its already in the No Match List 1781 | 1 == 1 #Just a placeholder 1782 | else: 1783 | i += 1 1784 | #Do A default case 1785 | # print "DEFAULT CASE!" 1786 | 1 == 1 #Just a placeholder 1787 | #for aceTwoTemp in secondaryACL.accessListSubRuleList: #Compare to the Starting list 1788 | i = 0 1789 | while i < len(secondaryACL.accessListSubRuleList): 1790 | aceTwoTemp = secondaryACL.accessListSubRuleList[i] 1791 | #print "(innerLoop)(secondarACL)AceTwoTemp= " + aceTwoTemp.fullLine 1792 | protocolCompareValue = CompareProtocolExpandedLists(aceOneTemp.protocol_expanded,aceTwoTemp.protocol_expanded) 1793 | sourceIpCompareValue = CompareSourceIpExpandedLists(aceOneTemp.source_ip_expanded,aceTwoTemp.source_ip_expanded) 1794 | sourcePortCompareValue = 100 #Forcing a match until I verify soure port extractions 1795 | #sourcePortCompareValue = CompareSourcePortExpandedLists(aceOneTemp.source_port_expanded,aceTwoTemp.source_port_expanded) #STUB OR COMMENT THIS 1796 | destIpCompareValue = CompareDestIpExpandedLists(aceOneTemp.dest_ip_expanded,aceTwoTemp.dest_ip_expanded) 1797 | destPortCompareValue = CompareDestPortExpandedLists(aceOneTemp.dest_port_expanded,aceTwoTemp.dest_port_expanded) 1798 | typeOfAccessCompareValue = CompareRuleType(aceOneTemp,aceTwoTemp) 1799 | #Combine the values for a total match value 1800 | totalMatchValue = (protocolCompareValue + sourceIpCompareValue + sourcePortCompareValue + destIpCompareValue + destPortCompareValue + typeOfAccessCompareValue) / 6 1801 | if doDebugDump == True: 1802 | fileAclComparisonDebugDump.write("---===ACL COMPARISON TESTING===---\n") 1803 | fileAclComparisonDebugDump.write("*****COMPARING SUMMARY BELOW*****\n") 1804 | fileAclComparisonDebugDump.write("I'M IN THE SECONDARY LIST\n") 1805 | fileAclComparisonDebugDump.write("Primary Config ACE :"+ aceOneTemp.fullLine) 1806 | fileAclComparisonDebugDump.write("Secondary Config ACE: " + aceTwoTemp.fullLine) 1807 | fileAclComparisonDebugDump.write("protocolCompareValue: "+ str(protocolCompareValue) + "\n") 1808 | fileAclComparisonDebugDump.write("sourceIpCompareValue: " + str(sourceIpCompareValue) + "\n") 1809 | fileAclComparisonDebugDump.write("sourcePortCompareValue: " + str(sourcePortCompareValue) + "\n") 1810 | fileAclComparisonDebugDump.write("destIpCompareValue: " + str(destIpCompareValue) + "\n") 1811 | fileAclComparisonDebugDump.write("destPortCompareValue" + str(destPortCompareValue) + "\n") 1812 | fileAclComparisonDebugDump.write("typeOfAccessCompareValue" + str(typeOfAccessCompareValue) + "\n") 1813 | fileAclComparisonDebugDump.write("totalMatchValue" + str(totalMatchValue) + "\n") 1814 | if totalMatchValue == 100: 1815 | fileAcl100MatchList.write("******MATCHING PAIR BELOW*****\n") 1816 | fileAcl100MatchList.write("Primary ACE : "+ aceOneTemp.fullLine) 1817 | fileAcl100MatchList.write("Secondary ACE: "+ aceTwoTemp.fullLine) 1818 | #print "MATCH!" 1819 | #Do Match stuff. Move ACE from starting list to Match list 1820 | aceMatchList.append(aceTwoTemp) 1821 | secondaryACL.accessListSubRuleList.remove(aceTwoTemp) 1822 | elif totalMatchValue < 100: 1823 | #print "NO MATCH!" 1824 | #Do NO Match stuff 1825 | aceNoMatchList.append(aceTwoTemp) 1826 | secondaryACL.accessListSubRuleList.remove(aceTwoTemp) 1827 | else: 1828 | i += 1 1829 | #print "DEFAULT CASE!" 1830 | #Do A default case 1831 | 1 == 1 #Just a placeholder 1832 | 1833 | print "ACE's in the Match List: ", len(aceMatchList) 1834 | print "ACE's in the NO Match List: ", len(aceNoMatchList) 1835 | print "ACE's in the secondaryACL List: ", len(secondaryACL.accessListSubRuleList) 1836 | print "ACE's in the primaryACL: ", len(primaryACL.accessListSubRuleList) 1837 | #print "***aceMatchList***" 1838 | fileAclMatchList.write("*** ACE MATCH LIST ***\n") 1839 | for x in aceMatchList: 1840 | #print x.fullLine 1841 | fileAclMatchList.write(x.fullLine) 1842 | #print "***aceNoMatchList***" 1843 | fileAclNoMatchList.write("*** ACE NO MATCH LIST ***\n") 1844 | for x in aceNoMatchList: 1845 | #print x.fullLine 1846 | fileAclNoMatchList.write(x.fullLine) 1847 | #Go through the aceNoMatchList to find required Object Groups for a copy and paste config 1848 | setOfRequiredObjects = set() 1849 | for tempACE in aceNoMatchList: 1850 | #Check if Protocol section is an Object Group 1851 | if tempACE.protocolIsOG == True: 1852 | setOfRequiredObjects.add(tempACE.protocol) 1853 | elif tempACE.protocolIsO == True: 1854 | #DO SOMETHING, This might only matter before version 9 1855 | setOfRequiredObjects.add(tempACE.protocol) 1856 | #Check if Source section is an Object Group 1857 | if tempACE.sourceIsOG == True: 1858 | setOfRequiredObjects.add(tempACE.source) 1859 | elif tempACE.sourceIsO == True: 1860 | #DO SOMETHING, This might only matter before version 9 1861 | setOfRequiredObjects.add(tempACE.source) 1862 | #Check if Source Port section is an Object Group 1863 | if tempACE.source_portIsOG == True: 1864 | #DO SOMETHING 1865 | setOfRequiredObjects.add(tempACE.source_port) 1866 | elif tempACE.source_portIsO == True: 1867 | setOfRequiredObjects.add(tempACE.source_port) 1868 | #Check if Dest section is an Object Group 1869 | if tempACE.destIsOG == True: 1870 | #DO SOMETHING 1871 | setOfRequiredObjects.add(tempACE.dest) 1872 | elif tempACE.destIsO == True: 1873 | #DO SOMETHING, This might only matter before version 9 1874 | setOfRequiredObjects.add(tempACE.dest) 1875 | #Check if Dest port is an Object Group 1876 | if tempACE.dest_portIsOG == True: 1877 | #DO SOMETHING 1878 | setOfRequiredObjects.add(tempACE.dest_port) 1879 | elif tempACE.dest_portIsO == True: 1880 | #DO SOMETHING, This might only matter before version 9 1881 | setOfRequiredObjects.add(tempACE.dest_port) 1882 | #print "REQUIRED OBJECTS" 1883 | #for x in setOfRequiredObjects: 1884 | #print x 1885 | 1886 | #x is just a name, so we have to retrieive the object from the listOfObjectGroups2 1887 | allPrintedObjects = set() 1888 | for x in setOfRequiredObjects: 1889 | if doDebugDump == True: 1890 | fileReqObjectGroupDebugDump.write("****Name of Object in Req List= "+x+"\n") 1891 | printCopyAndPasteOfObject(x,listOfObjectGroups2,allPrintedObjects,fileReqObjectGroupCopyPaste,fileReqObjectGroupDebugDump,doDebugDump) 1892 | 1893 | #Identify where objects fullLine do not match. This is name, not content 1894 | setOfRequiredObjectsNameConflicts = set () #The ending tcp/udp/tcp-udp 1895 | setOfRequiredObjectsNoNameConflicts = set () #Add to config with no issues 1896 | setOfRequiredObjectsExactFullLineMatch = set () 1897 | setOfRequiredObjectsNotInPrimary = set() 1898 | for x in setOfRequiredObjects: #x is not an object, just a name of an object 1899 | #retrive that object from the list of objects for secondary config 1900 | for z in listOfObjectGroups2: 1901 | if x == z.name: 1902 | break 1903 | #now z is the object in question 1904 | for y in listOfObjectGroups1: 1905 | if y.fullLine == z.fullLine: 1906 | setOfRequiredObjectsExactFullLineMatch.add(z) 1907 | if y.name == z.name and y.fullLine != z.fullLine: 1908 | setOfRequiredObjectsNameConflicts.add(z) 1909 | 1910 | outputFileReqObjectsExactFullLineMatch = outputDir+'ReqObjectsExactFullLineMatch.txt' 1911 | fileReqObjectsExactFullLineMatch = open(outputFileReqObjectsExactFullLineMatch,'w') 1912 | outputFileReqObjectsExactFullLineMatchDebug = outputDir+'ReqObjectsExactFullLineMatchDebug.txt' 1913 | fileReqObjectsExactFullLineMatchDebug = open(outputFileReqObjectsExactFullLineMatchDebug,'w') 1914 | allPrintedObjects = set() 1915 | 1916 | #Print all the objects in the secondary config that have match in the primary config 1917 | fileReqObjectsExactFullLineMatch.write("All Objects in the Secondary config that have a match in the Primary based on fullLine value\n") 1918 | if doDebugDump == True: 1919 | fileReqObjectsExactFullLineMatchDebug.write("All Objects in the Secondary config that have a match in the Primary based on fullLine value\n") 1920 | for x in setOfRequiredObjectsExactFullLineMatch: 1921 | if doDebugDump == True: 1922 | fileReqObjectsExactFullLineMatchDebug.write("****Name of Object in Req List= "+x.fullLine) 1923 | printCopyAndPasteOfObject(x.name,listOfObjectGroups2,allPrintedObjects,fileReqObjectsExactFullLineMatch,fileReqObjectsExactFullLineMatchDebug,doDebugDump) 1924 | 1925 | outputFileReqObjectsNameConflicts = outputDir+'ReqObjectsNameConflicts.txt' 1926 | fileReqObjectsNameConflicts = open(outputFileReqObjectsNameConflicts,'w') 1927 | outputFileReqObjectsNameConflictsDebug = outputDir+'ReqObjectsNameConflictsDebug.txt' 1928 | fileReqObjectsNameConflictsDebug = open(outputFileReqObjectsNameConflictsDebug,'w') 1929 | allPrintedObjects = set() 1930 | 1931 | #Print all the objects in the secondary config that have a conflict in the primary config 1932 | fileReqObjectsNameConflicts.write("All Objects in the Secondary config that have a name conflict in the Primary based on fullLine value\n") 1933 | if doDebugDump == True: 1934 | fileReqObjectsNameConflictsDebug.write("All Objects in the Secondary config that have a name conflict in the Primary based on fullLine value\n") 1935 | for x in setOfRequiredObjectsNameConflicts: 1936 | if doDebugDump == True: 1937 | fileReqObjectsNameConflictsDebug.write("****Name of Object in Req List= "+x.fullLine) 1938 | printCopyAndPasteOfObject(x.name,listOfObjectGroups2,allPrintedObjects,fileReqObjectsNameConflicts,fileReqObjectsNameConflictsDebug,doDebugDump) 1939 | 1940 | #Remove the Name conflicts from the setOfRequiredObjects and print out 1941 | outputFileReqObjectGroupCopyPasteModified = outputDir+'ReqObjectGroupCopyPasteModified.txt' 1942 | fileReqObjectGroupCopyPasteModified = open(outputFileReqObjectGroupCopyPasteModified,'w') 1943 | outputFileReqObjectGroupCopyPasteModifiedDebug = outputDir+'ReqObjectGroupCopyPasteModifiedDebug.txt' 1944 | fileReqObjectGroupCopyPasteModifiedDebug = open(outputFileReqObjectGroupCopyPasteModifiedDebug,'w') 1945 | setOfRequiredObjectsModified = setOfRequiredObjects.copy() 1946 | for x in setOfRequiredObjectsNameConflicts: 1947 | setOfRequiredObjectsModified.remove(x.name) 1948 | #x is just a name, so we have to retrieive the object from the listOfObjectGroups2 1949 | allPrintedObjects = set() 1950 | for x in setOfRequiredObjectsModified: 1951 | if doDebugDump == True: 1952 | fileReqObjectGroupCopyPasteModifiedDebug.write("****Name of Object in Req List= "+x+"\n") 1953 | printCopyAndPasteOfObject(x,listOfObjectGroups2,allPrintedObjects,fileReqObjectGroupCopyPasteModified,fileReqObjectGroupCopyPasteModifiedDebug,doDebugDump) 1954 | 1955 | #Go through the aceNoMatchList to find required Object Groups for a copy and paste config 1956 | outputFileAclNoMatchListAppended = outputDir+'ACLNoMatchListAppended.txt' 1957 | fileAclNoMatchListAppended = open(outputFileAclNoMatchListAppended,'w') 1958 | appendedValue = input5 1959 | #appendedValue = "-SECOND" 1960 | setOfRequiredObjectsAppendedValue = set() 1961 | for tempACE in aceNoMatchList: 1962 | #Check if Protocol section is an Object Group 1963 | if tempACE.protocolIsOG == True: 1964 | setOfRequiredObjectsAppendedValue.add(tempACE.protocol+appendedValue) 1965 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.protocol+" ",tempACE.protocol+appendedValue+" ") 1966 | elif tempACE.protocolIsO == True: 1967 | #DO SOMETHING, This might only matter before version 9 1968 | setOfRequiredObjectsAppendedValue.add(tempACE.protocol+appendedValue) 1969 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.protocol+" ",tempACE.protocol+appendedValue+" ") 1970 | #Check if Source section is an Object Group 1971 | if tempACE.sourceIsOG == True: 1972 | setOfRequiredObjectsAppendedValue.add(tempACE.source+appendedValue) 1973 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.source+" ",tempACE.source+appendedValue+" ") 1974 | elif tempACE.sourceIsO == True: 1975 | #DO SOMETHING, This might only matter before version 9 1976 | setOfRequiredObjectsAppendedValue.add(tempACE.source+appendedValue) 1977 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.source+" ",tempACE.source+appendedValue+" ") 1978 | #Check if Source Port section is an Object Group 1979 | if tempACE.source_portIsOG == True: 1980 | #DO SOMETHING 1981 | setOfRequiredObjectsAppendedValue.add(tempACE.source_port+appendedValue) 1982 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.source_port+" ",tempACE.source_port+appendedValue+" ") 1983 | elif tempACE.source_portIsO == True: 1984 | setOfRequiredObjectsAppendedValue.add(tempACE.source_port+appendedValue) 1985 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.source_port+" ",tempACE.source_port+appendedValue+" ") 1986 | #Check if Dest section is an Object Group 1987 | if tempACE.destIsOG == True: 1988 | #DO SOMETHING 1989 | setOfRequiredObjectsAppendedValue.add(tempACE.dest+appendedValue) 1990 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.dest+" ",tempACE.dest+appendedValue+" ") 1991 | elif tempACE.destIsO == True: 1992 | #DO SOMETHING, This might only matter before version 9 1993 | setOfRequiredObjectsAppendedValue.add(tempACE.dest+appendedValue) 1994 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.dest+" ",tempACE.dest+appendedValue+" ") 1995 | #Check if Dest port is an Object Group 1996 | if tempACE.dest_portIsOG == True: 1997 | #DO SOMETHING 1998 | setOfRequiredObjectsAppendedValue.add(tempACE.dest_port+appendedValue) 1999 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.dest_port+" ",tempACE.dest_port+appendedValue+" ") 2000 | elif tempACE.dest_portIsO == True: 2001 | #DO SOMETHING, This might only matter before version 9 2002 | setOfRequiredObjectsAppendedValue.add(tempACE.dest_port+appendedValue) 2003 | tempACE.fullLine = tempACE.fullLine.replace(tempACE.dest_port+" ",tempACE.dest_port+appendedValue+" ") 2004 | fileAclNoMatchListAppended.write(tempACE.fullLine) 2005 | 2006 | outputFileReqObjectGroupCopyPasteAppended = outputDir+'ReqObjectGroupCopyPasteAppended.txt' 2007 | fileReqObjectGroupCopyPasteAppended = open(outputFileReqObjectGroupCopyPasteAppended,'w') 2008 | outputFileReqObjectGroupCopyPasteAppendedDebug = outputDir+'ReqObjectGroupCopyPasteAppendedDebug.txt' 2009 | fileReqObjectGroupCopyPasteAppendedDebug = open(outputFileReqObjectGroupCopyPasteAppendedDebug,'w') 2010 | #Copy the objects in the listOfObjectGroups2 to a new list where the Object Groups have the appended value 2011 | listOfObjectGroups2Appended = deepcopy(listOfObjectGroups2) 2012 | print "Count for listOfObjectGroups2Appended: ", len(listOfObjectGroups2Appended) 2013 | #For all required objects to merge in, append identifier 2014 | for x in listOfObjectGroups2Appended: 2015 | x.fullLine = x.fullLine.replace(x.name,x.name+appendedValue) 2016 | x.name = x.name+appendedValue 2017 | #print x.listOfObjectGroups 2018 | for i in range(0, len(x.listOfObjectGroups)): 2019 | x.listOfObjectGroups[i]=x.listOfObjectGroups[i]+appendedValue 2020 | 2021 | #for x in listOfObjectGroups2Appended: 2022 | # for y in x.listOfObjectGroups: 2023 | # y.name = y.name+appendedValue 2024 | #x is just a name, so we have to retrieive the object from the appended listOfObjectGroups2 2025 | allPrintedObjects = set() 2026 | for x in setOfRequiredObjectsAppendedValue: 2027 | if doDebugDump == True: 2028 | fileReqObjectGroupCopyPasteAppendedDebug.write("****Name of Object in Appended Require List= "+x+"\n") 2029 | printCopyAndPasteOfObject(x,listOfObjectGroups2Appended,allPrintedObjects,fileReqObjectGroupCopyPasteAppended,fileReqObjectGroupCopyPasteAppendedDebug,doDebugDump) 2030 | 2031 | 2032 | #Control stuff for text menu 2033 | if getFileFrom == 'rancidlist': 2034 | try: 2035 | svnRepo = configParser.get('SVNconfig','SVNrepo') 2036 | except: 2037 | print "Something bad happened when reading conf.ini SVNconfig Section. Just throwing my hands up" 2038 | #Get a SVN Client connection 2039 | client = pysvn.Client() 2040 | client.callback_ssl_server_trust_prompt = ssl_server_trust_prompt 2041 | #Get_login2 will pull the credentials for the conf.ini 2042 | client.callback_get_login = get_login2 2043 | print "Logged into SVN REPO" 2044 | #Read the config list and start looping 2045 | ###configListLinesStripped = [] 2046 | configListLines = configListFile.readlines() 2047 | ###strip newline characters and whitespace 2048 | lineSplit = [] 2049 | #hostList = [] 2050 | 2051 | #hostListType = [] 2052 | #for line in configListLines: 2053 | # lineSplit = line.split() 2054 | # hostList.append(lineSplit[0]) 2055 | # hostListType.append(lineSplit[1]) 2056 | #configListLinesStripped.append(line.strip()) 2057 | ###for line in configListLinesStripped: 2058 | print "----====Start Reading Through Device List====----" 2059 | for line in configListLines: 2060 | print "--Start Device" 2061 | lineSplit = line.split() 2062 | device = lineSplit[0] 2063 | deviceType = lineSplit[1] 2064 | print device + " " + deviceType 2065 | rev = pysvn.Revision(pysvn.opt_revision_kind.head) 2066 | info = client.info2(svnRepo+device,revision=rev,recurse=False) 2067 | revno = info[0][1].last_changed_rev.number 2068 | #revno = info[0][1].rev.number # revision number as an integer 2069 | print "lastChange Revision Number = " + str(revno) 2070 | deviceRepoRevisionNumber = revno 2071 | #Pull the device config into a temporary file for parsing 2072 | client.export(svnRepo+device, tempDir+"tempConfigFile"+device+".tmp") 2073 | tempConfigFile = tempDir+'tempConfigFile'+device+'.tmp' 2074 | inputFile = open(tempConfigFile,'r') 2075 | outputFile = outputDir+device+".txt" 2076 | outputFileLargeACLs = outputDir+device+'-output-LargeACLs.txt' 2077 | outputFileLargeACLsForCopyAndPaste = outputDir+device+'-output-LargeACLs-CopyPaste.txt' 2078 | outputFileDebugDump = outputDir+device+'-debugDump.txt' 2079 | outputFileLogging = logDir+'LogFile.txt' 2080 | options['deviceConfig'] = device 2081 | options['outputFile'] = outputFile 2082 | options['deviceRepoRevisionNumber'] = deviceRepoRevisionNumber 2083 | options['outputFileLargeACLs'] = outputFileLargeACLs 2084 | options['outputFileLargeACLsForCopyAndPaste'] = outputFileLargeACLsForCopyAndPaste 2085 | options['outputFileDebugDump'] = outputFileDebugDump 2086 | options['outputFileLogging'] = outputFileLogging 2087 | options['deviceType'] = deviceType 2088 | options['installedDir'] = installedDir 2089 | #options['logDir'] = logDir 2090 | #options['tempDir'] = tempDir 2091 | ParseMe(inputFile,options) 2092 | 2093 | main() 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | --------------------------------------------------------------------------------