Quick and Easy Carrot Slaw

Ingredients:

  • 2 cups shredded carrots (about half a pound)
  • 2T Dijon mustard
  • 2T extra virgin olive oil
  • 1.5T red wine vinegar
  • 1t fresh orange zest (or 1/2 t Penzey’s Mural of Flavor)

Method:

  1. Combine the Dijon and vinegar, whisk to combine
  2. Slowly drizzle olive oil into mixture, whisking constantly
  3. Stir in zest or spice blend
  4. Stir in carrot shreds, making sure to coat the shreds evenly
  5. Cover in clingfilm and place in refrigerator to marinate for at least an hour
This recipe is a version of the Dijon carrot salad I ate during trips to Lyon and Geneva. It’s got a lot of Dijon, so you might want to start with half the amount and taste as you add more.

Powershell Credentials

I’ve only recently started using PowerShell to perform automated batch functions, and storing passwords in plain text is a huge problem. In other languages, I crypt the password with a string stored elsewhere, then use the elsewhere-stored string in conjunction with the cipher text to retrieve the password. There’s a really easy way to accomplish this in PowerShell (although it does not split the credential into two separate entities that force an attacker to obtain something from two places {i.e. reading a file on disk is good enough} but if they’re already reading my code and on my server … the attacker could easily repeat the algorithmic process of retrieving the other string … which is a long way to say the PowerShell approach may seem less secure; but, effectively, it isn’t much less secure)

The first step is to store the password into a file. Use “read-host -AsSecureString” to grab the password from user input, pipe that to convertfrom-securestring to turn it into a big ugly jumble of text, then pipe that out to a file

read-host -assecurestring | converfrom-securestring | out-file -filepath c:\temp\pass.txt

View the content of the file and you’ll see … a big long hex thing

Great, I’ve got a bunch of rubbish in a file. How do I use that in a script? Set a variable to the content of the file piped through convertto-securestring and then use that password to create a new PSCredential object

$strPassword = get-content -path c:\temp\pass.txt | convertto-securestring
$cred = new-object -typename PSCredential -argumentlist ‘UserID’,$strPassword

Voila, $cred is a credential that you can use in other commands.

New Git Server

I love GitLab, but it’s resource intensive and I wasn’t able to run it on the current hardware. Getting a new server has been a slow process, so I needed another solution. We use the Bonobo Git Server at work — it’s really simple and doesn’t provide all of the analysis and workflow functionality of GitLab (e.g. there are no pull requests!) … but it does keep revisions of code to which you can revert. And that’s better than trying to figure out what changed and broke a program. So I set one up at home.

Super simple — except they forget a few steps — like they don’t mean you need to install .NET 4.6. You need to go in the Add Roles & Features, under Application Development Features, and enable ASP.NET. 4.5 worked fine for me. You’ve also got to restart your IIS MMC if you left it running, and change the application pool over to one that actually uses ASP.NET.

Once that was installed, a few quick changes to web.config enabled AD-based authentication. And now we’ve got a git server at home that I can leave running 24×7.

Except … I tried using a new git server and got the following error:
schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) –
The revocation function was unable to check revocation for the certificate.

To resolve the issue, I needed to changed from Windows to OpenSSL certificate handling:
git config –global http.sslBackend openssl

Except that blew away my config line that defines the SSL CA CRT file. Once I restored my configuration … voila, I can use the git client with my new git server
git config –system http.sslcainfo “c:\Program Files\Git\mingw64\ssl\certs\ca-bundle.crt”

Sorting Grep Results When Log File Names Are Incremented Integers

While rotated log files can have a timestamp like YYYYMMDDHHmmss appended, a lot of log files are rotated with incremented integers (i.e. file.3 is removed, file.2 becomes file.3, file.1 becomes file.2, file becomes file.1, and file is a new file for current log ‘stuff’). We had some … challenges changing the log4j settings to use the timestamp format. When you grep all of the log files, the results are organized by alpha-sorted file names. Problem is that alpha sorted file names are 1, 10, 11, 12, …, 19, 2, 20, 21 … which doesn’t produce results in ascending or descending date order. You get:

