XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Archive for the ‘Hacking’ Category

curl: (35) Unknown SSL protocol error in connection

Monday, November 25th, 2013

Recently we started getting the following error on the Agile India Registration site:

error number: 35 
error message: Unknown SSL protocol error in connection to our_payment_gateway:443

This error occurs when we try to connect to our Payment Gateway using Curl on the server side (PHP.)

By looking at the error message, it occurred to me, that may be, we are not setting the correct SSL protocol, which is supported by our PG server.

Using SSL Lab’s Analyser, I figured out that our PG server only supports SSL Version 3 and TLS Version 1.

Typically, if we don’t specify the SSL version, Curl figures out the supported SSL version and uses that. However to force Curl to use SSL Version 3, I added the following:

curl_setopt($ch, CURLOPT_SSLVERSION, 3);

As expected, it did not make any difference.

The next thing that occurred to me, was may be, the server was picking up a wrong SSL certificate and that might be causing the problem. So I got the SSL certificates from my payment gateway and then starting passing the path to the certificates:

curl_setopt($ch, CURLOPT_CAPATH, PATH_TO_CERT_DIR);

Suddenly, it started working; however not always. Only about 50% of the time.

May be there was some timeout issue, so I added another curl option:

curl_setopt($ch, CURLOPT_TIMEOUT, 0); //Wait forever

And now it started working always. However, I noticed that it was very slow. Something was not right.

Then I started using the curl command line to test things. When I issued the following command:

curl -v https://my.pg.server
* About to connect() to my.pg.server port 443 (#0)
*   Trying 2001:e48:44:4::d0... connected
* Connected to my.pg.server (2001:e48:44:4::d0) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to my.pg.server:443
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to my.pg.server:443

I noticed that it was connecting on iPV6 address. I was not sure if our PG server supported iPV6.

Looking at Curl’s man pages, I saw an option to resolve the domain name to IPv4 address. When I tried:

curl -v -4 https://my.pg.server

it worked!

* About to connect() to my.pg.server port 443 (#0)
*   Trying 221.134.101.175... connected
* Connected to my.pg.server (221.134.101.175) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
* 	 subject: C=IN; ST=Tamilnadu; L=Chennai; O=Name Private Limited; 
OU=Name Private Limited; OU=Terms of use at www.verisign.com/rpa (c)05; CN=my.pg.server
* 	 start date: 2013-08-14 00:00:00 GMT
* 	 expire date: 2015-10-13 23:59:59 GMT
* 	 subjectAltName: my.pg.server matched
* 	 issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; 
OU=Terms of use at https://www.verisign.com/rpa (c)10; 
CN=VeriSign Class 3 International Server CA - G3
* 	 SSL certificate verify ok.
> GET / HTTP/1.1
...

Long story short, it turns out that passing -4 or –ipv4 curl option, forces iPV4 usage and this solved the problem.

So I removed everything else and just added the following option and things are back to normal:

curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

What’s Inside MacBook’s Battery?

Monday, September 30th, 2013

Today, my six year old and I did a little experiment to figure-out what is actually inside a laptop’s battery.

1028927

We took a dead battery from one of my Mac Book Pro and cracked it open.

IMG_1772

IMG_1773

IMG_1774

IMG_1775

IMG_1777

Fetching Cross Domain XML in JavaScript – Simple Solution

Wednesday, July 17th, 2013

On my latest pet project, SlideShare Presentation Stack, I wanted to make an AJAX call to SlideShare.net to fetch all the details of the given slideshare user. One easy way to get this information is to request for the user’s RSS feed. However the RSS feed is only served as xml. And due to same-origin policy, I can’t make an AJAX call from my javascript to retrive the XML. I wish SlideShare support JSONP for fetching the user’s RSS feed. However they don’t. They do expose an API with rate limiting, but I wanted something simple. I found the following hack to work-around this issue:

<script type="text/javascript">
    simpleAJAXLib = {
        init: function () {
            this.fetchJSON('http://www.slideshare.net/rss/user/nashjain');
        },
 
        fetchJSON: function (url) {
            var root = 'https://query.yahooapis.com/v1/public/yql?q=';
            var yql = 'select * from xml where url="' + url + '"';
            var proxy_url = root + encodeURIComponent(yql) + '&format=json&diagnostics=false&callback=simpleAJAXLib.display';
            document.getElementsByTagName('body')[0].appendChild(this.jsTag(proxy_url));
        },
 
        jsTag: function (url) {
            var script = document.createElement('script');
            script.setAttribute('type', 'text/javascript');
            script.setAttribute('src', url);
            return script;
        },
 
        display: function (results) {
            // do the necessary stuff
            document.getElementById('demo').innerHTML = "Result = " + (results.error ? "Internal Server Error!" : JSON.stringify(results.query.results));
        }
    }
</script>

Trigger the AJAX call asynchronously by adding the following snippet where ever required:

<script type="text/javascript">
      simpleAJAXLib.init();
</script>

How does this actually work?

  • First, I would recommend you read my previous blog which explains how to make JSONP AJAX calls without using any javascript framework or library.
  • Once you understand that, the most important piece you need to understand is how we’ve used Yahoo! Query Language (YQL) as a proxy to retrieve your XML request to be served via JSONP.
  • Use the following steps:
    1. Write a SQL statement like select * from xml where url=’your_xml_returning_url’ and URI encode it.
    2. Append your yql statement to YQL url – https://query.yahooapis.com/v1/public/yql?q=
    3. Finally specify the format as json (ex: format=json) and a callback function name, which will be invoked by the browser once the results are retrieved (ex: callback=simpleAJAXLib.display)
    4. In the callback function, you can access the xml data from this JSON object: query.results

Interesting way of making JSONP AJAX calls from your JavaScript without using any Framework or Library

Wednesday, July 17th, 2013

On my latest pet project, SlideShare Presentation Stack, I wanted to make an AJAX call to fetch data from another domain. However due to same-origin policy, I can’t make a simple AJAX call, I need to use JSONP. JQuery and bunch of other libraries provide a very convenient way of making JSONP calls. However to minimize the dependency of my javascript library, I did not want to use any javascript framework or library. Also I wanted the code to be supported by all browsers that supported javascript.

One option was to use XMLHttpRequest. But I wanted to explore if there was any other option, just then I discovered this totally interesting way of making JSONP AJAX call. Code below:

<script type="text/javascript">
simpleAJAXLib = {
    init: function () {
        this.fetchViaJSONP('your_url_goes_here');
    },
 
    fetchViaJSONP: function (url) {
        url += '?format=jsonp&jsonp_callback=simpleAJAXLib.handleResponse';
        document.getElementsByTagName('body')[0].appendChild(this.jsTag(url));
    },
 
    jsTag: function (url) {
        var script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', url);
        return script;
    },
 
    handleResponse: function (results) {
        // do the necessary stuff; for example
        document.getElementById('demo').innerHTML = "Result = " + (results.error ? "Internal Server Error!" : results.response);
    }
};
</script>

Trigger the AJAX call asynchronously by adding the following snippet where ever required:

<script type="text/javascript">
      simpleAJAXLib.init();
</script>

How does this actually work?

Its simple:

  1. Construct the AJAX URL (any URL that support JSONP) and then append the callback function name to it. (For ex: http://myajaxcall.com?callback=simpleAJAXLib.handleResponse.) Also don’t forget to mention JSONP as your format.
  2. Create a new javascript html tag and add this URL as the src of the javascript tag
  3. Append this new javascript tag to the body. This will cause the browser to invoke the URL
  4. On the server side: In addition to returning the data in the expected formart, wrap the data as a paramater to the actual backback function and return it with a javascript header. The browser would eval this returned javascript and hence your callback function would be invoked. See server side code example below:
$data = array("response"=>"your_data");
header('Content-Type: text/javascript');
echo $_GET['jsonp_callback'] ."(".json_encode($data).")";

P.S: Via this exercise, I actually understood how JSONP works.

If you want to call an API, which does not support JSONP, you might be interested in reading my other blog post on Fetching Cross Domain XML in JavaScript, which uses Yahoo Query Language (YQL) as a proxy to work around the same-origin-policy for xml documents.

Using AppleScript to Programmatically Crop Images

Sunday, December 30th, 2012

Create the following AppleScript using the AppleScript Editor

on run argv
  set the this_file to item 1 of argv
  set the vertical_crop to 20
  set the horizontal_crop to 30
  tell application "Image Events"
    launch
    set this_image to open this_file
    copy dimensions of this_image to {W, H}
    crop this_image to dimensions {W - horizontal_crop, H - vertical_crop}
    save this_image with icon
    close this_image
  end tell
end run

Compile and save the file as a script.

save script dialog

Now you are ready to run the script on your images:

naresh$ osascript crop_image.scpt /complete/path/to/image.ext

Results:

Before After
original image cropped image

IMEI Unlock: Downgrade iPhone 3Gs baseband to 5.13.04 from 6.15.00

Wednesday, November 21st, 2012

Over the years, I bought many iPhones for family and friends from US. Only for the last 2 Years, Apple has been selling unlocked phones. Before that, for most phones, I had to figure out a way to jailbreak and carrier unlock the phone via Ultrasn0w.

For iPhone 3Gs, to carrier unlock your phone, I had to upgrade my phone’s baseband to 6.15.00 (iPad’s baseband) and then using Ultrasn0w I could use the phone with any service provider in India.

However for iPhone 4 with baseband 4.11.08, Ultrasn0w could not do the carrier unlock. Basically there was no way to upgrade/downgrade the baseband. I had given up hope and my daughter was happily using those iPhones as toys. Just then I came across BejingPhoneRepair’s IMEI Unlocking Steps. I was very skeptical that this would work. Paid $15 USD for 1 phone and it worked like a charm. I was able to unlock all my iPhone4’s.

Then I had this iPhone 3Gs, which I had jail broken and upgraded the baseband to 6.15.00. I wanted to upgrade that to iOS 6.0.1. So I thought I might as well use the same IMEI unlock. After I paid and followed the exact same steps I did for iPhone4, I realized there was an issue:

It refused to recognize the SIM card. Then I came across this article from Richard Ker of BeijingiPhoneRepair. This explains that iTunes does not let you activate your iPhone 3Gs with baseband 6.15.00 on iOS 6.

The solution they propose is to downgrade your baseband to 5.13.04 first. To downgrade your baseband you can get the original iPhone 3GS iOS 5.1.1 firmware and then using Redsn0w to flash the baseband. Since I already had iOS 6.0.1 installed on my phone, I kept getting the following error:

AppleBaseband: Could not find mux function error.

Tried downgrading my phone to iOS 5.1.1 using Redsn0w and iTunes, but no luck. Apple does not allow you to  downgrade from iOS 6 to iOS 5. You need the SHSH blobs saved for iOS 5.1.1 to downgrade as Apple has stopped signing this firmware. Using Redsn0w I tried searching Cydia’s server to see if SHSH blobs were available. No luck. So I followed the following steps to fix the issue:

  1. Using Redsn0w (0.9.14b2 or above), I put my phone in DFU mode.
  2. During the restore process, iTunes verifies with Apple’s server if the device is allowed to install the specific version of firmware. To work around this issue, I appended the following line 74.208.105.171 gs.apple.com to my host file (/etc/hosts) to fool iTunes.
  3. Then using iTunes, restored iOS 4.1 (8B117) firmware on my phone. I usually download my firmwares from iClarified’s site.
  4. After Launching redsn0w. Under Extras > Select IPSW and select the original iOS 4.1 (8B117) firmware
  5. Did a controlled shutdown of my iPhone (“slide to power off”).
  6. Returned to the first screen and clicked ‘Jailbreak’.
  7. Checked the ‘Downgrade from iPad baseband’ checkbox and unchecked Cydia. Next.
  8. Redsn0w started the downgrade process and you finally I saw the ‘Flashing Baseband’ screen on my iPhone with the Pawnapple icon. DO NOT INTERRUPT your iPhone while baseband flashing is in progress. This steps takes a good 5-10 mins.
  9. When this was done, after rebooting my iPhone, the baseband was downgraded to 5.13.04.
  10. Then I connected my phone to iTunes once more and upgraded my firmware to iOS 6.0.1.
  11. Once the upgrade was done, I saw this screen on iTunes.
  12. Now my phone can connect to the local service provider.
    Working iPhone with 6.0.1

ssl_error_ssl2_disabled error or the adventures of access internet in a hotel

Tuesday, February 28th, 2012

Last evening I checked into a very popular hotel in Bangalore. I was fascinated by the lavish suites and all the jazz.

Soon my fascination for the real world stopped and I wanted to get on to the internet. As soon as I tried to connect to the internet, I got the following error in my browser:

IE 5 and above only

WTF? I don’t have that crap (IE) with me and would never want to install it either.

However I realized that I could trick the server, by setting my browser’s user agent to IE 7.

safari_user_agent

Just as I was celebrating my smartness, I hit the next roadblock:

safari ssl2 error

Turns out that the 24Online service uses SSL v2 (Secure Sockets Layer 2.0), which of course was deprecated since the collapse of the roman empire.

I could not figure out how to enable this on safari or chrome. Suddenly I remembered, I could go to the about:config tab in Firefox and poke around there.

Tried filtering on security.*ssl2 and to my surprise found a config property called security.enable_ssl2. Tried turning it on. No luck!

Tried enabling the various encryption algorithms for the protocol/certificate:

Firefox SSL2 Config Filter

Yahoo! I was able to move to the next hurdle.

Finally I saw Firefox warning me about accessing the site with a fake certificate. I added the certificate to the exception list and there it was, The WWW. Finally I was connect!

    Licensed under
Creative Commons License