Skip to content

Commit 5319a02

Browse files
committed
adding new discover passwords feature
1 parent 3b6492a commit 5319a02

File tree

19 files changed

+426
-144
lines changed

19 files changed

+426
-144
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ vulnerability disclosure process.
6565

6666
## License
6767

68-
Copyright (c) 2017, 2023, Oracle and/or its affiliates.
68+
Copyright (c) 2017, 2024, Oracle and/or its affiliates.
6969

7070
Released under the Universal Permissive License v1.0 as shown at
7171
<https://oss.oracle.com/licenses/upl/>.

core/src/main/python/discover.py

+61-4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@
8888
CommandLineArgUtil.ADMIN_PASS_ENV_SWITCH,
8989
CommandLineArgUtil.TARGET_MODE_SWITCH,
9090
CommandLineArgUtil.OUTPUT_DIR_SWITCH,
91+
CommandLineArgUtil.DISCOVER_PASSWORDS_SWITCH,
92+
CommandLineArgUtil.PASSPHRASE_SWITCH,
93+
CommandLineArgUtil.PASSPHRASE_ENV_SWITCH,
94+
CommandLineArgUtil.PASSPHRASE_FILE_SWITCH,
9195
CommandLineArgUtil.TARGET_SWITCH,
9296
CommandLineArgUtil.REMOTE_SWITCH,
9397
CommandLineArgUtil.SSH_HOST_SWITCH,
@@ -125,7 +129,9 @@ def __process_args(args):
125129
__process_java_home(argument_map)
126130
__process_domain_home(argument_map, __wlst_mode)
127131

128-
return model_context_helper.create_context(_program_name, argument_map)
132+
model_context = model_context_helper.create_context(_program_name, argument_map)
133+
__validate_discover_passwords_args(model_context, argument_map)
134+
return model_context
129135

130136

131137
def __process_model_arg(argument_map):
@@ -252,6 +258,50 @@ def __process_domain_home(arg_map, wlst_mode):
252258
full_path = cla_utils.validate_domain_home_arg(domain_home)
253259
arg_map[CommandLineArgUtil.DOMAIN_HOME_SWITCH] = full_path
254260

261+
262+
def __validate_discover_passwords_args(model_context, argument_map):
263+
_method_name = '__validate_discover_passwords_args'
264+
if model_context.is_discover_passwords():
265+
if model_context.is_remote():
266+
ex = exception_helper.create_cla_exception(ExitCode.ARG_VALIDATION_ERROR, 'WLSDPLY-06050',
267+
_program_name, CommandLineArgUtil.DISCOVER_PASSWORDS_SWITCH,
268+
CommandLineArgUtil.REMOTE_SWITCH)
269+
__logger.throwing(ex, class_name=_class_name, method_name=_method_name)
270+
raise ex
271+
if model_context.is_encrypt_discovered_passwords():
272+
if model_context.get_encryption_passphrase() is None:
273+
ex = exception_helper.create_cla_exception(ExitCode.ARG_VALIDATION_ERROR, 'WLSDPLY-06051',
274+
_program_name, CommandLineArgUtil.DISCOVER_PASSWORDS_SWITCH,
275+
CommandLineArgUtil.PASSPHRASE_ENV_SWITCH, CommandLineArgUtil.PASSPHRASE_FILE_SWITCH)
276+
__logger.throwing(ex, class_name=_class_name, method_name=_method_name)
277+
raise ex
278+
else:
279+
if model_context.get_encryption_passphrase() is not None:
280+
if CommandLineArgUtil.PASSPHRASE_ENV_SWITCH in argument_map:
281+
bad_arg = CommandLineArgUtil.PASSPHRASE_ENV_SWITCH
282+
elif CommandLineArgUtil.PASSPHRASE_FILE_SWITCH in argument_map:
283+
bad_arg = CommandLineArgUtil.PASSPHRASE_FILE_SWITCH
284+
else:
285+
bad_arg = CommandLineArgUtil.PASSPHRASE_SWITCH
286+
287+
ex = exception_helper.create_cla_exception(ExitCode.ARG_VALIDATION_ERROR, 'WLSDPLY-06052',
288+
_program_name, CommandLineArgUtil.DISCOVER_PASSWORDS_SWITCH, bad_arg)
289+
__logger.throwing(ex, class_name=_class_name, method_name=_method_name)
290+
raise ex
291+
else:
292+
if model_context.get_encryption_passphrase() is not None:
293+
if CommandLineArgUtil.PASSPHRASE_ENV_SWITCH in argument_map:
294+
bad_arg = CommandLineArgUtil.PASSPHRASE_ENV_SWITCH
295+
elif CommandLineArgUtil.PASSPHRASE_FILE_SWITCH in argument_map:
296+
bad_arg = CommandLineArgUtil.PASSPHRASE_FILE_SWITCH
297+
else:
298+
bad_arg = CommandLineArgUtil.PASSPHRASE_SWITCH
299+
300+
ex = exception_helper.create_cla_exception(ExitCode.ARG_VALIDATION_ERROR, 'WLSDPLY-06056',
301+
_program_name, bad_arg, CommandLineArgUtil.DISCOVER_PASSWORDS_SWITCH)
302+
__logger.throwing(ex, class_name=_class_name, method_name=_method_name)
303+
raise ex
304+
255305
def __discover(model_context, aliases, credential_injector, helper, extra_tokens):
256306
"""
257307
Populate the model from the domain.
@@ -636,12 +686,19 @@ def main(model_context):
636686
if _exit_code == ExitCode.OK:
637687
aliases = Aliases(model_context, wlst_mode=__wlst_mode, exception_type=ExceptionType.DISCOVER)
638688
credential_injector = None
689+
639690
if model_context.get_variable_file() is not None or model_context.get_target() is not None:
640691
credential_injector = CredentialInjector(_program_name, model_context, aliases)
641-
642-
__logger.info('WLSDPLY-06025', class_name=_class_name, method_name=_method_name)
692+
if model_context.is_discover_passwords():
693+
password_key = 'WLSDPLY-06055'
694+
else:
695+
password_key = 'WLSDPLY-06025'
643696
else:
644-
__logger.info('WLSDPLY-06024', class_name=_class_name, method_name=_method_name)
697+
if model_context.is_discover_passwords():
698+
password_key = 'WLSDPLY-06054'
699+
else:
700+
password_key = 'WLSDPLY-06024'
701+
__logger.info(password_key, class_name=_class_name, method_name=_method_name)
645702

646703
extra_tokens = {}
647704
try:

core/src/main/python/wlsdeploy/aliases/aliases.py

+55-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Copyright (c) 2017, 2024, Oracle and/or its affiliates.
33
Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
44
"""
5+
import array
6+
57
from java.lang import String
68
from oracle.weblogic.deploy.aliases import AliasException
79
from oracle.weblogic.deploy.aliases import TypeUtils
@@ -31,7 +33,6 @@
3133
from wlsdeploy.aliases.alias_constants import MERGE
3234
from wlsdeploy.aliases.alias_constants import MODEL_NAME
3335
from wlsdeploy.aliases.alias_constants import PASSWORD
34-
from wlsdeploy.aliases.alias_constants import PASSWORD_TOKEN
3536
from wlsdeploy.aliases.alias_constants import PREFERRED_MODEL_TYPE
3637
from wlsdeploy.aliases.alias_constants import PRODUCTION_DEFAULT
3738
from wlsdeploy.aliases.alias_constants import PROPERTIES
@@ -706,6 +707,51 @@ def get_wlst_access_ro_attribute_names(self, location):
706707
self._raise_exception(ae, _method_name, 'WLSDPLY-19046', location.get_current_model_folder(),
707708
location.get_folder_path(), ae.getLocalizedMessage())
708709

710+
def get_wlst_attribute_type(self, location, wlst_attribute_name):
711+
"""
712+
Get the wlst_type from the alias for the specified WLST attribute.
713+
:param location: model folder location
714+
:param wlst_attribute_name: WLST attribute name
715+
:return: the wlst_type from the alias entry or None if the attribute is not in the aliases
716+
"""
717+
_method_name = 'get_wlst_attribute_type'
718+
self._logger.entering(str_helper.to_string(location), wlst_attribute_name,
719+
class_name=self._class_name, method_name=_method_name)
720+
721+
result = None
722+
if wlst_attribute_name not in AliasEntries.IGNORE_FOR_MODEL_LIST:
723+
# WLST online has dual attributes for passwords of the form Foo and FooEncrypted.
724+
# Since the aliases don't include the Foo form, allow this method to return None
725+
# for the type, which indicates that the attribute was not found in the aliases.
726+
#
727+
module_folder = dict()
728+
try:
729+
module_folder = self._alias_entries.get_dictionary_for_location(location)
730+
except AliasException, ae:
731+
self._raise_exception(ae, _method_name, 'WLSDPLY-19046',
732+
location.get_current_model_folder(), location.get_folder_path(),
733+
ae.getLocalizedMessage())
734+
735+
if ATTRIBUTES not in module_folder:
736+
ex = exception_helper.create_alias_exception('WLSDPLY-08418', wlst_attribute_name,
737+
location.get_folder_path())
738+
self._logger.throwing(ex, class_name=self._class_name, method_name=_method_name)
739+
raise ex
740+
741+
for key, value in module_folder[ATTRIBUTES].iteritems():
742+
if WLST_NAME in value and value[WLST_NAME] == wlst_attribute_name:
743+
if WLST_TYPE in value:
744+
result = value[WLST_TYPE]
745+
else:
746+
ex = exception_helper.create_alias_exception('WLSDPLY-08419',location.get_folder_path(),
747+
wlst_attribute_name, WLST_TYPE)
748+
self._logger.throwing(ex, class_name=self._class_name, method_name=_method_name)
749+
raise ex
750+
break
751+
752+
self._logger.exiting(class_name=self._class_name, method_name=_method_name, result=result)
753+
return result
754+
709755
###########################################################################
710756
# Model folder-related methods #
711757
###########################################################################
@@ -1064,6 +1110,9 @@ def get_model_uses_path_tokens_attribute_names(self, location, only_readable=Fal
10641110
self._raise_exception(ae, _method_name, 'WLSDPLY-19030', location.get_current_model_folder(),
10651111
location.get_folder_path(), ae.getLocalizedMessage())
10661112

1113+
# Although the wlst_attribute_value may be a password field, logging it is probably OK since the password is
1114+
# encrypted, just like it is in config.xml.
1115+
#
10671116
def get_model_attribute_name_and_value(self, location, wlst_attribute_name, wlst_attribute_value):
10681117
"""
10691118
Returns the model attribute name and value for the specified WLST attribute name and value.
@@ -1114,10 +1163,14 @@ def get_model_attribute_name_and_value(self, location, wlst_attribute_name, wlst
11141163
default_value = alias_utils.replace_tokens_in_path(location, default_value)
11151164

11161165
if model_type == 'password':
1166+
# WDT doesn't really understand PyArray so convert it to a string before proceeding.
1167+
if isinstance(wlst_attribute_value, array.array):
1168+
wlst_attribute_value = wlst_attribute_value.tostring()
1169+
11171170
if string_utils.is_empty(wlst_attribute_value) or converted_value == default_value:
11181171
model_attribute_value = None
11191172
else:
1120-
model_attribute_value = PASSWORD_TOKEN
1173+
model_attribute_value = wlst_attribute_value
11211174

11221175
elif model_type == 'boolean':
11231176
# some boolean attributes have WLST value of null until they are set

core/src/main/python/wlsdeploy/tool/discover/common_resources_discoverer.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ def get_mail_sessions(self):
300300
mail_session_result = result[mail_session]
301301
location.add_name_token(name_token, mail_session)
302302
self._populate_model_parameters(mail_session_result, location)
303-
_fix_passwords_in_mail_session_properties(mail_session_result)
303+
self._fix_passwords_in_mail_session_properties(mail_session_result)
304304
location.remove_name_token(name_token)
305305

306306
_logger.exiting(class_name=_class_name, method_name=_method_name, result=model_top_folder_name)
@@ -605,18 +605,18 @@ def _get_named_resources(self, folder_name):
605605
_logger.exiting(class_name=_class_name, method_name=_method_name, result=model_top_folder_name)
606606
return model_top_folder_name, result
607607

608-
609-
def _fix_passwords_in_mail_session_properties(mail_session_dict):
610-
"""
611-
Look for password properties in the mail session properties string, and replace the password with a fix me token.
612-
:param mail_session_dict: containing the discovered mail session attributes
613-
"""
614-
match_pattern = r'mail\.\w*\.?password'
615-
if model_constants.MAIL_SESSION_PROPERTIES in mail_session_dict:
616-
# alias framework has converted properties to a dictionary by this point
617-
properties_dict = mail_session_dict[model_constants.MAIL_SESSION_PROPERTIES]
618-
for property_name in properties_dict:
619-
property_value = properties_dict[property_name]
620-
is_tokenized = property_value.startswith('@@')
621-
if StringUtils.matches(match_pattern, property_name) and not is_tokenized:
622-
properties_dict[property_name] = PASSWORD_TOKEN
608+
def _fix_passwords_in_mail_session_properties(self, mail_session_dict):
609+
"""
610+
Look for password properties in the mail session properties string, and replace the password with a fix me token.
611+
:param mail_session_dict: containing the discovered mail session attributes
612+
"""
613+
match_pattern = r'mail\.\w*\.?password'
614+
if model_constants.MAIL_SESSION_PROPERTIES in mail_session_dict and \
615+
not self._model_context.is_discover_passwords():
616+
# alias framework has converted properties to a dictionary by this point
617+
properties_dict = mail_session_dict[model_constants.MAIL_SESSION_PROPERTIES]
618+
for property_name in properties_dict:
619+
property_value = properties_dict[property_name]
620+
is_tokenized = property_value.startswith('@@')
621+
if StringUtils.matches(match_pattern, property_name) and not is_tokenized:
622+
properties_dict[property_name] = PASSWORD_TOKEN

0 commit comments

Comments
 (0)