zwave.log.1:2018-07-01 22:51:21.450 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 58: Node not awake!
zwave.log.1:2018-07-01 22:51:21.450 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 55: Node not awake!
zwave.log.11:2018-07-02 00:47:05.375 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 70: Node not awake!
zwave.log.11:2018-07-02 00:47:05.376 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 46: Node not awake!
zwave.log.12:2018-07-02 01:01:12.850 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 82: Node not awake!
zwave.log.13:2018-07-02 01:11:22.465 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 48: Node not awake!
zwave.log.13:2018-07-02 01:11:22.478 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 82: Node not awake!
zwave.log.13:2018-07-02 01:11:22.478 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 49: Node not awake!
zwave.log.14:2018-07-02 01:25:22.632 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 112: Node not awake!
zwave.log.14:2018-07-02 01:25:22.632 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 212: Node not awake!
zwave.log.15:2018-07-02 01:40:29.053 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 58: Node not awake!
zwave.log.15:2018-07-02 01:40:29.053 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 70: Node not awake!
zwave.log.16:2018-07-02 01:55:01.702 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 50: Node not awake!
zwave.log.16:2018-07-02 01:55:01.702 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 122: Node not awake!
zwave.log.17:2018-07-02 02:08:48.818 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 67: Node not awake!
zwave.log.17:2018-07-02 02:08:48.818 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 212: Node not awake!
zwave.log.18:2018-07-02 02:23:53.281 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 55: Node not awake!
zwave.log.18:2018-07-02 02:23:53.281 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 46: Node not awake!
zwave.log.19:2018-07-02 02:44:23.567 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 48: Node not awake!
zwave.log.19:2018-07-02 02:44:23.567 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 86: Node not awake!
zwave.log.19:2018-07-02 02:44:23.567 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 50: Node not awake!
zwave.log.2:2018-07-01 23:03:36.704 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 57: Node not awake!
zwave.log.2:2018-07-01 23:03:36.704 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 64: Node not awake!
zwave.log.2:2018-07-01 23:03:36.704 [DEBUG] [ng.zwave.internal.protocol.ZWaveTransactionManager] – NODE 68: Node not awake!

So I put together a quick sequence of commands that will produce results sorted by date. This process strips off the file names (I could create a more complex command set to shuffle the file name off to the end, but I didn’t need the file name. I just needed to scroll through the times at which an event occurred).

grep “Node not awake” zwave.log* | sed -r ‘s/^zwave.log.*:2018/2018/’ | sort

The grep results are piped to sed to have the file name prefix removed. The subsequent results are then piped to sort to be, well, sorted.

Gathering Info For Oracle – Oracle Unified Directory

I’ve been opening a lot of tickets for Oracle Unified Directory bugs recently. To save time gathering, I put together a quick script that gathers the data for an initial ticket. It depends on having a $PKGDIRECTORY environment variable set to the installation directory, and the data is stashed in a gzip’d tar file in the /tmp directory.

Script:

$PKGDIRECTORY/Middleware/asinst_1/OUD/bin/start-ds -s > /tmp/${HOSTNAME%%.*}-startds.txt
$PKGDIRECTORY/Middleware/asinst_1/OUD/bin/status -D “cn=directory manager” -j ~/pwd.txt > /tmp/${HOSTNAME%%.*}-status.txt

tar -cvzf /tmp/${HOSTNAME%%.*}.tgz /tmp/${HOSTNAME%%.*}-startds.txt /tmp/${HOSTNAME%%.*}-status.txt $PKGDIRECTORY/Middleware/asinst_1/OUD/logs/access $PKGDIRECTORY/Middleware/asinst_1/OUD/logs/admin $PKGDIRECTORY/Middleware/asinst_1/OUD/logs/errors $PKGDIRECTORY/Middleware/asinst_1/OUD/logs/replication $PKGDIRECTORY/Middleware/asinst_1/OUD/logs/server.out
chmod o+r /tmp/${HOSTNAME%%.*}.tgz

Updating Oracle Unified Directory (OUD) SSL Certificate

# PRE-CHANGE VERIFICATION
# There are two environment variables set to allow this to work:
# WLSTOREPASS=Wh@t3v3rY0uU53d # WLSTOREPASS is set to whatever is used for the keystore and truststore password
# OUDINST=/path/to/OUD/installation (root into which both java and OUD were installed — if you are using an OS package
# for java, your paths will be different)
# Log into OUD web management GUI (https://hostname.domain.gTLD:7002/odsm) and verify for each server:
# Configuration=>General Configuration=>Connection Handlers=>LDAPS Connection handler: “Secure access properties” section, Key Manager Provider & Trust Manager Provider are JKS. Certificate name is short hostname
# Configuration=>General Configuration=>Kery Managers=>JKS: Path is /$OUDINST/Oracle/Middleware/<short hostname>.jks

