Coverage for pyanaconda/core/regexes.py: 0%

# Coverage for pyanaconda/core/regexes.py : 0%

## 27 statements 0 run 27 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | # # regexes.py: anaconda regular expressions # # Copyright (C) 2013 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # import re # Validation expressions # The full name field can contain anything except a colon. # The empty string allowed. GECOS_VALID = re.compile(r'^[^:]*$') # Everyone has different ideas for what can go in a username. Here's ours: # POSIX recommends that user and group names use only the characters within # the portable filesystem character set (ASCII alnum plus dot, underscore, # and hyphen), with the additional restriction that names not start with a # hyphen. The Red Hat modification to shadow-utils starts with these rules # and additionally allows a final $, because Samba. It doesn't allow fully # numeric names or just "." or "..". # # shadow-utils also defines length limits for names: 32 for group names, # and UT_NAMESIZE for user names (which is defined as 32 bits/utmp.h). This # expression captures all of that: the initial character, followed by either # up to 30 portable characters and a dollar sign or up to 31 portable characters, # both for a maximum total of 32. The empty string is not allowed. PORTABLE_FS_CHARS = r'a-zA-Z0-9._-' _NAME_BASE = r'[a-zA-Z0-9._][' + PORTABLE_FS_CHARS + r']{0,30}([' + PORTABLE_FS_CHARS + r']|\$)?' # A regex for user and group names. NAME_VALID = re.compile(r'^' + _NAME_BASE + '$') # A comma-separated list of groups, validated as in NAME_VALID # Any number of spaces are allowed at the start and end of the list and # before and after the commas. The empty string is allowed. GROUPLIST_SIMPLE_VALID = re.compile(r'^\s*(' + _NAME_BASE + r'(\s*,\s*' + _NAME_BASE + r')*)?\s*$') # Parse the <gr-name> (<gid>) strings in the group list. # # The name match is non-greedy so that it doesn't match the whitespace betweeen # the name and ID. # # There's some non-capturing groups ("clusters" in the perlre parlance) thrown # in there, and, haha, wow, that's confusing to look at. There are two groups # that actually end up in the match object, and they're named to try to make # it a little easier: the first is "name", and the second is "gid". # # EVERY STRING IS MATCHED. This expression cannot be used for validation. # If there is no GID, or the GID contains non-digits, everything except # leading or trailing whitespace ends up in the name group. The result needs to # be validated with NAME_VALID. GROUPLIST_FANCY_PARSE = re.compile(r'^(?:\s*)(?P<name>.*?)\s*(?:\((?P<gid>\d+)\))?(?:\s*)$') # IPv4 address without anchors IPV4_PATTERN_WITHOUT_ANCHORS = r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' IPV4_PATTERN_WITH_ANCHORS = re.compile("^" + IPV4_PATTERN_WITHOUT_ANCHORS + "$") # IPv4 address or dhcp with anchors IPV4_OR_DHCP_PATTERN_WITH_ANCHORS = re.compile("^(?:" + IPV4_PATTERN_WITHOUT_ANCHORS + "|dhcp)$") # IPv6 address without anchors # Adapted from the IPv6address ABNF definition in RFC 3986, so it has all those # IPv4 compatibility bits too. All groups are non-capturing to make it easy to # use in an expression with groups and completely impossible to read IPV6_PATTERN_WITHOUT_ANCHORS = r'(?:' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){6})(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:::(?:(?:[0-9a-fA-F]{1,4}:){5})(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:(?:[0-9a-fA-F]{1,4})?::(?:(?:[0-9a-fA-F]{1,4}:){4})(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,1}(?:[0-9a-fA-F]{1,4}))?::(?:(?:[0-9a-fA-F]{1,4}:){3})(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,2}(?:[0-9a-fA-F]{1,4}))?::(?:(?:[0-9a-fA-F]{1,4}:){2})(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,3}(?:[0-9a-fA-F]{1,4}))?::(?:(?:[0-9a-fA-F]{1,4}:){1})(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,4}(?:[0-9a-fA-F]{1,4}))?::(?:(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')))|' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,5}(?:[0-9a-fA-F]{1,4}))?::(?:[0-9a-fA-F]{1,4}))|' + \ r'(?:(?:(?:[0-9a-fA-F]{1,4}:){,6}(?:[0-9a-fA-F]{1,4}))?::)' + \ r')' # IPv4 dotted-quad netmask validation IPV4_NETMASK_WITHOUT_ANCHORS = r'((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))' # IPv4 netmask with anchors IPV4_NETMASK_WITH_ANCHORS = re.compile("^" + IPV4_NETMASK_WITHOUT_ANCHORS + "$") # Hostname validation # A hostname consists of sections separated by periods. Each of these sections # must be between 1 and 63 characters, contain only alphanumeric characters or # hyphens, and may not start or end with a hyphen. The whole string cannot start # with a period, but it can end with one. # This regex uses negative lookahead and lookback assertions to enforce the # hyphen rules and make it way more confusing HOSTNAME_PATTERN_WITHOUT_ANCHORS = r'(?:(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*\.?)' # URL Hostname # This matches any hostname, IPv4 literal or properly encased IPv6 literal # This does not match the "IPvFuture" form because come the hell on URL_HOSTNAME_PATTERN_WITHOUT_ANCHORS = r'(?:' + IPV4_PATTERN_WITHOUT_ANCHORS + r')|(?:\[' + IPV6_PATTERN_WITHOUT_ANCHORS + r'])|(?:' + HOSTNAME_PATTERN_WITHOUT_ANCHORS + ')' # Matches the "scheme" defined by RFC 3986 URL_SCHEME_PATTERN_WITHOUT_ANCHORS = r'[A-Za-z][A-Za-z0-9+.-]*' # Matches any unreserved or percent-encoded character URL_NORMAL_CHAR = r'[A-Za-z0-9._~-]|(?:%[0-9A-Fa-f]{2})' # The above but also matches 'sub-delims' and :, @ and / URL_PATH_CHAR = URL_NORMAL_CHAR + "|[!$&'()*+,;=:@/]" # Parse a URL # Parses a URL of the form [protocol://][username[:password]@]host[:port][path][?query][#fragment] # into the following named groups: # 1: protocol (e.g., http://) # 2: username # 3: password # 4: host # 5: port # 6: path # 7: query # 8: fragment URL_PARSE = re.compile(r'^(?P<protocol>' + URL_SCHEME_PATTERN_WITHOUT_ANCHORS + r'://)?' + r'(?:(?P<username>(?:' + URL_NORMAL_CHAR + r')*)(?::(?P<password>(?:' + URL_NORMAL_CHAR + r')*))?@)?' + r'(?P<host>' + URL_HOSTNAME_PATTERN_WITHOUT_ANCHORS + ')' + r'(?::(?P<port>[0-9]+))?' + r'(?P<path>/(?:' + URL_PATH_CHAR + r')*)?' + r'(?:\?(?P<query>(?:' + URL_PATH_CHAR + r'|\?)*))?' + r'(?:#(?P<fragment>(?:' + URL_PATH_CHAR + r'|\?)*))?$') # Valid characters for repository names REPO_NAME_VALID = re.compile(r'^[a-zA-Z0-9_.:-]+$') # Product Version string, just the starting numbers like 21 or 21.1 VERSION_DIGITS = r'([\d.]+)' #Regexes to validate iSCSI Names according to RFC 3720 and RFC 3721 #The conditions for iSCSI name used in the following regexes are #(https://tools.ietf.org/html/rfc3720#section-3.2.6.3.1 , https://tools.ietf.org/html/rfc3721#page-5 and http://standards.ieee.org/regauth/oui/tutorials/EUI64.html): #1. For iqn format: # a. Starts with string 'iqn.' # b. A date code specifying the year and month in which the organization # registered the domain or sub-domain name used as the naming authority # string. "yyyy-mm" # c. A dot (".") # d. The organizational naming authority string, which consists of a # valid, reversed domain or subdomain name. # e. Optionally, a colon (":"), followed by a string of the assigning # organization's choosing, which must make each assigned iSCSI name # unique. With the exception of the colon prefix, the owner of the domain # name can assign everything after the reversed domain name as desired. ISCSI_IQN_NAME_REGEX = re.compile(r'^iqn\.\d{4}-\d{2}((?<!-)\.(?!-)[a-zA-Z0-9\-]+){1,63}(?<!-)(?<!\.)(:[^:]+)?$') #2. For eui format: # a. The format is "eui." followed by an EUI-64 identifier (16 ASCII-encoded hexadecimal digits). ISCSI_EUI_NAME_REGEX = re.compile(r'^eui\.[a-fA-F0-9]{16}$') # Device with this name was configured from ibft (and renamed) by dracut IBFT_CONFIGURED_DEVICE_NAME = re.compile(r'^ibft\d+$') # Regex to validate a DASD device number (full or partial). # # A DASD number has the format n.n.hhhh, where n is any decimal # digit and h any hexadecimal digit, e.g., 0.0.abcd, 0.0.002A. # # The partial form of the DASD number is missing hexadecimal digits, # e.g., 0.0.b, or missing a bus number, e.g., 0012. The minimal # partial number contains a single digit. For example a. DASD_DEVICE_NUMBER = re.compile(r'^(?:[0-9]\.[0-9]\.|\.|)[0-9A-Fa-f]{1,4}$') # Regex to validate the Logical Unit Number (LUN). # The LUN is a 16 digit hexadecimal value padded with zeroes to the right, # for example 0x4010403300000000. ZFCP_LUN_NUMBER = re.compile(r'^(?:0x|)[0-9A-Fa-f]{1,16}$') # Regex to validate the Worldwide Port Name (WWPN). # The WWPN is a 16 digit hexadecimal number prefixed with 0x, # for example 0x5005076303000104. ZFCP_WWPN_NUMBER = re.compile(r'^(?:0x|)[0-9A-Fa-f]{16}$')