Merge "Generate /etc/{passwd,group} for all partitions"
This commit is contained in:
@@ -2444,8 +2444,16 @@ $(2): \
|
|||||||
$(1) \
|
$(1) \
|
||||||
$(HOST_INIT_VERIFIER) \
|
$(HOST_INIT_VERIFIER) \
|
||||||
$(HIDL_INHERITANCE_HIERARCHY) \
|
$(HIDL_INHERITANCE_HIERARCHY) \
|
||||||
$(call intermediates-dir-for,ETC,passwd)/passwd
|
$(call intermediates-dir-for,ETC,passwd_system)/passwd_system \
|
||||||
$(hide) $(HOST_INIT_VERIFIER) -p $(call intermediates-dir-for,ETC,passwd)/passwd -i $(HIDL_INHERITANCE_HIERARCHY) $$<
|
$(call intermediates-dir-for,ETC,passwd_vendor)/passwd_vendor \
|
||||||
|
$(call intermediates-dir-for,ETC,passwd_odm)/passwd_odm \
|
||||||
|
$(call intermediates-dir-for,ETC,passwd_product)/passwd_product
|
||||||
|
$(hide) $(HOST_INIT_VERIFIER) \
|
||||||
|
-p $(call intermediates-dir-for,ETC,passwd_system)/passwd_system \
|
||||||
|
-p $(call intermediates-dir-for,ETC,passwd_vendor)/passwd_vendor \
|
||||||
|
-p $(call intermediates-dir-for,ETC,passwd_odm)/passwd_odm \
|
||||||
|
-p $(call intermediates-dir-for,ETC,passwd_product)/passwd_product \
|
||||||
|
-i $(HIDL_INHERITANCE_HIERARCHY) $$<
|
||||||
else
|
else
|
||||||
$(2): $(1)
|
$(2): $(1)
|
||||||
endif
|
endif
|
||||||
|
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
# Base modules and settings for the product partition.
|
# Base modules and settings for the product partition.
|
||||||
PRODUCT_PACKAGES += \
|
PRODUCT_PACKAGES += \
|
||||||
|
group_product \
|
||||||
healthd \
|
healthd \
|
||||||
ModuleMetadata \
|
ModuleMetadata \
|
||||||
|
passwd_product \
|
||||||
product_compatibility_matrix.xml \
|
product_compatibility_matrix.xml \
|
||||||
product_manifest.xml \
|
product_manifest.xml \
|
||||||
|
@@ -77,6 +77,7 @@ PRODUCT_PACKAGES += \
|
|||||||
fsck_msdos \
|
fsck_msdos \
|
||||||
fs_config_files_system \
|
fs_config_files_system \
|
||||||
fs_config_dirs_system \
|
fs_config_dirs_system \
|
||||||
|
group_system \
|
||||||
gsid \
|
gsid \
|
||||||
heapprofd \
|
heapprofd \
|
||||||
heapprofd_client \
|
heapprofd_client \
|
||||||
@@ -210,6 +211,7 @@ PRODUCT_PACKAGES += \
|
|||||||
NetworkStack \
|
NetworkStack \
|
||||||
org.apache.http.legacy \
|
org.apache.http.legacy \
|
||||||
otacerts \
|
otacerts \
|
||||||
|
passwd_system \
|
||||||
perfetto \
|
perfetto \
|
||||||
ping \
|
ping \
|
||||||
ping6 \
|
ping6 \
|
||||||
|
@@ -47,7 +47,8 @@ PRODUCT_PACKAGES += \
|
|||||||
fs_config_files_nonsystem \
|
fs_config_files_nonsystem \
|
||||||
fs_config_dirs_nonsystem \
|
fs_config_dirs_nonsystem \
|
||||||
gralloc.default \
|
gralloc.default \
|
||||||
group \
|
group_odm \
|
||||||
|
group_vendor \
|
||||||
init_vendor \
|
init_vendor \
|
||||||
libashmemd_hidl_client \
|
libashmemd_hidl_client \
|
||||||
libbundlewrapper \
|
libbundlewrapper \
|
||||||
@@ -62,7 +63,8 @@ PRODUCT_PACKAGES += \
|
|||||||
libreverbwrapper \
|
libreverbwrapper \
|
||||||
libril \
|
libril \
|
||||||
libvisualizer \
|
libvisualizer \
|
||||||
passwd \
|
passwd_odm \
|
||||||
|
passwd_vendor \
|
||||||
selinux_policy_nonsystem \
|
selinux_policy_nonsystem \
|
||||||
shell_and_utilities_vendor \
|
shell_and_utilities_vendor \
|
||||||
vndservice \
|
vndservice \
|
||||||
|
@@ -20,7 +20,7 @@ bootstrap_go_package {
|
|||||||
"soong-genrule",
|
"soong-genrule",
|
||||||
],
|
],
|
||||||
srcs: [
|
srcs: [
|
||||||
"fs_config.go"
|
"fs_config.go",
|
||||||
],
|
],
|
||||||
pluginFor: ["soong_build"],
|
pluginFor: ["soong_build"],
|
||||||
}
|
}
|
||||||
@@ -56,13 +56,13 @@ cc_library_headers {
|
|||||||
export_generated_headers: ["oemaids_header_gen"],
|
export_generated_headers: ["oemaids_header_gen"],
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the vendor/etc/passwd text file for the target
|
// Generate the */etc/passwd text files for the target
|
||||||
// This file may be empty if no AIDs are defined in
|
// These files may be empty if no AIDs are defined in
|
||||||
// TARGET_FS_CONFIG_GEN files.
|
// TARGET_FS_CONFIG_GEN files.
|
||||||
genrule {
|
genrule {
|
||||||
name: "passwd_gen",
|
name: "passwd_gen_system",
|
||||||
tool_files: ["fs_config_generator.py"],
|
tool_files: ["fs_config_generator.py"],
|
||||||
cmd: "$(location fs_config_generator.py) passwd --required-prefix=vendor_ --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
cmd: "$(location fs_config_generator.py) passwd --partition=system --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
srcs: [
|
srcs: [
|
||||||
":target_fs_config_gen",
|
":target_fs_config_gen",
|
||||||
":android_filesystem_config_header",
|
":android_filesystem_config_header",
|
||||||
@@ -71,18 +71,90 @@ genrule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prebuilt_etc {
|
prebuilt_etc {
|
||||||
name: "passwd",
|
name: "passwd_system",
|
||||||
vendor: true,
|
filename: "passwd",
|
||||||
src: ":passwd_gen",
|
src: ":passwd_gen_system",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the vendor/etc/group text file for the target
|
genrule {
|
||||||
// This file may be empty if no AIDs are defined in
|
name: "passwd_gen_vendor",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) passwd --partition=vendor --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["passwd"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "passwd_vendor",
|
||||||
|
filename: "passwd",
|
||||||
|
vendor: true,
|
||||||
|
src: ":passwd_gen_vendor",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "passwd_gen_odm",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) passwd --partition=odm --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["passwd"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "passwd_odm",
|
||||||
|
filename: "passwd",
|
||||||
|
device_specific: true,
|
||||||
|
src: ":passwd_gen_odm",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "passwd_gen_product",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) passwd --partition=product --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["passwd"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "passwd_product",
|
||||||
|
filename: "passwd",
|
||||||
|
product_specific: true,
|
||||||
|
src: ":passwd_gen_product",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "passwd_gen_system_ext",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) passwd --partition=system_ext --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["passwd"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "passwd_system_ext",
|
||||||
|
filename: "passwd",
|
||||||
|
system_ext_specific: true,
|
||||||
|
src: ":passwd_gen_system_ext",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the */etc/group text files for the target
|
||||||
|
// These files may be empty if no AIDs are defined in
|
||||||
// TARGET_FS_CONFIG_GEN files.
|
// TARGET_FS_CONFIG_GEN files.
|
||||||
genrule {
|
genrule {
|
||||||
name: "group_gen",
|
name: "group_gen_system",
|
||||||
tool_files: ["fs_config_generator.py"],
|
tool_files: ["fs_config_generator.py"],
|
||||||
cmd: "$(location fs_config_generator.py) group --required-prefix=vendor_ --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
cmd: "$(location fs_config_generator.py) group --partition=system --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
srcs: [
|
srcs: [
|
||||||
":target_fs_config_gen",
|
":target_fs_config_gen",
|
||||||
":android_filesystem_config_header",
|
":android_filesystem_config_header",
|
||||||
@@ -91,7 +163,79 @@ genrule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prebuilt_etc {
|
prebuilt_etc {
|
||||||
name: "group",
|
name: "group_system",
|
||||||
vendor: true,
|
filename: "group",
|
||||||
src: ":group_gen",
|
src: ":group_gen_system",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "group_gen_vendor",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) group --partition=vendor --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["group"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "group_vendor",
|
||||||
|
filename: "group",
|
||||||
|
vendor: true,
|
||||||
|
src: ":group_gen_vendor",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "group_gen_odm",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) group --partition=odm --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["group"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "group_odm",
|
||||||
|
filename: "group",
|
||||||
|
device_specific: true,
|
||||||
|
src: ":group_gen_odm",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "group_gen_product",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) group --partition=product --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["group"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "group_product",
|
||||||
|
filename: "group",
|
||||||
|
product_specific: true,
|
||||||
|
src: ":group_gen_product",
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "group_gen_system_ext",
|
||||||
|
tool_files: ["fs_config_generator.py"],
|
||||||
|
cmd: "$(location fs_config_generator.py) group --partition=system_ext --aid-header=$(location :android_filesystem_config_header) $(locations :target_fs_config_gen) >$(out)",
|
||||||
|
srcs: [
|
||||||
|
":target_fs_config_gen",
|
||||||
|
":android_filesystem_config_header",
|
||||||
|
],
|
||||||
|
out: ["group"],
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "group_system_ext",
|
||||||
|
filename: "group",
|
||||||
|
system_ext_specific: true,
|
||||||
|
src: ":group_gen_system_ext",
|
||||||
}
|
}
|
||||||
|
@@ -312,13 +312,12 @@ class AIDHeaderParser(object):
|
|||||||
re.compile(r'%sUSER' % AID.PREFIX)
|
re.compile(r'%sUSER' % AID.PREFIX)
|
||||||
]
|
]
|
||||||
_AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % AID.PREFIX)
|
_AID_DEFINE = re.compile(r'\s*#define\s+%s.*' % AID.PREFIX)
|
||||||
_OEM_START_KW = 'START'
|
_RESERVED_RANGE = re.compile(
|
||||||
_OEM_END_KW = 'END'
|
r'#define AID_(.+)_RESERVED_\d*_*(START|END)\s+(\d+)')
|
||||||
_OEM_RANGE = re.compile('%sOEM_RESERVED_[0-9]*_{0,1}(%s|%s)' %
|
|
||||||
(AID.PREFIX, _OEM_START_KW, _OEM_END_KW))
|
|
||||||
# AID lines cannot end with _START or _END, ie AID_FOO is OK
|
# AID lines cannot end with _START or _END, ie AID_FOO is OK
|
||||||
# but AID_FOO_START is skiped. Note that AID_FOOSTART is NOT skipped.
|
# but AID_FOO_START is skiped. Note that AID_FOOSTART is NOT skipped.
|
||||||
_AID_SKIP_RANGE = ['_' + _OEM_START_KW, '_' + _OEM_END_KW]
|
_AID_SKIP_RANGE = ['_START', '_END']
|
||||||
_COLLISION_OK = ['AID_APP', 'AID_APP_START', 'AID_USER', 'AID_USER_OFFSET']
|
_COLLISION_OK = ['AID_APP', 'AID_APP_START', 'AID_USER', 'AID_USER_OFFSET']
|
||||||
|
|
||||||
def __init__(self, aid_header):
|
def __init__(self, aid_header):
|
||||||
@@ -330,7 +329,7 @@ class AIDHeaderParser(object):
|
|||||||
self._aid_header = aid_header
|
self._aid_header = aid_header
|
||||||
self._aid_name_to_value = {}
|
self._aid_name_to_value = {}
|
||||||
self._aid_value_to_name = {}
|
self._aid_value_to_name = {}
|
||||||
self._oem_ranges = {}
|
self._ranges = {}
|
||||||
|
|
||||||
with open(aid_header) as open_file:
|
with open(aid_header) as open_file:
|
||||||
self._parse(open_file)
|
self._parse(open_file)
|
||||||
@@ -355,6 +354,23 @@ class AIDHeaderParser(object):
|
|||||||
return 'Error "{}" in file: "{}" on line: {}'.format(
|
return 'Error "{}" in file: "{}" on line: {}'.format(
|
||||||
msg, self._aid_header, str(lineno))
|
msg, self._aid_header, str(lineno))
|
||||||
|
|
||||||
|
range_match = self._RESERVED_RANGE.match(line)
|
||||||
|
if range_match:
|
||||||
|
partition = range_match.group(1).lower()
|
||||||
|
value = int(range_match.group(3), 0)
|
||||||
|
|
||||||
|
if partition == 'oem':
|
||||||
|
partition = 'vendor'
|
||||||
|
|
||||||
|
if partition in self._ranges:
|
||||||
|
if isinstance(self._ranges[partition][-1], int):
|
||||||
|
self._ranges[partition][-1] = (
|
||||||
|
self._ranges[partition][-1], value)
|
||||||
|
else:
|
||||||
|
self._ranges[partition].append(value)
|
||||||
|
else:
|
||||||
|
self._ranges[partition] = [value]
|
||||||
|
|
||||||
if AIDHeaderParser._AID_DEFINE.match(line):
|
if AIDHeaderParser._AID_DEFINE.match(line):
|
||||||
chunks = line.split()
|
chunks = line.split()
|
||||||
identifier = chunks[1]
|
identifier = chunks[1]
|
||||||
@@ -366,9 +382,7 @@ class AIDHeaderParser(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if AIDHeaderParser._is_oem_range(identifier):
|
if not any(
|
||||||
self._handle_oem_range(identifier, value)
|
|
||||||
elif not any(
|
|
||||||
identifier.endswith(x)
|
identifier.endswith(x)
|
||||||
for x in AIDHeaderParser._AID_SKIP_RANGE):
|
for x in AIDHeaderParser._AID_SKIP_RANGE):
|
||||||
self._handle_aid(identifier, value)
|
self._handle_aid(identifier, value)
|
||||||
@@ -404,67 +418,6 @@ class AIDHeaderParser(object):
|
|||||||
self._aid_name_to_value[aid.friendly] = aid
|
self._aid_name_to_value[aid.friendly] = aid
|
||||||
self._aid_value_to_name[value] = aid.friendly
|
self._aid_value_to_name[value] = aid.friendly
|
||||||
|
|
||||||
def _handle_oem_range(self, identifier, value):
|
|
||||||
"""Handle an OEM range C #define.
|
|
||||||
|
|
||||||
When encountering special AID defines, notably for the OEM ranges
|
|
||||||
this method handles sanity checking and adding them to the internal
|
|
||||||
maps. For internal use only.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
identifier (str): The name of the #define identifier.
|
|
||||||
ie AID_OEM_RESERVED_START/END.
|
|
||||||
value (str): The value associated with the identifier.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: With message set to indicate the error.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
int_value = int(value, 0)
|
|
||||||
except ValueError:
|
|
||||||
raise ValueError(
|
|
||||||
'Could not convert "%s" to integer value, got: "%s"' %
|
|
||||||
(identifier, value))
|
|
||||||
|
|
||||||
# convert AID_OEM_RESERVED_START or AID_OEM_RESERVED_<num>_START
|
|
||||||
# to AID_OEM_RESERVED or AID_OEM_RESERVED_<num>
|
|
||||||
is_start = identifier.endswith(AIDHeaderParser._OEM_START_KW)
|
|
||||||
|
|
||||||
if is_start:
|
|
||||||
tostrip = len(AIDHeaderParser._OEM_START_KW)
|
|
||||||
else:
|
|
||||||
tostrip = len(AIDHeaderParser._OEM_END_KW)
|
|
||||||
|
|
||||||
# ending _
|
|
||||||
tostrip = tostrip + 1
|
|
||||||
|
|
||||||
strip = identifier[:-tostrip]
|
|
||||||
if strip not in self._oem_ranges:
|
|
||||||
self._oem_ranges[strip] = []
|
|
||||||
|
|
||||||
if len(self._oem_ranges[strip]) > 2:
|
|
||||||
raise ValueError('Too many same OEM Ranges "%s"' % identifier)
|
|
||||||
|
|
||||||
if len(self._oem_ranges[strip]) == 1:
|
|
||||||
tmp = self._oem_ranges[strip][0]
|
|
||||||
|
|
||||||
if tmp == int_value:
|
|
||||||
raise ValueError('START and END values equal %u' % int_value)
|
|
||||||
elif is_start and tmp < int_value:
|
|
||||||
raise ValueError(
|
|
||||||
'END value %u less than START value %u' % (tmp, int_value))
|
|
||||||
elif not is_start and tmp > int_value:
|
|
||||||
raise ValueError(
|
|
||||||
'END value %u less than START value %u' % (int_value, tmp))
|
|
||||||
|
|
||||||
# Add START values to the head of the list and END values at the end.
|
|
||||||
# Thus, the list is ordered with index 0 as START and index 1 as END.
|
|
||||||
if is_start:
|
|
||||||
self._oem_ranges[strip].insert(0, int_value)
|
|
||||||
else:
|
|
||||||
self._oem_ranges[strip].append(int_value)
|
|
||||||
|
|
||||||
def _process_and_check(self):
|
def _process_and_check(self):
|
||||||
"""Process, check and populate internal data structures.
|
"""Process, check and populate internal data structures.
|
||||||
|
|
||||||
@@ -475,36 +428,32 @@ class AIDHeaderParser(object):
|
|||||||
ValueError: With the message set to indicate the specific error.
|
ValueError: With the message set to indicate the specific error.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# tuplefy the lists since range() does not like them mutable.
|
|
||||||
self._oem_ranges = [
|
|
||||||
AIDHeaderParser._convert_lst_to_tup(k, v)
|
|
||||||
for k, v in self._oem_ranges.iteritems()
|
|
||||||
]
|
|
||||||
|
|
||||||
# Check for overlapping ranges
|
# Check for overlapping ranges
|
||||||
for i, range1 in enumerate(self._oem_ranges):
|
for ranges in self._ranges.values():
|
||||||
for range2 in self._oem_ranges[i + 1:]:
|
for i, range1 in enumerate(ranges):
|
||||||
if AIDHeaderParser._is_overlap(range1, range2):
|
for range2 in ranges[i + 1:]:
|
||||||
raise ValueError("Overlapping OEM Ranges found %s and %s" %
|
if AIDHeaderParser._is_overlap(range1, range2):
|
||||||
(str(range1), str(range2)))
|
raise ValueError(
|
||||||
|
"Overlapping OEM Ranges found %s and %s" %
|
||||||
|
(str(range1), str(range2)))
|
||||||
|
|
||||||
# No core AIDs should be within any oem range.
|
# No core AIDs should be within any oem range.
|
||||||
for aid in self._aid_value_to_name:
|
for aid in self._aid_value_to_name:
|
||||||
|
for ranges in self._ranges.values():
|
||||||
if Utils.in_any_range(aid, self._oem_ranges):
|
if Utils.in_any_range(aid, ranges):
|
||||||
name = self._aid_value_to_name[aid]
|
name = self._aid_value_to_name[aid]
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'AID "%s" value: %u within reserved OEM Range: "%s"' %
|
'AID "%s" value: %u within reserved OEM Range: "%s"' %
|
||||||
(name, aid, str(self._oem_ranges)))
|
(name, aid, str(ranges)))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def oem_ranges(self):
|
def ranges(self):
|
||||||
"""Retrieves the OEM closed ranges as a list of tuples.
|
"""Retrieves the OEM closed ranges as a list of tuples.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A list of closed range tuples: [ (0, 42), (50, 105) ... ]
|
A list of closed range tuples: [ (0, 42), (50, 105) ... ]
|
||||||
"""
|
"""
|
||||||
return self._oem_ranges
|
return self._ranges
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def aids(self):
|
def aids(self):
|
||||||
@@ -515,39 +464,6 @@ class AIDHeaderParser(object):
|
|||||||
"""
|
"""
|
||||||
return self._aid_name_to_value.values()
|
return self._aid_name_to_value.values()
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _convert_lst_to_tup(name, lst):
|
|
||||||
"""Converts a mutable list to a non-mutable tuple.
|
|
||||||
|
|
||||||
Used ONLY for ranges and thus enforces a length of 2.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
lst (List): list that should be "tuplefied".
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError if lst is not a list or len is not 2.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple(lst)
|
|
||||||
"""
|
|
||||||
if not lst or len(lst) != 2:
|
|
||||||
raise ValueError('Mismatched range for "%s"' % name)
|
|
||||||
|
|
||||||
return tuple(lst)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _is_oem_range(aid):
|
|
||||||
"""Detects if a given aid is within the reserved OEM range.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
aid (int): The aid to test
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if it is within the range, False otherwise.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return AIDHeaderParser._OEM_RANGE.match(aid)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_overlap(range_a, range_b):
|
def _is_overlap(range_a, range_b):
|
||||||
"""Calculates the overlap of two range tuples.
|
"""Calculates the overlap of two range tuples.
|
||||||
@@ -588,12 +504,12 @@ class FSConfigFileParser(object):
|
|||||||
_SECTIONS = [('_handle_aid', ('value', )),
|
_SECTIONS = [('_handle_aid', ('value', )),
|
||||||
('_handle_path', ('mode', 'user', 'group', 'caps'))]
|
('_handle_path', ('mode', 'user', 'group', 'caps'))]
|
||||||
|
|
||||||
def __init__(self, config_files, oem_ranges):
|
def __init__(self, config_files, ranges):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
config_files ([str]): The list of config.fs files to parse.
|
config_files ([str]): The list of config.fs files to parse.
|
||||||
Note the filename is not important.
|
Note the filename is not important.
|
||||||
oem_ranges ([(),()]): range tuples indicating reserved OEM ranges.
|
ranges ({str,[()]): Dictionary of partitions and a list of tuples that correspond to their ranges
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._files = []
|
self._files = []
|
||||||
@@ -604,7 +520,7 @@ class FSConfigFileParser(object):
|
|||||||
# (name to file, value to aid)
|
# (name to file, value to aid)
|
||||||
self._seen_aids = ({}, {})
|
self._seen_aids = ({}, {})
|
||||||
|
|
||||||
self._oem_ranges = oem_ranges
|
self._ranges = ranges
|
||||||
|
|
||||||
self._config_files = config_files
|
self._config_files = config_files
|
||||||
|
|
||||||
@@ -669,6 +585,27 @@ class FSConfigFileParser(object):
|
|||||||
# within the generated file.
|
# within the generated file.
|
||||||
self._aids.sort(key=lambda item: item.normalized_value)
|
self._aids.sort(key=lambda item: item.normalized_value)
|
||||||
|
|
||||||
|
def _verify_valid_range(self, aid):
|
||||||
|
"""Verified an AID entry is in a valid range"""
|
||||||
|
|
||||||
|
ranges = None
|
||||||
|
|
||||||
|
partitions = self._ranges.keys()
|
||||||
|
partitions.sort(key=len, reverse=True)
|
||||||
|
for partition in partitions:
|
||||||
|
if aid.friendly.startswith(partition):
|
||||||
|
ranges = self._ranges[partition]
|
||||||
|
break
|
||||||
|
|
||||||
|
if ranges is None:
|
||||||
|
sys.exit('AID "%s" must be prefixed with a partition name' %
|
||||||
|
aid.friendly)
|
||||||
|
|
||||||
|
if not Utils.in_any_range(int(aid.value, 0), ranges):
|
||||||
|
emsg = '"value" for aid "%s" not in valid range %s, got: %s'
|
||||||
|
emsg = emsg % (aid.friendly, str(ranges), aid.value)
|
||||||
|
sys.exit(emsg)
|
||||||
|
|
||||||
def _handle_aid(self, file_name, section_name, config):
|
def _handle_aid(self, file_name, section_name, config):
|
||||||
"""Verifies an AID entry and adds it to the aid list.
|
"""Verifies an AID entry and adds it to the aid list.
|
||||||
|
|
||||||
@@ -702,15 +639,11 @@ class FSConfigFileParser(object):
|
|||||||
sys.exit(error_message('Found specified but unset "value"'))
|
sys.exit(error_message('Found specified but unset "value"'))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
aid = AID(section_name, value, file_name, '/vendor/bin/sh')
|
aid = AID(section_name, value, file_name, '/bin/sh')
|
||||||
except ValueError as exception:
|
except ValueError as exception:
|
||||||
sys.exit(error_message(exception))
|
sys.exit(error_message(exception))
|
||||||
|
|
||||||
# Values must be within OEM range
|
self._verify_valid_range(aid)
|
||||||
if not Utils.in_any_range(int(aid.value, 0), self._oem_ranges):
|
|
||||||
emsg = '"value" not in valid range %s, got: %s'
|
|
||||||
emsg = emsg % (str(self._oem_ranges), value)
|
|
||||||
sys.exit(error_message(emsg))
|
|
||||||
|
|
||||||
# use the normalized int value in the dict and detect
|
# use the normalized int value in the dict and detect
|
||||||
# duplicate definitions of the same value
|
# duplicate definitions of the same value
|
||||||
@@ -1000,7 +933,7 @@ class FSConfigGen(BaseGenerator):
|
|||||||
args['capability_header'])
|
args['capability_header'])
|
||||||
self._base_parser = AIDHeaderParser(args['aid_header'])
|
self._base_parser = AIDHeaderParser(args['aid_header'])
|
||||||
self._oem_parser = FSConfigFileParser(args['fsconfig'],
|
self._oem_parser = FSConfigFileParser(args['fsconfig'],
|
||||||
self._base_parser.oem_ranges)
|
self._base_parser.ranges)
|
||||||
|
|
||||||
self._partition = args['partition']
|
self._partition = args['partition']
|
||||||
self._all_partitions = args['all_partitions']
|
self._all_partitions = args['all_partitions']
|
||||||
@@ -1265,7 +1198,7 @@ class OEMAidGen(BaseGenerator):
|
|||||||
|
|
||||||
hdr_parser = AIDHeaderParser(args['aid_header'])
|
hdr_parser = AIDHeaderParser(args['aid_header'])
|
||||||
|
|
||||||
parser = FSConfigFileParser(args['fsconfig'], hdr_parser.oem_ranges)
|
parser = FSConfigFileParser(args['fsconfig'], hdr_parser.ranges)
|
||||||
|
|
||||||
print OEMAidGen._GENERATED
|
print OEMAidGen._GENERATED
|
||||||
|
|
||||||
@@ -1313,17 +1246,19 @@ class PasswdGen(BaseGenerator):
|
|||||||
'to parse AIDs and OEM Ranges from')
|
'to parse AIDs and OEM Ranges from')
|
||||||
|
|
||||||
opt_group.add_argument(
|
opt_group.add_argument(
|
||||||
'--required-prefix',
|
'--partition',
|
||||||
required=False,
|
required=True,
|
||||||
help='A prefix that the names are required to contain.')
|
help=
|
||||||
|
'Filter the input file and only output entries for the given partition.'
|
||||||
|
)
|
||||||
|
|
||||||
def __call__(self, args):
|
def __call__(self, args):
|
||||||
|
|
||||||
hdr_parser = AIDHeaderParser(args['aid_header'])
|
hdr_parser = AIDHeaderParser(args['aid_header'])
|
||||||
|
|
||||||
parser = FSConfigFileParser(args['fsconfig'], hdr_parser.oem_ranges)
|
parser = FSConfigFileParser(args['fsconfig'], hdr_parser.ranges)
|
||||||
|
|
||||||
required_prefix = args['required_prefix']
|
filter_partition = args['partition']
|
||||||
|
|
||||||
aids = parser.aids
|
aids = parser.aids
|
||||||
|
|
||||||
@@ -1331,13 +1266,22 @@ class PasswdGen(BaseGenerator):
|
|||||||
if not aids:
|
if not aids:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
aids_by_partition = {}
|
||||||
|
partitions = hdr_parser.ranges.keys()
|
||||||
|
partitions.sort(key=len, reverse=True)
|
||||||
|
|
||||||
for aid in aids:
|
for aid in aids:
|
||||||
if required_prefix is None or aid.friendly.startswith(
|
for partition in partitions:
|
||||||
required_prefix):
|
if aid.friendly.startswith(partition):
|
||||||
|
if partition in aids_by_partition:
|
||||||
|
aids_by_partition[partition].append(aid)
|
||||||
|
else:
|
||||||
|
aids_by_partition[partition] = [aid]
|
||||||
|
break
|
||||||
|
|
||||||
|
if filter_partition in aids_by_partition:
|
||||||
|
for aid in aids_by_partition[filter_partition]:
|
||||||
self._print_formatted_line(aid)
|
self._print_formatted_line(aid)
|
||||||
else:
|
|
||||||
sys.exit("%s: AID '%s' must start with '%s'" %
|
|
||||||
(args['fsconfig'], aid.friendly, required_prefix))
|
|
||||||
|
|
||||||
def _print_formatted_line(self, aid):
|
def _print_formatted_line(self, aid):
|
||||||
"""Prints the aid to stdout in the passwd format. Internal use only.
|
"""Prints the aid to stdout in the passwd format. Internal use only.
|
||||||
|
Reference in New Issue
Block a user