# During Change, server can be online
# Use the web GUI to issue certificates from WIN-WEB-CA. Export each cert as a PFX with keystore password $WLSTOREPASS
# On each server, place the approprate PFX file named with the hostname (i.e. the cert for LDAPFrontEndAlias.domain.gTLD will be stored to HOST1 as host1.pfx but stored on HOST2 as host2.pfx) in /tmp/ssl
# Alternatively, issue one certificate with each hostname and the front end alias as SAN values and use a static filename for the PFX file
# Put the root & web CA base-64 public key in /tmp/ssl/ as well (named Win-Root-CA.b64.cer and Win-Web-CA.b64.cer)

### Import the chain for the private key certificate
$OUDINST/java/jdk/bin/keytool -import -v -trustcacerts -alias WIN-ROOT -file /tmp/ssl/Win-Root-CA.b64.cer -keystore /tmp/ssl/${HOSTNAME%%.*}.jks -keypass $WLSTOREPASS -storepass $WLSTOREPASS
$OUDINST/java/jdk/bin/keytool -import -v -trustcacerts -alias WIN-WEB -file /tmp/ssl/Win-Web-CA.b64.cer -keystore /tmp/ssl/${HOSTNAME%%.*}.jks -keypass $WLSTOREPASS -storepass $WLSTOREPASS

# get GUID for the private key in the PFX file
HOSTCERTALIAS=”$($OUDINST/java/jdk/bin/keytool -v -list -storetype pkcs12 -keystore /tmp/ssl/${HOSTNAME%%.*}.pfx –storepass $WLSTOREPASS | grep Alias | cut -d: -f2-)”

# Change the cert alias to be the short hostname
$OUDINST/java/jdk/bin/keytool -importkeystore -srckeystore /tmp/ssl/${HOSTNAME%%.*}.pfx -destkeystore /tmp/ssl/${HOSTNAME%%.*}.jks -srcstoretype pkcs12 -deststoretype JKS -alias $HOSTCERTALIAS -storepass $WLSTOREPASS -srcstorepass $WLSTOREPASS
$OUDINST/java/jdk/bin/keytool -changealias -alias $HOSTCERTALIAS -destalias ${HOSTNAME%%.*} -keypass $WLSTOREPASS -keystore /tmp/ssl/${HOSTNAME%%.*}.jks -storepass $WLSTOREPASS

# Verify you have a WIN-ROOT, WIN-WEB, and hostname record
$OUDINST/java/jdk/bin/keytool -v -list -keystore /tmp/ssl/${HOSTNAME%%.*}.jks –storepass $WLSTOREPASS | grep Alias

# STOP THE LDAP SERVER AT THIS POINT
# Back up the current Java keystore file and move the new one into place
CURRENTDATE=”$(date +%Y%m%d)”
mv $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks $OUDINST/Oracle/Middleware/$CURRENTDATE.jks

cp $OUDINST/Oracle/Middleware/asinst_1/OUD/config/truststore $OUDINST/Oracle/Middleware/asinst_1/OUD/config/truststore-$CURRENTDATE
$OUDINST/java/jdk/bin/keytool -import -v -trustcacerts -alias WIN-ROOT -file /tmp/ssl/Win-Root-CA.b64.cer -keystore $OUDINST/Oracle/Middleware/asinst_1/OUD/config/truststore -keypass $WLSTOREPASS -storepass $WLSTOREPASS
$OUDINST/java/jdk/bin/keytool -import -v -trustcacerts -alias WIN-WEB -file /tmp/ssl/Win-Web-CA.b64.cer -keystore $OUDINST/Oracle/Middleware/asinst_1/OUD/config/truststore -keypass $WLSTOREPASS -storepass $WLSTOREPASS

mv /tmp/ssl/${HOSTNAME%%.*}.jks $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks

# START THE LDAP SERVER AND check for errors / test

# Backout:
# Stop the LDAP server
# mv $OUDINST/Oracle/Middleware/$CURRENTDATE.jks $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks
# mv $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks /tmp/ssl/${HOSTNAME%%.*}.jks
# Start the LDAP server

Updating Weblogic Certificate For OUD Management Utility

This is the process I use to update the WebLogic SSL certificate for our OUD management web interface. 


