繁体   English   中英

Python解析复杂文本

[英]Python parsing complex text

我正在努力开发一种可以编辑以下XML文件片段的算法。 有人可以提供意见吗? 要求是解析该文件作为输入,删除使用“ RC4”的“密码”,并输出一个新的xml文件,其中仅删除“ RC4”密码。 问题是XML文件中有多个“连接器”部分。 我需要阅读所有内容,但仅编辑使用端口443并具有特定IP地址的内容。 因此,该脚本需要一次解析每个Connector部分,但丢弃没有正确IP地址和端口的部分。 尝试过:1.使用ElementTree XML解析器。 问题是它不能很好地输出新的XLM文件-情况一团糟。 我需要使用python 2.6进行美化。

<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="443"
redirectPort="443"
executor="tomcatThreadPool"
disableUploadTimeout="true"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
keystoreType="JKS"
keystoreFile="tomcat.keystore"
keystorePass="XXXXX"
server="XXXX"
ciphers="TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
         TLS_DH_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
         TLS_DH_DSS_WITH_AES_128_CBC_SHA,
         TLS_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_RC4_128_SHA"
address="192.168.10.6">

这是我的代码:

from xml.etree import ElementTree
print "[+] Checking for removal of RC4 ciphers"
file = "template.xml"

with open(file, 'rt') as f:
    tree = ElementTree.parse(f)
f.close()

for node in tree.getiterator('Connector'):
    if node.tag == 'Connector':

        address = node.attrib.get('address')
        port = node.attrib.get('port')
        if "EMSNodeMgmtIp" in address and port == "443":
            ciphers = node.attrib.get('ciphers')
            if "RC4" in ciphers:
                # If true, RC4 is enabled somewhere in the cipher suite 
                print "[+] Found RC4 enabled ciphers"

                # Find RC4 specific cipher suite string, for replacement
                elements = ciphers.split()
                search_str = ""
                for element in elements:
                    if "RC4" in element:
                        search_str = element
                        print "[+] Search removal RC4 string: %s" % search_str

                # Replace string by removing RC4 cipher
                print "[+] Removing RC4 cipher"
                replace_str = ciphers.replace(search_str,"")
                rstrip_str = replace_str.rstrip()
                if rstrip_str.endswith(','):
                    new_cipher_str = rstrip_str[:-1]
                    #print new_cipher_str

            node.set('ciphers', new_cipher_str)
tree.write('new.xml')

我添加了评论以解释发生了什么。 inb4downvote

from lxml import etree
import re

xml = '''<?xml version="1.0"?>
<data>
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="443"
redirectPort="443"
executor="tomcatThreadPool"
disableUploadTimeout="true"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
keystoreType="JKS"
keystoreFile="tomcat.keystore"
keystorePass="XXXXX"
server="XXXX"
ciphers="TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
         TLS_DH_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
         TLS_DH_DSS_WITH_AES_128_CBC_SHA,
         TLS_RSA_WITH_AES_128_CBC_SHA,
         TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_3DES_EDE_CBC_SHA,
         TLS_RSA_WITH_RC4_128_SHA"
address="192.168.10.6"></Connector></data>'''

tree = etree.fromstring(xml)
root = tree.getroottree().getroot()
for connector in root.findall('Connector'):
    port = connector.get('port')
    ip = connector.get('address')
    #change this to port/ip you want to remove
    if port != '443' or ip != '192.168.10.6':
        #removes child connector
        connector.getparent().remove(connector)
        continue
    #here we use list comprehension to remove any cipher with "RC4"
    ciphers = ','.join([x for x in re.split(r',\s*', connector.get('ciphers')) if 'RC4' not in x])
    #set the modified cipher back
    connector.set('ciphers', ciphers)
print etree.tostring(root, pretty_print=True)

如果XML工具没有保留原始结构和格式,请转储它们。 这是一个简单的文本处理问题,您可以编写一个Python程序来处理它。

遍历文件的各行; 只需向输出回显除“ cipher”语句以外的任何内容。 当您击中其中之一时:

  1. 将字符串填充到变量中。
  2. 将字符串拆分为一个列表。
  3. 删除任何包含“ RC4 ”的列表元素。
  4. 以所需的格式打印结果“ cipher”语句。
  5. 返回到正常的“读取和回显”处理。

这个算法会让您顺利进行吗?

请在下面回答。 基本上必须将每个连接器部分(共有4个)读入一个临时列表,以检查端口和地址是否正确。 如果是这样,则仅在启用RC4密码的情况下,通过删除密码字符串来更改密码。 因此,该代码必须一次将所有4个连接器读取到一个临时列表中。

f = open('template.xml', 'r')
lines = f.readlines()
f.close()

new_file = open('new.xml', 'w')

tmp_list = []
connector = False
for line in lines:
    if '<Connector' in line:
        connector = True
        new_file.write(line)
    elif '</Connector>' in line:
        connector = False
        port = False
        address = False
        for a in tmp_list:
            if 'port="443"' in a:
                port = True
            elif 'address="%(EMSNodeMgmtIp)s"' in a:
                address = True
        if port and address:
            new_list = []
            count = 0
            for b in tmp_list:
                if "RC4" in b:
                    print "[+] Found RC4 cipher suite string at line index %d:  %s" % (count,b) 
                    print "[+] Removing RC4 cipher string from available cipher suites"
                    # check if RC4 cipher string ends with "
                    check = b[:-1]
                    if check.endswith('"'):
                        tmp_str = tmp_list[count-1]
                        tmp_str2 = tmp_str[:-2]
                        tmp_str2+='"\n'
                        new_list[count-1] = tmp_str2
                        replace_line = b.replace(b,"")
                        new_list.append(replace_line)
                    else:
                        replace_line = b.replace(b,"")
                        new_list.append(replace_line)
                else:
                    new_list.append(b)
                count+=1
            for c in new_list:
                new_file.write(c) 
            new_file.write('    </Connector>\n')
        else:
            # Not port and address
            for d in tmp_list:
                new_file.write(d)
            new_file.write('    </Connector>\n')
        tmp_list = []
    elif connector:
        tmp_list.append(line)
    else:
        new_file.write(line)
new_file.close()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM