Archive

Archive for November, 2017

Implementing a #HTTPS #Tunnel using c#

November 14, 2017 Leave a comment

rZl08

You very rarely have to work at TCP/IP level whenever writing network code in C#, and if you find yourself doing it, you’ve probably taken a very wrong turn. However, since information is sparse about the format of low level TCP requests, I’m writing this article.

This particular code snippet shows how to make a HTTPS tunnel via a proxy server in C#. It involves these steps:

  1. Send a CONNECT command instructing the proxy to connect to a remote server on a given port, i.e. 443 for SSL, and forward all subsequent traffic to this host and port.
  2. Read the response from the proxy, it should be a line saying “200 Tunnel Established”
  3. Pass the stream to a SSL stream object, and call AuthenticateAsClient
  4. Send HTTP data as normal.

Here’s some code to connect to ICanHazIP via SSL.

private static string TestIp(WebProxy proxy)
{
var tcp = new TcpClient(proxy.Address.Host, proxy.Address.Port);
var stream = tcp.GetStream();
var connect = Encoding.ASCII.GetBytes(“CONNECT http://www.icanhazip.com:443 HTTP/1.0\n\n”);
stream.Write(connect, 0, connect.Length);
var rawStream = new StreamReader(stream);
var strConnect = rawStream.ReadLine();
var ssl = new SslStream(stream);
ssl.AuthenticateAsClient(“www.icanhazip.com”);
var send = Encoding.ASCII.GetBytes(“GET / HTTP/1.0\r\n” +
“Host:www.icanhazip.com\r\n” +
“\r\n”);
ssl.Write(send, 0, send.Length);
var sr = new StreamReader(ssl);
var str = sr.ReadToEnd();
tcp.Close();
ssl.Close();
return str;
}

If you’re interested in low level socket programming in C#, check out by book:

Advertisements
Categories: Uncategorized

Access UK TV #EPG via #JSON

November 13, 2017 1 comment

iplayerfreesat02

If you are developing an app or website that allows people check television guides in the UK, then this API may help you out.

First, a list of 576 TV channels from the UK can be listed via this Rest API call;

http://tv.apixml.net/api.aspx?action=channels

Then, to get details of programs to be shown on this channel, then you can use the url;

http://tv.apixml.net/api.aspx?action=program&channelid=03c9f88a54910f471bb80c039e2a8fa1

Where channelId is obtained from the previous call. The schedule is always for the next 24 hours.

This API will be built into out TV UK app for iOS: https://itunes.apple.com/us/app/tv-uk/id464570844?mt=8

 

 

 

Categories: Uncategorized

Sending a base64 encoded file using #SMTP.js

November 10, 2017 Leave a comment

smtpjs

SMTPjs.com is a javascript library that allows you send email through Javascript. – You still need access to a outgoing mail (SMTP) server, but this makes life a little easier for your JS apps.

Today, we released v2.0.1 of the library, which has a few important fixes

  • The message body is no longer limited in size
  • There is now an optional callback parameter, that allows your code continue after the email is sent.
  • Attachments can be sent in base 64 format (dataURI) to the library.

Previous versions of the library will continue to be functional, but we recommend upgrading to the latest version.

Callback feature:

Depending on whether you use a stored token, or send your SMTP credentials with every request, then you use one of the two following blocks of code:

Email.send(“from@you.com”,
“to@them.com”,
“Subject”,
“Body”,
“smtp.server.com”,
“username”,
“password”,
function done(message) { alert(“sent”) }
);

or, when using stored credentials;

Email.send(“from@you.com”,
“to@them.com”,
“Subject”,
“Body”,
{
token: “your-token”,
callback:function done(message) { alert(“sent”) }
});

DataUri Attachments

Previously, in order to send an attachment with this script, then the file you needed to send needed to be already hosted online. This, may not be ideal, if you wanted your user to select a file from their device, or otherwise dynamically generate the file to be sent.

So, let’s imagine we want the user to select a file to be sent from their device, we add a form element as follows;

<input type=”file” id=”fileupload” onchange=”uploadFileToServer()” />

Then define the function uploadFileToServer as follows:

function uploadFileToServer() {
var file = event.srcElement.files[0];
console.log(file);
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function () {
var datauri = “data:” + file.type + “;base64,” + btoa(reader.result);
Email.sendWithAttachment(“from@you.com”,
“to@them.com”,
“Subject”,
“Body”,
“smtp.server.com”,
“username”,
“password”,,
datauri,
function done(message) { alert(“Message sent OK”) }
);
};
reader.onerror = function() {
console.log(‘there are some problems’);
};
}

Categories: Uncategorized

#Translate any country name into any language in C#

November 10, 2017 Leave a comment

WordPress-Theme-Translation

If you have a multi-lingual app or website that needs to show a drop down list of country names, then it suddenly adds 195 words to your translation file, which is going to make your translation word count shoot up suddenly.

Surely, someone else has done this already?, yes, they have. The Unicode consortium have a public file that you can download that contains a list of countries, and lots of other information translated into many different languages; here; http://unicode.org/Public/cldr/1.7.0/core.zip

I extracted the two letter files ({language}.xml) from core/common/main, removed the dtd definition, and put it in to a folder named /data/localisation off the root of my website.

public static string Country(string code, string culture)
{
// Source: http://unicode.org/Public/cldr/1.7.0/core.zip
var locale = new CultureInfo(culture).TwoLetterISOLanguageName.ToLower();
var strLocalXmlFile = HttpContext.Current.Server.MapPath(“/data/Localisation/” + locale + “.xml”);
var xdoc = new XmlDocument();
xdoc.Load(strLocalXmlFile);
var xn = xdoc.SelectSingleNode(“//territory[@type='” + code + “‘]”);
return xn.InnerText;
}

Then you can call Country(“GB”,”sv-SE”) to get Storbritannien

Of course, there is many more things that you may want to translate, and nothing is better than a human translator, which I’d recommend OutsourceTranslation.com to find one.

Categories: Uncategorized

Protect yourself from #IAP #Fraud com.zeptolab.ctrbonus.superpower1

November 7, 2017 Leave a comment

maxresdefault

IAP or In app Purchases is now the most popular way App developers get paid for their apps. Most IAPs don’t actually incur added cost the developer when used, such as unlocking extra levels, or power ups, but some activate real-world services, and can incur added server costs to the developer – such as extra file storage, or paid-for API calls.

This is why you really need to ensure that you validate your IAP receipt from apple, to ensure that it has indeed come from apple, and not a replay attack from someone else’s IAP.

I received this IAP receipt that failed validation this morning:

ewoJInNpZ25hdHVyZSIgPSAiQXBkeEpkdE53UFUyckE1L2NuM2tJTzFPVGsyNWZlREthMGFhZ3l5UnZlV2xjRmxnbHY2UkY2em5raUJTM3VtOVVjN3BWb2IrUHFaUjJUOHd5VnJITnBsb2YzRFgzSXFET2xXcSs5MGE3WWwrcXJSN0E3ald3dml3NzA4UFMrNjdQeUhSbmhPL0c3YlZxZ1JwRXI2RXVGeWJpVTFGWEFpWEpjNmxzMVlBc3NReEFBQURWekNDQTFNd2dnSTdvQU1DQVFJQ0NHVVVrVTNaV0FTMU1BMEdDU3FHU0liM0RRRUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURXpNREVHQTFVRUF3d3FRWEJ3YkdVZ2FWUjFibVZ6SUZOMGIzSmxJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEE1TURZeE5USXlNRFUxTmxvWERURTBNRFl4TkRJeU1EVTFObG93WkRFak1DRUdBMVVFQXd3YVVIVnlZMmhoYzJWU1pXTmxhWEIwUTJWeWRHbG1hV05oZEdVeEd6QVpCZ05WQkFzTUVrRndjR3hsSUdsVWRXNWxjeUJUZEc5eVpURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFNclJqRjJjdDRJclNkaVRDaGFJMGc4cHd2L2NtSHM4cC9Sd1YvcnQvOTFYS1ZoTmw0WElCaW1LalFRTmZnSHNEczZ5anUrK0RyS0pFN3VLc3BoTWRkS1lmRkU1ckdYc0FkQkVqQndSSXhleFRldngzSExFRkdBdDFtb0t4NTA5ZGh4dGlJZERnSnYyWWFWczQ5QjB1SnZOZHk2U01xTk5MSHNETHpEUzlvWkhBZ01CQUFHamNqQndNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqQkJnd0ZvQVVOaDNvNHAyQzBnRVl0VEpyRHRkREM1RllRem93RGdZRFZSMFBBUUgvQkFRREFnZUFNQjBHQTFVZERnUVdCQlNwZzRQeUdVakZQaEpYQ0JUTXphTittVjhrOVRBUUJnb3Foa2lHOTJOa0JnVUJCQUlGQURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQUVhU2JQanRtTjRDL0lCM1FFcEszMlJ4YWNDRFhkVlhBZVZSZVM1RmFaeGMrdDg4cFFQOTNCaUF4dmRXLzNlVFNNR1k1RmJlQVlMM2V0cVA1Z204d3JGb2pYMGlreVZSU3RRKy9BUTBLRWp0cUIwN2tMczlRVWU4Y3pSOFVHZmRNMUV1bVYvVWd2RGQ0TndOWXhMUU1nNFdUUWZna1FRVnk4R1had1ZIZ2JFL1VDNlk3MDUzcEdYQms1MU5QTTN3b3hoZDNnU1JMdlhqK2xvSHNTdGNURXFlOXBCRHBtRzUrc2s0dHcrR0szR01lRU41LytlMVFUOW5wL0tsMW5qK2FCdzdDMHhzeTBiRm5hQWQxY1NTNnhkb3J5L0NVdk02Z3RLc21uT09kcVRlc2JwMGJzOHNuNldxczBDOWRnY3hSSHVPTVoydG04bnBMVW03YXJnT1N6UT09IjsKCSJwdXJjaGFzZS1pbmZvIiA9ICJld29KSW05eWFXZHBibUZzTFhCMWNtTm9ZWE5sTFdSaGRHVXRjSE4wSWlBOUlDSXlNREV5TFRBM0xURXlJREExT2pVME9qTTFJRUZ0WlhKcFkyRXZURzl6WDBGdVoyVnNaWE1pT3dvSkluQjFjbU5vWVhObExXUmhkR1V0YlhNaUlEMGdJakV6TkRJd09UYzJOelU0T0RJaU93b0pJbTl5YVdkcGJtRnNMWFJ5WVc1ellXTjBhVzl1TFdsa0lpQTlJQ0l4TnpBd01EQXdNamswTkRrME1qQWlPd29KSW1KMmNuTWlJRDBnSWpFdU5DSTdDZ2tpWVhCd0xXbDBaVzB0YVdRaUlEMGdJalExTURVME1qSXpNeUk3Q2draWRISmhibk5oWTNScGIyNHRhV1FpSUQwZ0lqRTNNREF3TURBeU9UUTBPVFF5TUNJN0Nna2ljWFZoYm5ScGRIa2lJRDBnSWpFaU93b0pJbTl5YVdkcGJtRnNMWEIxY21Ob1lYTmxMV1JoZEdVdGJYTWlJRDBnSWpFek5ESXdPVGMyTnpVNE9ESWlPd29KSW1sMFpXMHRhV1FpSUQwZ0lqVXpOREU0TlRBME1pSTdDZ2tpZG1WeWMybHZiaTFsZUhSbGNtNWhiQzFwWkdWdWRHbG1hV1Z5SWlBOUlDSTVNRFV4TWpNMklqc0tDU0p3Y205a2RXTjBMV2xrSWlBOUlDSmpiMjB1ZW1Wd2RHOXNZV0l1WTNSeVltOXVkWE11YzNWd1pYSndiM2RsY2pFaU93b0pJbkIxY21Ob1lYTmxMV1JoZEdVaUlEMGdJakl3TVRJdE1EY3RNVElnTVRJNk5UUTZNelVnUlhSakwwZE5WQ0k3Q2draWIzSnBaMmx1WVd3dGNIVnlZMmhoYzJVdFpHRjBaU0lnUFNBaU1qQXhNaTB3TnkweE1pQXhNam8xTkRvek5TQkZkR012UjAxVUlqc0tDU0ppYVdRaUlEMGdJbU52YlM1NlpYQjBiMnhoWWk1amRISmxlSEJsY21sdFpXNTBjeUk3Q2draWNIVnlZMmhoYzJVdFpHRjBaUzF3YzNRaUlEMGdJakl3TVRJdE1EY3RNVElnTURVNk5UUTZNelVnUVcxbGNtbGpZUzlNYjNOZlFXNW5aV3hsY3lJN0NuMD0iOwoJInBvZCIgPSAiMTciOwoJInNpZ25pbmctc3RhdHVzIiA9ICIwIjsKfQ

Running it through my IAP receipt validator I got this;

{ “receipt”: { “original_purchase_date_pst”: “2012-07-12 05:54:35 America/Los_Angeles”, “purchase_date_ms”: “1342097675882”, “original_transaction_id”: “170000029449420”, “original_purchase_date_ms”: “1342097675882”, “app_item_id”: “450542233”, “transaction_id”: “170000029449420”, “quantity”: “1”, “bvrs”: “1.4”, “version_external_identifier”: “9051236”, “bid”: “com.zeptolab.ctrexperiments”, “product_id”: “com.zeptolab.ctrbonus.superpower1“, “purchase_date”: “2012-07-12 12:54:35 Etc/GMT”, “purchase_date_pst”: “2012-07-12 05:54:35 America/Los_Angeles”, “original_purchase_date”: “2012-07-12 12:54:35 Etc/GMT”, “item_id”: “534185042” }, “status”: 0 }

Where I’ve highlighted com.zeptolab.ctrbonus.superpower1 – Which looks like ZeptoLab’s Cut the Rope Super Power 1 from 2012!,  Not the IAP I was expecting at all.

Thankfully my validator code spotted this.

Here’s the code for decoding an Apple receipt in c#

private const string urlProduction = “https://buy.itunes.apple.com/verifyReceipt&#8221;;
private const string urlSandbox = “https://sandbox.itunes.apple.com/verifyReceipt&#8221;;

private string Verify(string receipt, string serviceUrl, string sharedSecret)
{
var json = string.Format(“{{\”receipt-data\”:\”{0}\”,\”password\”:\”{1}\”}}”, receipt, sharedSecret);
var wr = WebRequest.Create(serviceUrl);
wr.ContentType = “text/plain”;
wr.Method = “POST”;
var sw = new System.IO.StreamWriter(wr.GetRequestStream());
sw.Write(json);
sw.Flush();
sw.Close();
var wresp = wr.GetResponse();
if (wresp != null)
{
var sr = new System.IO.StreamReader(wresp.GetResponseStream());
var response = sr.ReadToEnd();
sr.Close();
return response;
}
return “no-data”;
}

 

 

Categories: Uncategorized