Home

November 27, 2013

A Guide to Using SSO and LDAP with PeopleSoft

This post is a comprehensive guide to configuring an SSO solution with PeopleSoft. The SSO product I’m using is called Pubcookie; it is an open source system and is used at several universities today, including the University of Virginia and the University of Washington.

This guide does not assume any prerequisites other than a working PeopleSoft CS installation. Other posts on my site detail how to obtain such an installation. Two servers will be set up in the succeeding sections; although it does not matter where they are hosted, I used Amazon EC2, and there are several references to EC2-specific settings throughout. If you are not using EC2, it should be easy to translate or ignore those references based on your own requirements.

Pubcookie is used in a hierarchical fashion: there’s a central keyserver, along with one or more app servers that are authorized by the keyserver to verify login credentials for applications hosted on each app server. This guide will keep it simple: only one keyserver and only one app server. Later, when the LDAP server is set up, it will be installed on the Pubcookie keyserver to keep things simple; you will almost certainly want to install your LDAP server to a separate server instead, especially if you are setting up a production environment. Although the steps in this guide lead to a functional, fairly secure SSO/LDAP implementation for use with PeopleSoft, the resulting setup requires additional modifications before it should be considered for production use; such modifications are not covered here.

This guide also references the enterrupt.com domain and subdomains thereof. You will need to provide your own domain and decide on the subdomain naming scheme you wish to use; then, substitute your choices where appropriate.

Provisioning a Server for the Pubcookie Keyserver

  • Created a t1.micro instance on EC2; Ubuntu 12.04 LTS; 64-bit.
  • Assigned Elastic IP to instance: <elastic-ip-of-pubc-key-server>
  • Assigned <elastic-ip-of-pubc-key-server> to pubcookie.enterrupt.com in Route 53.
  • Using EC2 security group: PUBCOOKIE_SERVER. Ensure that inbound traffic on 22, 80, and 443 is allowed.
  • Logged into instance as UNIX user ubuntu.
  • sudo apt-get update
  • sudo apt-get upgrade
  • sudo -i
  • sudo passwd root; used <redacted> as password.
  • logout
  • su - root
  • groupadd entsso
  • useradd -G entsso -d /home/apache -m apache -s /bin/bash (creates the UNIX user apache, assigns to group entsso, uses /home/apache as the home directory, creates the directory if it doesn’t exist (-m flag), and uses bash for the user’s shell (-s flag)).
  • useradd -G entsso -d /home/pubcookie -m pubcookie -s /bin/bash
  • passwd apache; set password to <redacted>.
  • passwd ubuntu; set password to <redacted>.
  • /usr/sbin/visudo
    • Added %entsso  ALL=(ALL) ALL to end of file to give members of the entsso group ability to gain root privileges.
    • Wrote file to disk.
  • reboot