# PRE-CHANGE VERIFICATION
# There are two environment variables set to allow this to work:
WLSTOREPASS=Wh@t3v3rY0uU53d # WLSTOREPASS is set to whatever is used for the keystore and truststore password
# OUDINST=/path/to/OUD/installation (root into which both java and OUD were installed — if you are using an OS package
# for java, your paths will be different)
#Log into https://hostname.domain.gTLD:7002/console (or whatever your WL console URL is)
# As my WebLogic instance auths users via LDAP, I log in with my UID & pwd … you may have a generic account like ‘admin’
#
#Navigate to Domain Structure => Environment => Servers
#Select “AdminServer”
#
#Keystores tab — will tell you the name of the keystore and trust store
#SSL tab — will tell you the friendly name of the certificate
# Verify the keystore and truststore are $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks,
# Verify the friendly name of the certificate is the short hostname
#
# Verify the keystore is using the normal keystore password
#[ldap@dell115 ~]$ $OUDINST/java/jdk/bin/keytool -v -list -keystore $OUDINST/Oracle/Middleware/dell115.jks –storepass $WLSTOREPASS| grep Alias
#Alias name: dell115
#Alias name: win-we
#Alias name: win-root
#Alias name: winca1-root
#Alias name: winca1-issuing
# *** If you do not get any output, remove the ” | grep Alias” part and check for errors. “keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect” means the password is different.
# *** either try to guess the password (company name or ‘a’ are good guesses, along with the java-typical default of changeit)
# *** to continue using the existing password or you’ll need to update the keystore and truststore passwords in the web GUI.
# *** Since the keystores are generated using the process below … 99% of the time, the password matches.
#
# Generate a cert with appropriate info, export public/private key as a PFX file named with the short hostname of the server (i.e. dell115.pfx here) and, as the keystore password, use whatever you’ve set in $WLSTOREPASS

 # DURING THE CHANGE, as the ldap service account on the server:

mkdir /tmp/ssl

# Put base 64 public keys for our root and web CA in /tmp/ssl as Win-Root-CA.b64.cer and Win-Web-CA.b64.cer
# Put public/private key export from above in /tmp/ssl 

# Import the keychain for your certificate
$OUDINST/java/jdk/bin/keytool -import -v -trustcacerts -alias WIN-ROOT -file /tmp/ssl/Win-Root-CA.b64.cer -keystore /tmp/ssl/${HOSTNAME%%.*}.jks -keypass $WLSTOREPASS -storepass $WLSTOREPASS

$OUDINST/java/jdk/bin/keytool -import -v -trustcacerts -alias WIN-WEB -file /tmp/ssl/Win-Web-CA.b64.cer -keystore /tmp/ssl/${HOSTNAME%%.*}.jks -keypass $WLSTOREPASS -storepass $WLSTOREPASS 

# get GUID for cert within PFX file
HOSTCERTALIAS=”$($OUDINST/java/jdk/bin/keytool -v -list -storetype pkcs12 -keystore /tmp/ssl/${HOSTNAME%%.*}.pfx –storepass $WLSTOREPASS | grep Alias | cut -d: -f2-)” 

# Import the private key
$OUDINST/java/jdk/bin/keytool -importkeystore -srckeystore /tmp/ssl/${HOSTNAME%%.*}.pfx -destkeystore /tmp/ssl/${HOSTNAME%%.*}.jks -srcstoretype pkcs12 -deststoretype JKS -alias $HOSTCERTALIAS -storepass $WLSTOREPASS -srcstorepass Ra1n1ng1

# Change the alias to match what is configured in the web GUI
$OUDINST/java/jdk/bin/keytool -changealias -alias $HOSTCERTALIAS -destalias ${HOSTNAME%%.*} -keypass $WLSTOREPASS-keystore /tmp/ssl/${HOSTNAME%%.*}.jks -storepass $WLSTOREPASS
 

# Verify you have a WIN-ROOT, WIN-WEB, and hostname record

$OUDINST/java/jdk/bin/keytool -v -list -keystore /tmp/ssl/${HOSTNAME%%.*}.jks –storepass $WLSTOREPASS | grep Alias

# Stop the weblogic server

# Back up current keystore file and move new one into place
CURRENTDATE=”$(date +%Y%m%d)”
mv $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks $OUDINST/Oracle/Middleware/$CURRENTDATE.jks
cp /tmp/ssl/${HOSTNAME%%.*}.jks $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks

# Start the weblogic server in the screen session, then disconnect from the screen session

# Assuming success
rm -rf /tmp/ssl

# Backout is
# stop weblogic
mv $OUDINST/Oracle/Middleware/$CURRENTDATE.jks  $OUDINST/Oracle/Middleware/${HOSTNAME%%.*}.jks
# start weblogic

Fixing The Problems You Create

