How to configure PwmConfiguration.xml passwords programmatically

2,066 views
Skip to first unread message

Trevor Fuson

unread,
Jul 28, 2015, 12:07:01 PM7/28/15
to pwm-general
From my understanding of the PWM config file the passwords right now can only be set via the GUI. However this makes it difficult to deploy new docker nodes using PWM and passing the entire config via parameters.

Is there some method available via the CLI that I missed that could maybe do this?
Does anyone know the java class used to dump the password to the config file? It might be possible for us to write a small java program to use the library that writes out the password to give us back the hash.
Does anyone know where the key used to encrypt the config file passwords are stored? I can use this and they just do the encryption directly in the shell.

Thanks,

Trevor.

trosk...@gmail.com

unread,
Jul 28, 2015, 6:10:43 PM7/28/15
to pwm-general, trevor...@gmail.com
I dug into this for a bit. It appears to be AES encryption based on a key combining the creation time value within the PwmConfiguration.xml and the simple name of the stored configuration.

StoredConfiguration.java:

if (storedConfiguration.isDefaultValue(setting)) {
settingElement.addContent(new Element("default"));
} else {
final List<Element> valueElements;
if (setting.getSyntax() == PwmSettingSyntax.PASSWORD) {
final String key = PwmConstants.DEFAULT_DATETIME_FORMAT.format(storedConfiguration.createTime) + StoredConfiguration.class.getSimpleName();
valueElements = ((PasswordValue) storedConfiguration.settingMap.get(setting)).toXmlValues("value", key);
settingElement.addContent(new Comment("Note: This value is encrypted and can not be edited directly."));
settingElement.addContent(new Comment("Please use the Configuration Manager GUI to modify this value."));
} else {
valueElements = storedConfiguration.settingMap.get(setting).toXmlValues("value");
}
for (final Element loopValueElement : valueElements) {
settingElement.addContent(loopValueElement);
}
}

Since we have an automated play to deploy, I attempted to decrypt a known value using a static configuration file and an online AES decrypter without success (not sure if it was the simple name or the exact Z format of the creation timestamp that was to blame) . In the end, we created an ansible play to deploy pwm locally in configuration mode so that an admin can use the config UI to generate the password for the config pushed to formal environments.

I'll follow this as well to see if you get any interesting responses - but almost academic at this point for me.

HTH,
Trevor

Trevor Fuson

unread,
Jul 28, 2015, 6:16:24 PM7/28/15
to pwm-general, trosk...@gmail.com
Wow, thanks for sharing this information! I will play with it a bit to see if I am able to get any further. Right now I am in the same boat as you, I think that I will do a deploy minus the passwords which isn't as nice since there is a manual element to handle afterwards.

This really helps!

Trevor.

Trevor Roskewich

unread,
Jul 28, 2015, 6:22:20 PM7/28/15
to Trevor Fuson, pwm-general
No problem - we took the approach of generating the hash locally with the identical PwmConfiguration file, then taking the generated value and storing it in the ansible vault to populate the variable at deployment time in the particular env. So no manual monkeying around after the value is determined.

Good luck!

Jason Rivard

unread,
Aug 4, 2015, 2:35:57 PM8/4/15
to pwm-general, trevor...@gmail.com, trosk...@gmail.com
You can set the password values using plaintext like:

<value plaintext="true">plaintextPassword</value>

The password will then be encrypted the next time the config is saved.

Trevor Roskewich

unread,
Aug 5, 2015, 9:26:14 AM8/5/15
to Jason Rivard, pwm-general, Trevor Fuson
Thanks for the reply, Jason. The issue is that the configs in our case are pushed out via ansible plays, so modification/save via the configuration manager doesn’t apply.

I haven’t yet traced back what the value of StoredConfiguration.class.getSimpleName(); resolves to, but if you could provide some insight there that’d be great (we need a way for DevOps folks to generate encrypted values for secrets without need of a working pwm env in config mode).

Trevor Fuson

unread,
Aug 5, 2015, 11:42:05 AM8/5/15
to pwm-general, trevor...@gmail.com, trosk...@gmail.com
This is exactly what I need, thanks. Hopefully this works with version 1.7.1?

Trevor Fuson

unread,
Aug 5, 2015, 12:11:00 PM8/5/15
to pwm-general, jri...@gmail.com, trevor...@gmail.com, trosk...@gmail.com
We figured out how to generate the encrypted hashes by interfacing to the code directly using Java.


You need the following files from the latest pwm build:
commons-csv-1.1.jar
ldapchai-0.6.6-SNAPSHOT.jar
log4j-1.2.17.jar
pwm-servlet.jar

Compile with everything in the same directory
javac -cp "*" pwmtool.java
java -cp "*" pwmtool

java -cp "*" pwmtool test test
dSpPiyENQGDUXMKFMJPGWA==

The first parameter is the password, the second is your seed, you can extract the seed with something like this:
test=$(grep "<PwmConfiguration" PwmConfiguration.xml | sed 's/^.*createTime[^"]*"\([^"]*\)".*/\1StoredConfiguration/')

Sorry about all of the rough edges on this, but I won't be polishing it anymore because we will likely be going down the plaintext route.

For information on the method on encryption it uses a SHA1 of the seed, stores that in a java byte array and takes the first 16 bytes of that. Then it passes that key to do a AES128 encryption with no salt.
pwmtool.java

Trevor Roskewich

unread,
Aug 5, 2015, 12:14:46 PM8/5/15
to Trevor Fuson, pwm-general, jri...@gmail.com
Certainly is the approach we need to take … thank so much for sharing this! Will look to working/testing it out in our next sprint.

<pwmtool.java>

Jason Rivard

unread,
Aug 7, 2015, 12:46:50 PM8/7/15
to pwm-general, jri...@gmail.com, trevor...@gmail.com, trosk...@gmail.com
I guess I don't understand what your saying.  The suggestion I made above is a literal modification of the configuration XML file.  It will accept plain text passwords.  You do not need to use the configuration manager.  This method was added for exactly the same reason - deploying a configuration file without using the PWM codebase.

Reverse engineering the encryption is a really bad idea as the method has changed over time and will almost certainly be changed substantially in the near future.

Trevor Roskewich

unread,
Aug 7, 2015, 12:53:13 PM8/7/15
to Jason Rivard, pwm-general, trevor...@gmail.com
Hmm… well the issue is that the password appears to live in the configuration file as plain text until the config is saved again via the configuration manager, like you mentioned. Some environments may not permit storage of an admin-privileged account in a file in plain-text (or may have compliance issues with that) is all.

Jason Rivard

unread,
Aug 7, 2015, 2:14:27 PM8/7/15
to pwm-general, trevor...@gmail.com, trosk...@gmail.com
As I mentioned the password will become encrypted the next time it is saved by the app.  If that isn't soon enough you can set this config propery:

<properties type="config">
  <property key="saveConfigOnStart">true</property>
</properties>

(add this to the exiting properties type="config" element if one already exists).  

This will cause the file to be immediately saved once the app is started.  (note the property value will revert to false when it is saved)

Trevor Roskewich

unread,
Aug 7, 2015, 2:16:35 PM8/7/15
to Jason Rivard, pwm-general, trevor...@gmail.com
That’s the ticket… thanks Jason!

..and kudos for a great little app. It filled a technology gap for an access management product quite nicely. ;)

Trevor Fuson

unread,
Aug 7, 2015, 2:25:13 PM8/7/15
to pwm-general, trevor...@gmail.com, trosk...@gmail.com
This is great Jason!

I can't wait to use the new version when it is released, we have to use the java hack right now to get the passwords in the XML as our team decided to use 1.7.1.

Thanks for your help and foresight,

Trevor.

Trevor Roskewich

unread,
Aug 7, 2015, 2:51:48 PM8/7/15
to Trevor Fuson, pwm-general
Sorry - 1.7.1 for us as well, so I guess we’ll have to use the java util that Trevor has so graciously shared.

Jason Rivard

unread,
Aug 7, 2015, 2:53:44 PM8/7/15
to pwm-general, trevor...@gmail.com, trosk...@gmail.com
I doubt it.  1.7.1 is pretty ancient.


On Wednesday, August 5, 2015 at 11:42:05 AM UTC-4, Trevor Fuson wrote:

shaun...@gmail.com

unread,
Nov 5, 2019, 11:50:57 AM11/5/19
to pwm-general
Does <value plaintext="true"> apply in all cases? In particular to ldap.proxy.password. For other settings e.g. db.password changing to plaintext is explicitly mentioned in a comment block, but not that one.  On PWM 1.9.1 FWIW.

I'm not very familiar with PWM yet and I've been handed some non-working config to get working with Ansible. So currently trying to narrow settings to a known good (or at least "should work") set. And obviously I want to pull all the passwords etc out of a secrets store and deploy them using a template.

Sorry for old thread resurrection, but it seemed like a good idea to keep all the discussion in one place for anyone else who uses the search feature in future.

thanks

Jason Rivard

unread,
Nov 6, 2019, 2:53:41 PM11/6/19
to pwm-general
It should work for any setting with a password syntax of syntax="PASSWORD".

Andrii Malyi

unread,
Feb 22, 2024, 10:33:11 AMFeb 22
to pwm-general
Should it work with the https.server <key> also?
Reply all
Reply to author
Forward
0 new messages