Installing Apache on the Provisioned Server

  • Pubcookie is served by the Apache web server. This section sets up Apache to listen on 443 for HTTPS requests for Pubcookie resources.
  • su - apache
  • sudo apt-get install apache2
  • sudo a2enmod ssl
  • sudo service apache2 restart
  • cd /var
  • chown -R apache:entsso www
  • mkdir www/pubcookie.enterrupt.com
  • cd /etc/apache2
  • sudo mkdir ssl
  • At this point, you need to bundle the private key, server certificate, and CA certificate chain into a zip file and upload it to the keyserver. On the keyserver, extract the contents of the zip file to /etc/apcache2/ssl (you may need to create the ssl directory if it doesn’t already exist). Also be sure to:
    • sudo chmod 600 /etc/apache2/ssl/* - ensure that only root read/write to files
    • sudo chmod 700 /etc/apache2/ssl - ensure that only root can access the directory.
  • su - ubuntu
  • sudo a2dissite default
  • sudo cp sites-available/default-ssl sites-available/pubcookie.enterrupt.com
  • sudo nano sites-available/pubcookie.enterrupt.com; added the following text:

/etc/apache2/sites-available/pubcookie.enterrupt.com

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerAdmin mquinn@enterrupt.com

        DocumentRoot /var/www/pubcookie.enterrupt.com
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/pubcookie.enterrupt.com>
                Options ExecCGI Indexes FollowSymLinks
                AllowOverride None
                Order allow,deny
                allow from all
                AddHandler cgi-script .cgi
                DirectoryIndex index.cgi index.html
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined

        SSLEngine on
        SSLCertificateFile    /etc/apache2/ssl/STAR_enterrupt_com.crt
        SSLCertificateKeyFile /etc/apache2/ssl/STAR_enterrupt_com.key
        SSLCertificateChainFile /etc/apache2/ssl/ca_bundle.txt
</VirtualHost>
</IfModule>


  • sudo a2ensite pubcookie.enterrupt.com
  • sudo service apache2 reload
  • Successfully viewed index page at https://pubcookie.enterrupt.com; green lock icon visible in URL bar.
  • At this point, I snapshotted the EBS volume backing this EC2 instance, because the Pubcookie app server will require the exact same setup covered in this section. The Pubcookie app server will be set up later on in this guide.

Installing and Configuring the Pubcookie Keyserver Software

  • On the EC2 security group PUBCOOKIE_SERVER, I added a rule to allow TCP traffic on port 2222 for the Pubcookie keyserver.
  • This section references the installation instructions here.
  • su - pubcookie
  • wget www.pubcookie.org/downloads/pubcookie-3.3.4a.tar.gz
  • unzip pubcookie-3.3.4a.tar.gz
  • tar -xvf pub*.gz
  • rm pub*.gz
  • cd pubcookie-3.3.4a
  • sudo apt-get install gcc ibssl-dev make
  • ./configure --enable-login --disable-apache
  • make
  • sudo make install
  • cd /usr/local/pubcookie/keys
  • sudo openssl req -new -x509 -out pubcookie_granting.cert -newkey rsa:1024 -nodes -keyout pubcookie_granting.key - this creates the granting key used to authorize Pubcookie app servers. The values below were provied to the openssl binary when prompted; you’ll need to replace these with your own values:
    • Country Code: US
    • State: VA
    • Locality: Charlottesville
    • Organization Name: Enterrupt
    • Left Organizational Unit Name blank.
    • Common Name: pubcookie.enterrupt.com
    • Email: <redacted>
  • cd ..
  • sudo nano config
    • Changed logging_level to 3.
    • Changed ssl_key_file to /etc/apache2/ssl/STAR_enterrupt_com.key
    • Changed ssl_cert_file to /etc/apache2/ssl/STAR_enterrupt_com.crt
    • Left values for granting_key_file and granting_cert_file as they were; they were already correct and pointing to the key/cert files generated in the previous step.
    • Changed login_uri to https://pubcookie.enterrupt.com/ (IMPORTANT: use the domain name that you plan to assign to the Pubcookie app server. If the server certificate that you are using is a wildcard cert, you will actually need to use a value here in the form of *.example.com - in a few steps I encountered an error that made me realize this).
    • Changed login_host to pubcookie.enterrupt.com (use the domain name that you have assigned to the Pubcookie keyserver).
    • Changed enterprise_domain to .enterrupt.com (replace with your domain, don’t forget the leading period).
    • Changed keymgt_uri to https://pubcookie.enterrupt.com:2222 (this is the address that the Pubcookie app server will use to contact the Pubcookie keyserver for authentication transactions).
    • Changed keyserver_client_list to pubcookie.enterrupt.com (we don’t have any other clients besides the keyserver itself at this time).
    • Changed ssl_ca_file to /etc/apache2/ssl/ca_bundle.txt
    • Wrote file to disk.
  • sudo apt-get install openbsd-inetd
  • sudo nano /etc/inetd.conf
    • Added this line to the end of the file: 2222    stream    tcp   nowait   root   /usr/local/pubcookie/keyserver keyserver
    • Wrote file to disk.
  • sudo service openbsd-inetd restart
  • sudo cp starter.key keys/pubcookie.enterrupt.com
  • sudo ./keyclient
  • Got the following error: “certificate presented isn’t the key server: *.enterrupt.com != pubcookie.enterrupt.com”
    • After finding this-page, I did the following:
      • sudo nano config
      • Changed login_host to *.enterrupt.com
      • Wrote file to disk
      • sudo service openbsd-inetd restart
      • sudo ./keyclient -H pubcookie.enterrupt.com
      • keyclient executed successfully this time.
  • Verified that /usr/local/pubcookie/keys/pubcookie.enterrupt.com changed from the default filler text of “key key key…” to a binary file now that keyclient has been run.
  • cd /usr/local/pubcookie
  • sudo cp -R login/* /var/www/pubcookie.enterrupt.com
  • cd /var/www/pubcookie.enterrupt.com
  • chown -R apache:entsso *
  • Opened https://pubcookie.enterrupt.com in browser; got message from pubcookie indicating that “Generic error has occurred.” I tailed /var/log/syslog (which is where pubcookie logs to) but there was nothing pubcookie-related there. I tested to see if level 3 logging was working as intended by issuing logger -p local3.error "Test error MJQ."; it appeared at the end of /var/log/syslog, so I did some Internet research.
    • Found:  http://mailman2.u.washington.edu/pipermail/pubcookie-users/2008-March/001789.html
    • In /usr/local/pubcookie/config, I added the lines:
      • general_facility: local3
      • audit_facility: local3
      • and wrote to disk.
    • sudo service openbsd-inetd restart
  • Opened https://pubcookie.enterrupt.com in browser; I got the generic error again, but this time, output appeared in /var/log/syslog. The first error was: “security_init: Session keyfile (/etc/apache2/ssl/STAR_enterrupt_com.key) doesn’t exist.” This is likely due to permissions, because that path is correct.
    • su - root
    • cd /etc/apache2
    • chmod -R 655 ssl
    • logout
  • Opened https://pubcookie.enterrupt.com in browser; still got the generic error, but this time, pubcookie complained in syslog about “can’t access crypt key file  /usr/local/pubcookie/keys/*.enterrupt.com (try setting crypt_key)”
    • cd /usr/local/pubcookie/keys
    • sudo cp pubcookie.enterrupt.com "*.enterrupt.com"
  • Successfully opened the pubcookie login page in a browser window; I’m not sure if the above resolution is 100% sound, but it likely complained because the certificate I’m using in the keyserver is a wildcard. Simply duplicating the key that was generated using keyclient shouldn’t be an issue.
  • sudo nano /usr/local/pubcookie/config
    • Reduced logging_level to 1; wrote file to disk.
  • sudo halt
  • At this point, the Pubcookie keyserver has been set up using what Pubcookie calls the “alwaystrue” verifier - this means that you can go to the Pubcookie login page right now and type anything you want for the username and password; regardless of the values, Pubcookie will accept them. We’ll keep this mode in order to keep things simple. When we add an LDAP server to the mix, we’ll turn off the alwaystrue verifier in favor of the LDAP credential set.

Configuring PeopleSoft and Writing Sign-on PeopleCode

  • At this point we need to boot the Pubcookie keyserver, the PeopleSoft database server, and the PeopleSoft workstation. On the PeopleSoft workstation, start both the app and web server processes.
  • Signed into portal as user PS.
  • I will be referencing the PeopleTools 8.52 Security PeopleBook throughout this section, beginning on page 186 and following along roughly sequentially.
  • Via portal, I added a new User Profile called GUEST.
    • Password: <redacted>
    • On ID tab, set ID Type to None.
    • PeopleBook says that no roles or permission lists are necessary, so leaving all of those blank / empty.
    • Saved user profile.
  • Went to PeopleTools > Web Profile > Web Profile Configuration
    • Opened the DEV profile.
    • On the Security tab, checked Allow Public Access and entered GUEST / <redacted> as the credentials.
    • Set Days to Auto Fill User ID to 0 to prevent auto-filling of sign-on page (suggested in PeopleBook).
    • Saved the profile.
  • Went to PeopleTools > Security > Encryption > Algorithm Chain
    • Added new chain called ENT_SHA1_AC
    • Set description to Enterrupt SHA1
    • Added PSUnicodeToAscii in sequence position 1.
    • Added sha1_generate in sequence position 2.
    • Added PSHexEncode in sequence position 3.
    • Added PSAsciiToUnicode in sequence position 4.
    • Remember that the list should be ordered with the lowest sequence position at the top of the list, and the highest at the bottom.
    • Saved the chain.
  • Went to PeopleTools > Security > Encryption > Encryption Profile
    • Added new profile called ENT_SHA1
    • Used Algorithm Chain ID ENT_SHA1_AC
    • Set Description to Enterrupt SHA1 Profile
    • Saved the profile.
  • I’m creating a new administrative user called MQUINN so that my modifications in App Designer will be marked as me(rather than PPLSOFT or PS).
    • Went to PeopleTools > Security > User Profiles > Copy User Profiles
    • Selecting PS as the source record.
    • Using MQUINN as the new user id, <redacted> the password, leaving the description blank, checked the box next to Copy Type ID Information.
    • Pressed Save.
    • Pressed Save again; ignored warning about EMPLID assigned to another user.
  • Opened RDP connection to PS app / web server on EC2.
  • Signed into App Designer using MQUINN / <redacted>.
    • Attempted to open Record:FUNCLIB_LDAB, but I do not have permission and would only be able to open it as read-only.
    • Found this useful reference.
    • Therefore, went to Go > Definition Security in App Designer.
    • The PS Definition Security window appeared.
    • Went to File > Open > Group and selected PEOPLETOOLS.
    • In the type dropdown, selected Records and waited for data to populate.
    • In the left pane, highlighted FUNCLIB_LDAP and moved it to the right pane.
    • File > Save.
    • Closed Definition Security.
  • Returned to App Designer; opened Record:FUNCLIB_LDAP successfully this time.
  • Opened the PeopleCode FieldDefault segment for Field:LDAPAUTH
  • Added a comment block at the top and a function called ENT_Pubcookie at the bottom; the function body is as follows:

Appended to FUNCLIB_LDAP.LDAPAUTH.FieldDefault

/*//////////////////////////////////////////////////////////////////////////////////////////////////////
  Used during single sign on to process information sent over by pubcookie server.
//////////////////////////////////////////////////////////////////////////////////////////////////////*/
Function ENT_Pubcookie()

   /* Get the parameters that are passed in the form. */
   &PubcookieCompId = %Request.GetParameter("compid");
   &PubcookieRandom = %Request.GetParameter("random");
   &PubcookieTime = %Request.GetParameter("time");
   &PubcookieDigitalSignature = Upper(%Request.GetParameter("sha1"));

   /* Ensure that all parameters are present before executing. */
   If All(&PubcookieCompId) And
         All(&PubcookieRandom) And
         All(&PubcookieTime) And
         All(&PubcookieDigitalSignature) Then

      /* Calculate the epoch time in GMT */
      &ENT_Time = String(DateTimeToTimeZone(%Datetime, %ServerTimeZone, "GMT") - DateTime6(1970, 1, 1, 0, 0, 0));

      /* If time difference is less than 10 seconds, perform further edits. */
      /* MQUINN 09-25-2013
       * Disabling time difference check because it will be a headache come
       * daylight savings transitions. Also, there are three servers at play (PS app server,
       * PS db server, and Pubcookie app server, and I don't feel like messing around with the times on
       * any of them. Thankfully this is not a production machine, so it doesn't matter anyway.
       */
      If ( True Or
            Value(&PubcookieTime) - Value(&ENT_Time) < 10) Then
         SQLExec("select 'Y' from PSOPRDEFN where oprid = :1", &PubcookieCompId, &UserIdPresent);

         /* Ensure that UserId or the CompId passed by Pubcookie exists in the system. */
         If &UserIdPresent = "Y" Then

            /* Invoke Encryption. ENT_SHA1 is the Encrpytion Profile defined. Update Data passes the text
                that needs to be encrypted to create the Digital Signature. */
            &EntCrypt = CreateObject("Crypt");
            &EntCrypt.Open("ENT_SHA1");
            &EntCrypt.UpdateData(&PubcookieCompId | &PubcookieTime | "This is the shared secret." | &PubcookieRandom);
            &EntDigitalSignature = Upper(&EntCrypt.Result);

            /* If the Digital Signatures match, authenticate the UserId / CompId. */
            If &PubcookieDigitalSignature = &EntDigitalSignature Then
               &userID = &PubcookieCompId;
               SetAuthenticationResult( True, &userID, "", False);
            Else
               &failureReason = "Digital Signature does not match."
            End-If;
         Else
            &failureReason = "Operator ID not present in database: " | &PubcookieCompId;
         End-If;
      Else
         &failureReason = "Credentials supplied are older than 10 seconds: " | String(Value(&PubcookieTime) - Value(&ENT_Time));
      End-If;

   End-If;

