Wednesday 23 July 2014

TIL - Hidding HTML elements with jQuery in IE.

The snippets of code below are equivalent, however the code in red does not work in IE (at least IE 9 and 11)

$('#myid').prop('hidden', true);
$('#myid').hide();

$('#myid').prop('hidden', false);
$('#myid').show();

Monday 21 July 2014

Update Entity from JavaScript in Ms Dynamics CRM 2011/2013 using OData endpoint

Posting this for future reference:

function updateEntity(entityName, id, entity ) {

    var url = oDataUrl + "/" + entityName + "Set(guid'" + id + "')";

    entityData = window.JSON.stringify(entity);

    return $.ajax({
        type: "POST",
        contentType: "application/json;charset=utf-8",
        datatype: "json",
        data: entityData,
        url: url,
        beforeSend: function (x) {
            x.setRequestHeader("Accept", "application/json");
            x.setRequestHeader("X-HTTP-Method", "MERGE")
        },
    });
}
entityName is the logical entity name.
id is the Id of the record that we want to update
entity is a object that contains that values that need changing.
 e.g.:
 account = {};
 account.Name = "New Name"; 

 oDataUrl is the Url of the OData endpoint for your organization

Tuesday 15 July 2014

RHEL 7 - RHCE + RHCSA Exam Objectives

I intend to go through these exams at some point in the near future and I thought it would be handy to have the objectives for both exams here.

Note: I'm reusing the links from my RHEL 6 post, so if something doesn't quite work let me know and I'll update the post with a new RHEL 7 post. I do intend to go through them but it might take me a while.

I'll attempt to link newer post to the relevant objective, where appropriate. Almost always, it won't be appropriate and in that case I have made an attempt to link to a page with the relevant information for the objective.

Feel free to suggest a better or alternatively link to ones I have provided.

RHCSA Exam Objectives

Red Hat reserves the right to add, modify and remove objectives. Such changes will be made public in advance through revisions to this document.

RHCSA exam candidates should be able to accomplish the tasks below without assistance. These have been grouped into several categories.

Understand and Use Essential Tools

* Access a shell prompt and issue commands with correct syntax
Use input-output redirection (>, >>, |, 2>, etc.)
Use grep and regular expressions to analyze text
Access remote systems using ssh
* Log in and switch users in multi-user runlevels
* Archive, compress, unpack and uncompress files using tarstargzip, and bzip2
Create and edit text files
Create, delete, copy and move files and directories
Create hard and soft links
* List, set and change standard ugo/rwx permissions
Locate, read and use system documentation including man, info, and files in /usr/share/doc .
[Note: Red Hat may use applications during the exam that are not included in Red Hat Enterprise Linux for the purpose of evaluating candidate's abilities to meet this objective.]

Operate Running Systems

Boot, reboot, and shut down a system normally
Boot systems into different runlevels manually
* Interrupt the boot process in order to gain access to a system
Identify CPU/memory intensive processesadjust process priority with renice, and kill processes
Locate and interpret system log files and journals.
Access a virtual machine's console
Start and stop virtual machines
* Start, stop and check the status of network services
* Securely transfer files between systems.

Configure Local Storage

* List, create, delete partitions on MBR and GPT disks.
Create and remove physical volumes, assign physical volumes to volume groups, create and delete logical volumes
Create and configure LUKS-encrypted partitions and logical volumes to prompt for password and mount a decrypted file system at boot
Configure systems to mount file systems at boot by Universally Unique ID (UUID) or label
Add new partitions, logical volumes and swap to a system non-destructively

Create and Configure File Systems

* Create, mount, unmount, and use vfat, ext4 and xfs file systems.
Mount, unmount and use LUKS-encrypted file systems
Mount and unmount CIFS and NFS network file systems
Configure systems to mount ext4, LUKS-encrypted and network file systems automatically
* Extend existing logical volumes
Create and configure set-GID directories for collaboration
Create and manage Access Control Lists (ACLs)
Diagnose and correct file permission problems

Deploy, Configure and Maintain Systems

Configure networking and hostname resolution statically or dynamically
* Schedule tasks using at and cron
* Start and stop services and configure services to start automatically at boot
Configure systems to boot into a specific runlevel automatically
Configure a physical machine to host virtual guests
Install Red Hat Enterprise Linux systems as virtual guests
Configure systems to launch virtual machines at boot
* Configure a system to use time services.
* Install and update software packages from Red Hat Network, a remote repository, or from the local filesystem
Update the kernel package appropriately to ensure a bootable system
Modify the system bootloader

Manage Users and Groups

Create, delete, and modify local user accounts
Change passwords and adjust password aging for local user accounts
Create, delete and modify local groups and group memberships
* Configure a system to use an existing authentication service for user and group information.

Manage Security

Configure firewall settings using firewall-config, firewall-cmd or iptables
Configure key-based authentication for SSH
Set enforcing and permissive modes for SELinux
* List and identify SELinux file and process context
* Restore default file contexts
Use boolean settings to modify system SELinux settings
Diagnose and address routine SELinux policy violations

RHCE Exam Objectives

Red Hat reserves the right to add, modify and remove objectives. Such changes will be made public in advance through revisions to this document.

RHCE exam candidates should be able to accomplish the following without assistance. These have been grouped into several categories.
System Configuration and Management

* Use network teaming or bonding to configure aggregated network links between two Red Hat Enterprise Linux systems.
* Configure IPv6 addresses and perform basic IPv6 troubleshooting
Route IP traffic and create static routes
* Use FirewallD, including Rich Rules, Zones and custom rules, to implement packet filtering and configure network address translation (NAT).
Use /proc/sys and sysctl to modify and set kernel run-time parameters
Configure system to authenticate using Kerberos
Configure a system as an iSCSI initiator that persistently mounts an iSCSI target
Produce and deliver reports on system utilization (processor, memory, disk, and network)
Use shell scripting to automate system maintenance tasks
Configure a system to log to a remote system
Configure a system to accept logging from a remote system

Network Services

Network services are an important subset of the exam objectives. RHCE candidates should be capable of meeting the following objectives for each of the network services listed below:

* Install the packages needed to provide the service
* Configure SELinux to support the service
Use SELinux port labelling to allow services to use non-standard ports.
* Configure the service to start when the system is booted
* Configure the service for basic operation
* Configure host-based and user-based security for the service

RHCE candidates should also be capable of meeting the following objectives associated with specific services:

HTTP/HTTPS

Configure a virtual host
Configure private directories
Deploy a basic CGI application
Configure group-managed content
Configure TLS security

DNS

Configure a caching-only name server
Configure a caching-only name server to forward DNS queries

NFS

Provide network shares to specific clients
Provide network shares suitable for group collaboration
* Use Kerberos to control access to NFS network shares.

SMB

Provide network shares to specific clients
Provide network shares suitable for group collaboration

SMTP

* Configure a system to forward all email to a central mail server

SSH

Configure key-based authentication
Configure additional options described in documentation

NTP

Synchronize time using other NTP peers


Database Services

* Install and configure MariaDB.
* Backup and restore a database.
* Create a simple database schema.
* Perform simple SQL queries against a database.

Monday 14 July 2014

The authentication endpoint Kerberos was not found on the configured Secure Token Service!

We finally managed to overcome all issues and deployed the build to the OAT environment and it went: KABOOM!!!
Unable to get item. Exception: System.NotSupportedException: The authentication endpoint Kerberos was not found on the configured Secure Token Service! at Microsoft.Xrm.Sdk.Client.IssuerEndpointDictionary.GetIssuerEndpoint(TokenServiceCredentialType credentialType) at Microsoft.Xrm.Sdk.Client.AuthenticationCredentials.get_IssuerEndpoint() at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.AuthenticateInternal(AuthenticationCredentials authenticationCredentials) at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.AuthenticateFederationInternal(AuthenticationCredentials authenticationCredentials) at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.Authenticate(AuthenticationCredentials authenticationCredentials) at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1.Authenticate(ClientCredentials clientCredentials) at Microsoft.Xrm.Sdk.Client.OrganizationServiceConfiguration.Authenticate(ClientCredentials clientCredentials) at Microsoft.Xrm.Sdk.Client.ServiceProxy`1.AuthenticateClaims() at Microsoft.Xrm.Sdk.Client.ServiceProxy`1.AuthenticateCore() at Microsoft.Xrm.Sdk.Client.ServiceProxy`1.Authenticate() at Microsoft.Xrm.Sdk.Client.ServiceProxy`1.ValidateAuthentication() at Microsoft.Xrm.Sdk.Client.ServiceContextInitializer`1.Initialize(ServiceProxy`1 proxy) at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.RetrieveMultipleCore(QueryBase query) at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.RetrieveMultiple(QueryBase query) at Consumer.ItemManager.RetrieveLastItem(String type) at
Consumer.ItemManager.RetrieveLastItem(String type) at
Consumer.Service.ConsumerService.Process[T](Config feed)

I thought that the Kerberos endpoint must not be enabled in ADFS, but it was and after a bit of investigating, it turns out that this is a known issue in MS Dynamics CRM 2011/13.

The interesting bit about this issue is that the front end was working fine, but trying to use the SDK in any way was not working.

The MEX endpoint that gets set when Claims Based Authentication is configured is like this:
https://adfs.domain.com/adfs/ls/mex
This is a bit of a problem, as it doesn't exist :(

The Working MEX endpoint is:
https://adfs.domain.com/adfs/services/trust/mex
Microsoft have kindly provided a PowerShell script to rectify this issue:

Save this as UpdateMEXEndpoint.ps1

Param (
     #optional params
     [string]$ConfigurationEntityName="FederationProvider",
     [string]$SettingName="ActiveMexEndpoint",
     [object]$SettingValue,
     [Guid]$Id
 )
 $RemoveSnapInWhenDone = $False
 
 if (-not (Get-PSSnapin -Name Microsoft.Crm.PowerShell -ErrorAction SilentlyContinue))
 {
     Add-PSSnapin Microsoft.Crm.PowerShell
     $RemoveSnapInWhenDone = $True
 }
 
 $Id=(Get-CrmAdvancedSetting -ConfigurationEntityName FederationProvider -Setting ActiveMexEndpoint).Attributes[0].Value
 
 $setting = New-Object "Microsoft.Xrm.Sdk.Deployment.ConfigurationEntity"
 $setting.LogicalName = $ConfigurationEntityName
 if($Id) { $setting.Id = $Id }
 
 $setting.Attributes = New-Object "Microsoft.Xrm.Sdk.Deployment.AttributeCollection"
 $keypair = New-Object "System.Collections.Generic.KeyValuePair[String, Object]" ($SettingName, $SettingValue)
 $setting.Attributes.Add($keypair)
 
 Set-CrmAdvancedSetting -Entity $setting
 
 if($RemoveSnapInWhenDone)
 {
     Remove-PSSnapin Microsoft.Crm.PowerShell
 }

This can then be used to modify the relevant setting:

UpdateMEXEndpoint.ps1 –SettingValue “https://<ADFS STSHOST>/adfs/services/trust/mex”

An alternative to use this script is updating the FederationProvider table in the MSCRM_Config database, but this is not supported.

Monday 7 July 2014

Storing sensitive data (e.g. passwords) in MS Dynamics CRM 2011/2013

We need to integrate with a third party, who have decided that implementing a federated trust is too complex and thus have just given us a user name and password.

Since the integration is done via a couple of plug-ins and custom activities we've decided to store the password in Dynamics CRM, the only problem is that there is no out of the box way of storing the passwords that would allow a relatively simple automated deployment.