I’ve thought of Trump’s EO on child separation like a fireman torching buildings and “saving” people from the inferno. But his actions are more like throwing the person a dodgy life preserver he knows was recalled a few years back and calling himself a hero as soon as the person touches the thing. Anyone bother dragging the dude to safety? Anyone care that the preserver takes on water and sinks ten seconds later? Nope – I threw the thing, so I saved the guy.

The Obama admin took the “family detention center” approach to the issue. Flores v Lynch 212 F.Supp.3d 907 (2015) found that this violated the 1997 Flores Agreement *and* ordered the release of (I’m too lazy to look up how many) both detained children and their parents. Flores v. Lynch, 828 F.3d 898 (2016) determined that the *parents* did not have an affirmative right of release under the agreement … and what do you do if you are legally barred from holding the kids but *could* hold the parents. You either separate families or release both parents and children.

So Trump signs an EO saying to take measures consistent with the law to avoid separating families. What’s that fix? Either they do what they are doing today (and cite Flores v. Lynch as REQUIRING they separate families because the kids are not actually being detained but rather waiting for accommodations whilst their parents are detained during their transit of the legal system) or they go the family detention center route & pretend like they’re trying to convince some judge how this is materially different than when Obama did it.

We’re 3D Printing!

There are things that are evidently too self-evident to bear mentioning — I’m certain I do it too. A friend of mine who taught computer programming used the example of telling a student how to get to the Bursar’s office v/s writing computer code to do it. You don’t have to tell the person to leave the room, go down the hall, down the stairs, and outside. There’s a lot of instruction humans will infer. A computer, on the other hand, will be completely stymied if you omit a few steps.

Well, 3D printing seems to be loaded with so-obvious-I-won’t-mention-it stuff. A lot of getting started guides and troubleshooting guides are out there in Internet-land — level the bed at the temp you’ll be printing, temperature guides for different materials, how to identify leveling or flow problems in prints. But to get started … there are a few vital pieces of info that seem to fall into the “so obvious it isn’t worth mentioning” category.

Loading the WanHao Duplicator i3 Plus / Monoprice Maker Select IIIp v2, you have to depress the little lever to load filament. Also — even though you’ve got a brand new 3D printer, they’ve run a test print on it. Nice way to confirm everything works … but it also means that brand new device you just pulled out of the box … has a clogged nozzle and needs to be cleaned.

Filament doesn’t start flowing perfectly immediately — add a couple lines of ‘skirt’ to your print. It does nothing to prevent warping or increase bed adhesion, but it makes a small loop that you don’t subsequently need to detach from your printout. If there are a couple of blobs before the extruder really gets going on that little loop? No big.

With three leveling screws, you are never going to get it perfect. Each little tweak throws all the others out of whack (three points define a plane, four over-define it). Get the bed level to the point you’re making little teeny tiny adjustments and you’re good.

And in Cura – all of the good settings you need to tweak up to get adhesion (primarily temperatures, speed, and initial layer height) are hidden. The “Print Setup” section defaults to “Recommended”. Click “Custom” and you’ll see settings for all of the stuff people recommend to sort poor adhesion, poor print quality, etc.

 

And some gcode to wipe off the extruder tip before printing because I want to be able to find it again:

M107 ;turn off fan
G28 X0 Y0 Z0 ; home X, Y and Z axis end-stops
G29 ; initiate z-probing
G0 X0 Y0 F9000 ; Go to front
G0 Z0.15 ; Drop to bed
G92 E0 ; zero the extruded length
G1 X40 E25 F500 ; Extrude 25mm of filament in a 4cm line
G92 E0 ; zero the extruded length
G1 E-1 F500 ; Retract a little
G1 X80 F4000 ; Quickly wipe away from the filament line
G1 Z0.3 ; Raise and begin printing.

Restaurants and Bakers

If you firmly believe a baker should be able to refuse to bake for same-sex weddings, how can you think a restaurant owner us wrong to eject the face of the Trump White House?

It’s not discrimination if you object to the specific actions of an individual – that’s an opinion. Were restaurants to wholesale refuse to provide service to anyone who works under the Executive Branch (hard to ascertain that subset of people, but pretend) that might be discrimination based on political affiliation. But if a baker’s free speech / religion rights permit refusing service to individuals who wish to marry someone of the same gender … how do free speech / religion rights not permit refusing service to Republicans as a whole?

The problem seems to be, again, people conflate the freedom from government enacted punishment with freedom from consequences. You have the right to assemble and spew whatever white supremacist rubbish you want. But you may find yourself fired. Or court marshaled. Or ostracized in your neighborhood.