End-Function;


  • Saved the PeopleCode segment.
  • Returned to portal session as user PS.
  • Went to PeopleTools > Security > Security Objects > Signon PeopleCode
    • Used user PS with password <redacted> for the second Invoke as option in the Signon box.
    • Added row to the bottom of the table.
    • Using 7 for sequence number.
    • Selected the Enabled checkbox.
    • Using FUNCLIB_LDAP for the record.
    • Using LDAPAUTH for the field name.
    • Using FieldDefault for the event name.
    • Using ENT_Pubcookie for function name.
    • Leaving Exec Auth fail checbox deselected.
    • Clicked Save.

Intermission

At this point, PeopleSoft is ready to accept POST requests with the form fields (compid, random, time, sha1) it expects. The Pubcookie app server that we haven’t yet set up is responsible for sending this request once it has confirmed with the keyserver that the user requesting access to PeopleSoft is a valid user. The next steps involve setting up the Pubcookie app server and writing the front-end script that will interface with the Sign-on PeopleCode from the previous step.

Setting up a Pubcookie App Server (Part 1)

  • Using this guide as a reference.
  • Note: The first step is to get Apache up and running serving content via HTTPS. Since I already have a snapshot of pubcookie.enterrupt.com from the second step in this guide, I’ll use that as the starting point for the new EC2 instance. All of the configuration settings applied up to that snapshot are thus retroactively included here for this instance.
  • Launched an EC2 instance (Ubuntu Server 12.04) and assigned an Elastic IP to the instance. Used the PUBCOOKIE_SERVER Security Group for the instance. Deleted the default volume and loaded a volume that was created from the snapshot mentioned in the previous bullet. Added an entry to Route 53 to route requests to pblogin.enterrupt.com to this server.
  • Connected via SSH to pblogin.enterrupt.com as UNIX user ubuntu.
  • su - apache
  • cd /var/www
  • mv pubcookie.enterrupt.com pblogin.enterrupt.com
  • cd /etc/apache2
  • sudo a2dissite pubcookie.enterrupt.com
  • sudo service apache2 stop
  • cd sites-available
  • sudo mv pubcookie.enterrupt.com pblogin.enterrupt.com
  • sudo nano pblogin.enterrupt.com
  • Changed DocumentRoot to /var/www/pblogin.enterrupt.com
  • For the second element, changed /var/www/pubcookie.enterrupt.com to /var/www/pblogin.enterrupt.com
  • Wrote file to disk.
  • sudo a2ensite pblogin.enterrupt.com
  • sudo service apache2 start
  • Successfully viewed index page at https://pblogin.enterrupt.com; green lock icon visible in URL bar.
  • su - pubcookie
  • wget http://www.pubcookie.org/downloads/pubcookie-3.3.4a.tar.gz
  • tar -xvf pubcookie*gz
  • rm pubcookie*gz
  • su - root (switching to root as install documentation suggests installing module as root)
  • cd /home/pubcookie/pubcookie-3.3.4a
  • At this point, I can either build the module and load it dynamically or compile the module into a new Apache binary. I’ll go with the former.
  • sudo apt-get install gcc libssl-dev make
  • ./configure --enable-apache --prefix=/usr/local/pubcookie
    • I ran the above command and got an error saying that “either apxs or the apache source must be specified.” I have no desire to compile the module statically, so I searched for a way to get apxs on my system. I found this page so I ran the following:
      • sudo apt-get remove apache2
      • sudo apt-get install apache2-threaded-dev
      • I found apxs2 in /usr/bin, so this is what I’ll pass to configure.
  • sudo ./configure --enable-apache --prefix=/usr/local/pubcookie --with-apxs=/usr/bin/apxs2
  • sudo make
    • This failed initially; error from make was: “No rule to make target /build/rules.mk. Stop.” I found this page, so I did the following:
      • sudo apachectl restart (just in case)
      • cd module
      • nano Makefile
        • Set the value for top_srcdir to /usr/share/apache2
        • Set the value for top_builddir to /usr/share/apache2
        • Wrote disk to file
  • sudo make; this time it finished successfully.
  • sudo make install; all indicates were that it finished successfully.
  • Verified that the keyclient binary and keys directory were in /usr/local/pubcookie.
  • Verified that the mod_pubcookie.so library was added to /usr/lib/apache2/modules.
  • cd /usr/local/pubcookie
  • nano config - this is a new file, contents used are below:

/usr/local/pubcookie/config

# ssl config
ssl_key_file: /etc/apache2/ssl/STAR_enterrupt_com.key
ssl_cert_file: /etc/apache2/ssl/STAR_enterrupt_com.crt

# keyclient-specific config
keymgt_uri: https://pubcookie.enterrupt.com:2222
ssl_ca_file: /etc/apache2/ssl/ca_bundle.txt


  • Wrote config to disk.
  • ./keyclient -H pblogin.enterrupt.com
    • Failed with error: “certificate presented isn’t the key server: *.enterrupt.com != pubcookie.enterrupt.com” due to my use of a wildcard cert. I had the problem before, so I applied those steps here:
      • sudo nano config
      • Changed login_host to *.enterrupt.com
      • Wrote file to disk.
  • ./keyclient -H pblogin.enterrupt.com
    • Failed with error: “NO you (pblogin.enterrupt.com) are not authorized for keys”
    • On pubcookie.enterrupt.com, I modified /usr/local/pubcookie/config as follows:
      • Added pblogin.enterrupt.com to keyserver_client_list.
      • Added *.enterrupt.com to keyserver_client_list (if you do not do this, you will not be able to run the keyclient command two steps from now).
      • Wrote file to disk.
      • ./keyclient -P pblogin.enterrupt.com (authorizes pblogin.enterrupt.com to request host keys. If you do not add .enterrupt.com to the keyserver_client_list directive, you will get the following error: “NO you (.enterrupt.com) are not authorized to authorize”
      • Verified that there is now a key for pblogin.enterrupt.com in /usr/local/pubcookie/keys
    • Closed SSH session on pubcookie.enterrupt.com and returned to session on pblogin.enterrupt.com
  • ./keyclient -H pblogin.enterrupt.com; command completed successfully this time (“Set crypt key for pblogin.enterrupt.com”)
  • Verified that there is now a key for pblogin.enterrupt.com in /usr/local/pubcookie/keys
  • ./keyclient -G keys/pubcookie_granting.cert
  • Verified that there is now a pubcookie_granting.cert file in /usr/local/pubcookie/keys

Setting up a Pubcookie App Server (Part 2)

  • Now that Pubcookie has been configured, we need to tell Apache to use the mod_pubcookie module; this module allows the Pubcookie app server to interface with the keyserver.
  • In the previous step, the module (mod_pubcookie.so) was placed in /usr/lib/apache2/modules, but I need it in /etc/apache2/mods-available, so:
    • cp /usr/lib/apache2/modules/mod_pubcookie.so /etc/apache2/mods-available
  • cd /etc/apache2/conf.d
  • sudo service apache2 stop
  • touch pubcookie.conf
    • Note: I am placing a config file here (in /etc/apache2/conf.d) because modifying httpd.conf is deprecated from what I can tell. This new config file should get loaded on restart.
  • nano pubcookie.conf; contents are as follows:

/etc/apache2/conf.d/pubcookie.conf

# MQUINN 09-24-2013
# I added this config file in order to load the pubcookie
# Apache module and configure its use.

LoadModule pubcookie_module mods-available/mod_pubcookie.so
PubcookieGrantingCertFile /usr/local/pubcookie/keys/pubcookie_granting.cert
PubcookieSessionKeyFile /etc/apache2/ssl/STAR_enterrupt_com.key
PubcookieSessionCertFile /etc/apache2/ssl/STAR_enterrupt_com.crt
PubcookieKeyDir /usr/local/pubcookie/keys/

PubcookieLogin https://pubcookie.enterrupt.com
PubcookieLoginMethod POST
PubcookieDomain .enterrupt.com
PubcookieAuthTypeNames Pubcookie

# Disable inactivity timeout by default.
<Directory "/">
        PubcookieInactiveExpire -1
</Directory>


  • Wrote file to disk.
  • sudo service apache2 start
    • Failed to start; checked /var/log/apache2/error.log and found: “security_init: can’t access crypt key file /usr/local/pubcookie/keys/*.enterrupt.com (try setting crypt_key)”
      • This occurred when I setup the keyserver on pubcookie.enterrupt.com; using the remedy I listed in a previous section of this guide:
        • cd /usr/local/pubcookie/keys
        • cp pblogin.enterrupt.com "*.enterrupt.com"
  • sudo service apache2 start; startup was successful this time.
  • Verified that empty index page was displayed at https://pblogin.enterrupt.com; green lock icon is displayed.

Creating and Testing an Example Pubcookie-Protected Application

  • We’ll create a test application to ensure that the Pubcookie app server can communicate with the Pubcookie keyserver. Since we’re still using the “alwaystrue” verifier, all attempts to access the sample application will be OK’d by the keyserver. Once the authentication attempt returns control to the app server, the test application will POST some form data to PeopleSoft and attempt to trigger Sign-on PeopleCode. If everything works, we should see the portal page for a signed-in user; for now we’ll hardcode the user’s operator into the POST request.
  • Logged into pblogin.enterrupt.com as ubuntu UNIX user.
  • cd /var/www/pblogin.enterrupt.com
  • mkdir testapp
  • cd testapp
  • nano index.html
    • Added the line: This is protected by pubcookie.
  • nano .htaccess
    • Added the line: AuthType Pubcookie
    • Added the line: require valid-user
  • sudo nano /etc/apache2/sites-enabled/pblogin.enterrupt.com
    • Changed both occurrences of the directive AllowOverride None to AllowOverride AuthConfig
  • sudo service apache2 restart
  • Opened a browser and navigated to https://pblogin.enterrupt.com/testapp; was successfully directed to the login page on pubcookie.enterrupt.com.
    • After logging in (don’t just press login with alwaystrue verifier, you must type something (anything) in the boxes), I was successfully redirected back to pblogin.enterrupt.com, where the text “This is protected by pubcookie was displayed.”
    • Confirmed that the username being entered into the credentials page is outputted to the Apache access.log on pblogin.enterrupt.com.
  • At this point, we have verified that the Pubcookie app server and keyserver are communicating successfully with each other. Now we’ll set up the test application, which will be written in Perl.
  • Renamed /var/www/testapp to /var/www/app/sis
  • Created /var/www/pblogin.enterrupt.com/app/sis/.htaccess
    • Added the line AuthType Pubcookie
    • Added the line require valid-user
  • Created /var/www/pblogin.enterrupt.com/app/sis/login.cgi
  • Aadded a <Directory> element for /var/www/pubcookie.enterrupt.com/app/sis/ in the site config file in Apache, with the lines Options +ExecCGI and AddHandler cgi-script .cgi included in the element body.
  • Restarted Apache.
  • I was able to display the Pubcookie remote user with the following in login.cgi:

/var/www/pblogin.enterrupt.com/app/sis/login.cgi

#/usr/bin/perl
print "Content-type: text/html\n\n";
print "Remote user: $ENV{'REMOTE_USER'}";


  • Going to  https://pblogin.enterrupt.com/app/sis/login.cgi?env=/ENTCSDEV in a browser printed “Remote user: mjq4aq” from my pubcookie session that I created earlier.
  • Also: I did a recursive chown (apache:entsso) and chmod (755) on /var/www/pblogin.enterrupt.com/app/sis/; this was because the Apache error log was showing permission denied errors in the error.log. This level of permission is obviously unsafe, but I don’t care about this server for production use, just demo use.
  • I modified login.cgi to generate the four fields (compid, time, random, and sha1) that need to be sent over to PeopleSoft. After doing so, I was able to login to PeopleSoft successfully by typing an operator ID into the Pubcookie login page. Immediately below is a tree view of the directory structure of the sample application, followed by the file contents of each important file:

Directory Structure for the Sample Application

  • /var/www/pblogin.enterrupt.com/app/sis
    • .htaccess (File1 below)
    • login.cgi (File2 below)
    • logout (directory)
      • .htaccess (File3 below)
      • index.html (blank)

.htaccess (File1)

PubcookieAppID entCampusSolutions
AuthType Pubcookie
require valid-user
PubcookieSessionCauseReAuth on

login.cgi (File2)

#!/usr/bin/perl

use Digest::MD5 qw(md5 md5_hex);
use Digest::SHA qw(sha1 sha1_hex);

my $portalDefaultPage = "http://university.enterrupt.com/psp/ENTCSDEV/EMPLOYEE/HRMS/h/?tab=DEFAUL$

my $compid = $ENV{'REMOTE_USER'};
my $time = time;
my $rand = substr(md5_hex(rand()), 0, 16);
my $sha1 = sha1_hex($compid . $time . "This is the SSP shared secret." . $rand);

print "Content-type: text/html\n\n";
print "<html>";
print "<head>";
print "</head>";
print "<body>";
print "<body onload=\"document.automatic.submit()\">";

print "compid: $compid<br\>";
print "time: $time<br\>";
print "random: $rand<br\>";
print "sha1: $sha1<br\>";

print "<form name=\"automatic\" method=\"POST\" action=\"$portalDefaultPage\">";
print "<input type=\"hidden\" name=\"compid\" value=\"$compid\"/>";
print "<input type=\"hidden\" name=\"time\" value=\"$time\"/>";
print "<input type=\"hidden\" name=\"random\" value=\"$rand\"/>";
print "<input type=\"hidden\" name=\"sha1\" value=\"$sha1\"/>";
print "</form>";
print "</body>";
print "</html>";

.htaccess (File3)

PubcookieEndSession clearLogin

Forcing Re-Authentication For Each Access of the Test Application

  • For extra security, you may want to force a Pubcookie “application” to require the user to authenticate every time they request access to it. When I tried to configure this, it turned out that the default settings, as compiled into Pubcookie, prevent this. I tried to include the “PubcookieSessionCauseReAuth on” directive in my .htaccess file on pblogin.enterrupt.com, but it seems to have had no effect. I found this thread with one person saying they also had no luck; however, they were specifically asking about the PubcookieHardExpire limit, which pubcookie forces to be greater than 3600 seconds. If this limit can be reduced to 1, theoretically I should be able to achieve the desired effect. However, that requires that I modify the source code for pubcookie and recompile it. This section details how to do that.
  • First, I’m going to create a backup of /usr/local/pubcookie in case it gets overwritten:
    • sudo cp -R /usr/local/pubcookie /usr/local/pubcookie_mjqbackup
  • su - root
  • cd ~
  • wget http://www.pubcookie.org/downloads/pubcookie-3.3.4a.tar.gz
  • tar xvf p*gz
  • rm *.gz
  • cd ~/pubcookie-3.3.4a
  • Before continuing, we need to allow the hard expiry limit to be 1.
    • cd src
    • nano pbc_config.h
    • Search for PBC_MIN_HARD_EXPIRE; you want the #define statement. Change the value from (1 * 60 * 60) to just 1.
    • Wrote file to disk.
  • cd ~/pubcookie-3.3.4a
  • ./configure --enable-apache --prefix=/usr/local/pubcookie --with-apxs=/usr/bin/apxs2
  • make
    • This failed initially, as it did before (see further up in this log). Error was: “No rule to make target: `/build/rules.mk’. Stop.”
    • cd module
    • nano Makefile
      • Set the value for top_srcdir to /usr/share/apache2
      • Set the value for top_builddir to /usr/share/apache2
      • Wrote file to disk.
  • make; this time it completed successfully.
  • make install
  • The /usr/local/properties directory appears intact; all my changes are in place.
  • Verified that the newly built mod_pubcookie.so is in /usr/lib/apache2/modules.
  • Replaced the old mod_pubcookie.so with the newly built one:
    • sudo service apache2 stop
    • rm /etc/apache2/modules-available/mod_pubcookie.so
    • cp /usr/lib/apache2/modules/mod_pubcookie.so /etc/apache2/modules-available
    • sudo service apache2 start
    • Added the following lines to /var/www/pblogin.enterrupt.com/app/sis/.htaccess
      • PubcookieSessionCauseReAuth on
      • PubcookieHardExpire 1
      • Wrote file to disk.
    • Successfully tested the new setup; I am now forced to reauthenticate every time I sign into the test application, as I should be.

Setting Up an LDAP Server

  • This section sets up an LDAP server on the same machine as the Pubcookie keyserver to keep things simple. I’m using the OpenLDAP open source LDAP server.
  • Logged in to pubcookie.enterrupt.com over SSH as ubuntu UNIX user.
  • su - root
  • cd ~
  • Starting to install / configure LDAP server; using this page as an installation reference and this page as a general LDAP reference.
  • sudo apt-get install slapd ldap-utils
  • Used <redacted> as the Administrator password when prompted.
  • nano /etc/ldap/ldap.conf
    • Uncommented the BASE directive and used dc=pubcookie,dc=enterrupt,dc=com
    • Uncommented the URI directive and used ldap://localhost
    • Wrote file to disk.
  • dpkg-reconfigure slapd
  • Hit No when prompted to omit OpenLDAP server configuration.
  • Used pubcookie.enterrupt.com when prompted for DNS domain name.
  • Used entpubcookie as the Organization name.
  • Entered <redacted> admin password for LDAP directory.
  • Used HDB for backend.
  • Entered no to prevent database from being removed when slapd is purged.
  • Entered yes to move old database.
  • Entered no to disallow LDAPv2 protocol.
  • Ran ldapsearch -x to verify configuration.
  • Going to install phpldapadmin, but first I need to enable PHP for Apache:
    • sudo apt-get install libapache2-mod-php5 php5
  • sudo apt-get install phpldapadmin (GUI interface for LDAP administration)
  • ln -s /usr/share/phpldapadmin /var/www/phpldapadmin
  • nano /etc/phpldapadmin/config.php
    • Scrolled to “Define your LDAP servers in this section”
    • Changed server name to ENT Pubcookie LDAP Server
    • Changed host to localhost
    • Changed array of base DNs to dc=pubcookie,dc=enterrupt,dc=com
    • Changed bind_id to cn=admin,dc=pubcookie,dc=enterrupt,dc=com
    • Wrote file to disk.
  • cd /etc/apache2
  • cp sites-available/default sites-available/phpldapadmin
  • nano sites-available/phpldapadmin; text is below:

/etc/apache2/sites-available/phpldapadmin

<VirtualHost *:80>
        ServerAdmin <redacted>
        ServerName pubcookie.enterrupt.com

        DocumentRoot /var/www/phpldapadmin
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/phpldapadmin>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>


  • sudo a2ensite phpldapadmin
  • sudo service apache2 restart
  • IMPORTANT: I am not opening up port 389 on the EC2 Security Group because I have no plans to make this LDAP server accessible to any machine other than localhost (i.e., pubcookie login server).
  • Logged in as admin in PHPLDAPAdmin successfully.
  • Added new Generic: Posix Group called entcsdev and clicked Create Object, then Commit.
  • Under new entcsdev group, created a Generic: User Account:
    • cn: Kimberly Adams
    • first name: Kimberly
    • GID number: entcsdev
    • Home dir: /home/users/kadams
    • Last Name: Adams
    • Password: <redacted> (want this to be different from PS-defined value for testing purposes)
    • User ID: kadams
    • Committed data.

Switching Pubcookie from AlwaysTrue Verifier to LDAP Verifier

  • Now that there’s a user account in the LDAP database, I need to switch Pubcookie over from using the alwaystrue verifier to use the LDAP verifier. Then I can attempt to log in to PeopleSoft with the LDAP credentials for user account kadams.
  • Logged into pubcookie.enterrupt.com over SSH as ubuntu UNIX user.
  • su - root
  • Backing up current /usr/local/pubcookiecp -R /usr/local/pubcookie /usr/local/pubcookie_mjqbackup
  • Deleting current /usr/local/pubcookie: rm -rf /usr/local/pubcookie
  • wget www.pubcookie.org/downloads/pubcookie-3.3.4a.tar.gz
  • tar xvf pub*gz
  • rm pub*gz
  • cd pubcookie-3.3.4a
  • ./configure --enable-login --disable-apache --enable-ldap --with-ldap-dir=/usr/lib/ldap/
    • Note: saw “Warning: No OpenLDAP API found” in output of configure. This could be an issue, but I tried several times with different flags to resolve the issue with no luck. Continuing anyway.
  • sudo make; failed because of LDAP-related errors, likely due to above issue.
    • Searched for ldap.h, which is what configure looked for; none found on system.
    • Found a development related package for OpenLDAP; installed using sudo apt-get install libldap2-dev
    • Re-ran search; found ldap.h in /usr/include
    • ran dpkg -L libldap2-dev to list all files put on filesystem for package; /usr/include seems to be where the headers were installed.
  • ./configure --enable-login --disable-apache --enable-ldap
    • I excluded the --with-ldap-dir flag to see if configure would pick it up this time and it did; no LDAP errors were found this time around.
  • sudo make; completed successfully this time.
  • sudo make install completed successfully
  • cd /usr/local/pubcookie; verified files were built successfully
  • Copied over following files from backup:
    • config
    • login_templates directory
    • keys directory
  • Replaced the index.cgi and media directories in /var/www/pubcookie.enterrupt.com with the newly built equivalents from /usr/local/pubcookie/login
  • sudo service openbsd-inetd restart (just in case)
  • nano config
    • Changed basic_verifier from alwaystrue to ldap
    • Added value for ldap_uri: ldap://localhost/cn=entcsdev,dc=pubcookie,dc=enterrupt,dc=com???(uid=%s)?x-BindDN=cn=admin;dc=pubcookie%2Cdc=enterrupt%2Cdc=com,x-Password=<redacted>
  • Opened https://pubcookie.enterrupt.com and successfully established a session using username kadams and password <redacted>.
  • Booted up db server, ps app server, and pblogin to verify everything.
  • Tried to sign in as kadams, greeted with authorization error by PS. This is likely due to the difference in case; PS expects upper case.
    • Solution: In the login.cgi script on pblogin.enterrupt.com, I upper-cased the REMOTE_USER before forwarding it to PeopleSoft. I thought about using “uppercase_username: 1” in the pubcookie.enterrupt.com config file, but this is too broad; upper-casing should be done on application-by-application basis.
  • Successfully signed into PeopleSoft using kadams / <redacted> credentials.
  • Added LDAP entry for username mquinn / <redacted> credentials.
    • Successfully signed into PeopleSoft using those credentials as well.