Changing Citrix ICA Settings on the Fly

Lets say your organization uses some software that you access through some other company’s Citrix XenApp web front-end. When you launch an application from XenApp, the browser downloads an ICA file that citrix receiver opens. You can change a wide variety of setting in that ica file (see https://docs.citrix.com/en-us/receiver/windows/ica-settings.html), but of course you can’t tell your users to edit the file every time they use that application, and if you have the citrix plugin you never even see the ica file.
I wanted to change the clientname that the citrix session would use since we were running an application that used the hostname to determine some settings. So I wrote a script in php that goes and gets the ica file from the XenApp web front end, modifies the ica, and then provides it to the user. This way you can change a lot of settings that the citrix session will use without having to resort to registry overrides, etc.

This post is partly inspired by: https://sysadminasaservice.wordpress.com/2015/08/30/login-to-storefront-with-curl/ Definitely check it out.

You would need to modify this for your particular use case. To find the url used to get the ica file, use chrome or firefox developer tools and monitor the net traffic to see which url finally actually provides the ica (the xenapp front end has a ton of redirects and js and such so you can’t just copy links). Also in our case the web front end allows anonymous logins, if not I think you could just collect and post the users login credentials to the right site as you collect the cookies.

 

$client_name = $_GET['c'];
if(!isset($client_name))
    die('wrong usage');
 
$ica_url = 'https://BASE_URL/Citrix/XenApp/site/launch.ica?CTX_Application=Citrix.SOMETHING.YOUR_APPLICATION&CTX_AppFriendlyNameURLENcoded=YOUR_APPLICATION';
     
function get_cookies_from_header($ch, $headerLine) {
    global $cookies;
    if (preg_match('/^Set-Cookie:\s*([^;]*)/mi', $headerLine, $cookie) == 1){
        $halves = explode('=',$cookie[1],2);
        $cookies[$halves[0]] = $halves[1];
    }
    return strlen($headerLine); // Needed by curl
}
function all_cookies(){
    global $cookies;
    $out = '';
    foreach($cookies as $k => $v){
        $out = $out.$k.'='.$v.'; ';
    }
    return $out;
}
 
$cookies = Array(); //a global
 
//setup curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADERFUNCTION, "get_cookies_from_header");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
 
//collect cookies
curl_setopt($ch, CURLOPT_URL, 'https://BASE_URL/Citrix/XenApp/site/default.aspx');
$r = curl_exec($ch);
 
curl_setopt($ch, CURLOPT_URL, 'https://BASE_URL/cgi/setclient?wica');
curl_setopt($ch, CURLOPT_COOKIE, all_cookies());
$r = curl_exec($ch);
 
curl_setopt($ch, CURLOPT_URL, 'https://BASE_URL/Citrix/XenApp/auth/silentDetection.aspx');
curl_setopt($ch, CURLOPT_COOKIE, all_cookies());
$r = curl_exec($ch);
 
//get final cookies
$cookies[WIClientInfo]="Cookies_On#true~icaScreenResolution#1000x700~clientConnSecure#true";
$cookies[WINGSession]="icaScreenResolution#1000x700~streamingClientDetected#~clientConnSecure#true~remoteClientDetected#~icoStatus#IcoNotDetected"; //you can change this for your situation
unset($cookies['ASP.NET_SessionId']); //not sure exactly why you need this, but you do... presumably we are skipping some step in the fwd chain that changes this
 
curl_setopt($ch, CURLOPT_URL, 'https://BASE_URL/Citrix/XenApp/auth/login.aspx');
curl_setopt($ch, CURLOPT_COOKIE, all_cookies());
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: keep-alive','Upgrade-Insecure-Requests: 1','User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36','Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8','Referer: https://BASE_URL/Citrix/XenApp/auth/silentDetection.aspx','Accept-Encoding: gzip, deflate, sdch, br','Accept-Language: en-US,en;q=0.8'));
$r = curl_exec($ch);
 
 
 
//get ica
curl_setopt($ch, CURLOPT_URL, $ica_url);
curl_setopt($ch, CURLOPT_COOKIE, all_cookies());
curl_setopt($ch, CURLOPT_HTTPHEADER,null);  //remove the header set above
$ica = curl_exec($ch);
 
 
 
//we have ica, check, modify and send out
if(strpos($ica,'[WFClient]') == false)
    die('error');
$mod_ica=str_replace("[WFClient]\r\n","[WFClient]\r\nClientName=".$client_name."\r\n",$ica);
//at this point you can modify the ica however you want
 
header('Content-Type: application/x-ica');
header('Content-Disposition: filename="launch.ica"');
print($mod_ica);

Other References:
http://stackoverflow.com/questions/895786/how-to-get-the-cookies-from-a-php-curl-into-a-variable

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s