Sure, we can register plug-in and use the secure configuration but that means deploying the solution and then re-registering the plug-ins with the secure data but this wasn't suitable.

We ruled out symmetric encryption as we would just have the same problem but for the encryption key, so the obvious choice was asymmetric encryption, the problem is that asymmetric encryption is not really suitable for large amounts of data, so we settled on the recommend way of using asymmetric encryption to encrypt the encryption key of a symmetric encryption scheme.

The thing is, the .NET framework sort of includes this in the form of the EncryptedXml class, which can use a certificate to encrypt and decrypt Xml documents and we can use this for storing a password for instance.

A sample of how to use this class can be seen below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using log4net;

namespace Encryption
{
    public class Encryption
    {
        ILog logger;
        X509Certificate2 certificate;

        public Encryption(string certificateThumbprint) 
        {
            logger = LogManager.GetLogger("Encryption");
            certificate = GetCert(certificateThumbprint);
        }

        public string Encrypt(string plaintext)
        {
            XmlDocument Doc = new XmlDocument();
            Doc.LoadXml(string.Format("<sensitivedata>{0}</sensitivedata>", HttpUtility.HtmlEncode(plaintext)));
            Doc.PreserveWhitespace = true;
            XmlElement toEncrypt = Doc.GetElementsByTagName("sensitivedata")[0] as XmlElement;
            EncryptedXml eXml = new EncryptedXml();
            EncryptedData edElement = eXml.Encrypt(toEncrypt, certificate);
            EncryptedXml.ReplaceElement(toEncrypt, edElement, false);
            return Doc.OuterXml;
        }

        public string Decrypt(string encryptedtext)
        {
            XmlDocument Doc = new XmlDocument();
            Doc.LoadXml(encryptedtext);
            EncryptedXml exml = new EncryptedXml(Doc);
            exml.DecryptDocument();
            string plaintext = HttpUtility.HtmlDecode(XDocument.Parse(Doc.OuterXml).Element("sensitivedata").Value);
            return plaintext;
        }

        private X509Certificate2 GetCert(string thumbprint)
        {
            X509Certificate2 cert = null;
            X509Store store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            try
            {
                X509Certificate2Collection certCollection = store.Certificates;
                cert = certCollection.Cast<X509Certificate2>().Where(c => c.Thumbprint.Equals(thumbprint)).Single();
            }
            catch (Exception ex)
            {
                logger.ErrorFormat("An error occurred looking for certificate with thumbprint: {0}.\nException:{1}."
                    , thumbprint, ex);
            }
            finally
            {
                store.Close();
            }
   
            return cert;
        }
    }
}

The thing to note is that sensitive data to be encrypted needs to be valid xml data, in other words, if your sensitive data contains ampersands it will not be parsed, which is why I use the HttpUtility class to encode and decode the sensitive data.
 
 It does seem a little bit fiddly but it is quite almost all done by the framework, so it's really less code to maintain and the extra text that needs to be stored is not a consideration as it's a single record.
 
Furthermore, it would be trivial to modify and return a plaintext Xml Document for processing instead of the value of an element, but the value of an element is what I needed.

Saturday 5 July 2014

URLs fields in MS Dynamics CRM 2011 - MS Dynamics CRM 2011 annoyances part 1337

We had a requirement to let users see a URL field but not change the URL, the requirement, quite sensibly specified that the users should be able to click on the link.
I thought this was a textbook case for field security profiles, alas I was wrong. In MS Dynamics CRM 2011 if a URL field is read only, however this is achieved, the URL will not be clickable.

Despite the message, it does not work, note how the mouse icon does not change.


Fortunately, this has been rectified in MS Dynamics CRM 2013

Tuesday 1 July 2014

ADFS Sign-in Page Url

Another happy day messing about with ADFS, another day I needed this, so here it goes:
https://<ADFS FQDN>/adfs/ls/IdpInitiatedSignon.aspx
where <ADFS FQDN> is the FQDN of your ADFS server or VIP's DNS entry.