I need help putting together a POST/PUT/GET request for my ESP32 - httpclient

Can someone post an example code for sending data in a URL using HTTPClient on a ESP32 (I'm using dweet as an example, I have a different site)?
Say I have a sensor data of temperature (24'C - nevermind the "'C", sensor only shows the number which is what I want) and humidity (30%) and want to send those as URL like this: http://dweet.io/sensor.php?temperature=24&humidity=30
I guess header should be "HTTP/1.0".
Ways to send over HTTPS without CA or fingerprint would also be helpful.
Practices to avoid memory leaks and to prevent errors or crashes would be a delightful bonus. :-)

You might find the protocol examples provided by ESP-IDF to be very helpful. And there are some tutorials that help with writing those requests as well.
If you do not want to use a CA and just want to have https for testing purposes, then I have found the https-mbedtls example provided by ESP-IDF to be very helpful here, as there is an option to optionally verify the certificate. MBEDTLS_SSL_VERIFY_OPTIONAL can be set to MBEDTLS_SSL_VERIFY_NONE in the https_mbedtls_example_main.c file meaning that you can use self-signed certificates without receiving an error.

Related

How to configure Big Blue Button for Xirsys TURN server?

I run an self-hosted instance of BigBlueButton and signed up for Xirsys TURN server services because we need to serve clients behind (pretty restrictive) firewalls. Before I had been running my own instance of coturn, but as this led to problems recently, I thought I will got someone who does this for a living a try.
Now the configuration in BBB is explained here:
https://docs.bigbluebutton.org/2.2/setup-turn-server.html
Yet so far I completely failed to match the parameters I receive from Xirsys with what I have to put into the /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml file in the place of the <turn.example.com> and <secret_value>.
Did anyone ever make this work? I did try and find a tutorial but also failed.
bbb_web, is returning this the turn uris. passwords to the html5 client, that the client is using in sip.js
so you can either get bbb-web to send valid username/passwords is same method is used, or modify the html5 client to make a Xirsys api call, to get access to the turn candidates.
Would need to look at api docs. twilio has a similar service.
regards,
Stephen
not the most elegant solution but the easiest one for me:
modify the final bbb js bundle to load the stunturn info from a fixed url in
e.g.
/usr/share/meteor/bundle/programs/web.browser/f30716b2b57e2862c4db2325 b7aac63f4622842b.js
the minified part should then look somewhat like:
const r=Meteor.settings.public.media,i='https://<yourbbburl>/html5client/stunturn.json',a=r.cacheStunTurnServers,s=r.fallbackStunServer;
and put either the static credentials or generated ones in a file stunturn.json besides the js bundle.

Determining if a request came from an iPhone app

I have an iPhone app that communicates with a server (both of which I own and wrote the code for). I need to way to determine if a request on my server came from an iPhone (or any mobile device running the app I wrote for that matter). Basically, I only want to allow apps that I wrote to communicate with the server and need a way to verify that. Since I'm writing the apps, I can modify the headers and what not any way I need to.
I read up a little on Public Key Encryption, but I don't think it'd work. If I sent some sort of secret hashed word in my headers to verify it, couldn't some outside party simply get those headers and use the same ones in their request?
You can use a checksum. Let's say that you have something like:
date
subject
and calculate the checksum by using, let's say MD5 of (date + "string" + subject),
and you calculate the MD5 in the very same way on the server. If they match, they are from the mobile client.
This will work until someone figures out your algorithm.
You could have your server send a message to your app that contains a random code. This message and code changes every time it is sent.
Your app then does some kind of algorithm on that message to "encrypt" it and send it back to the server and the server can then check it. That way there's nothing to intercept and use without knowing your "encryption".
Of course, they could intercept the message from each direction and then work out your algorithm, but if you make it sufficiently difficult, then that would be a while.
You could just use HTTP Basic authentication, unless you needed something more secure.

How did PUSH / APNS works?

I read a few tutorials / howtos about Apples Push Notifications, but there are a lot of information out there, so I wanna know if I understand everything correct.
Here is how I understand it:
You need a certificate for Puhs, you can get it in the development center (found very good tutorials for it)
You need a database in which the DeviceToken is stored. This you can set into the database from your application itself (found a tutorial for that I think)
When a user should get a message (e.g. gets a Private Message or something like this) you must send a PHP Payload to the apple server.
Is that all? (I know its a much longer, I only wanna know if I understand everything right).
Must I do any other thing on the client side else then save the device token to the database?
Yes you pretty much have it there. If looking at sending large volumes then make sure that you are not opening and closing the connection to the Apple APNS servers as they treat it as a DOS attack.
The payload is also not PHP but JSON.
Also make sure you read from the feedback service and deactivated device tokens and stop sending them messages.
Client side you also need to "decode/process" the payload in the various app delegate places. Essentially it is a discretionary and you can send custom info as part of the APNS payload.

How to send data to webserver and know it comes from a certain application?

I'm trying to send data from my application to a webserver.
The catch is that I want to encrypt the sent data and also make sure it comes from my application. (From what I've read so far it's easy to decrypt the data if it's not sent via HTTPS. On the unique application I didn't find anything except the Application ID Apple provides for each application but I don't know how that works).
The data sent are various highscores and achievements that the user can enable. The thing is that the user doesn't have to type in anything but his username and having that associated with the UDID it should be enough.
But how to make sure it's from my application?
Edit:After reading some responses around here I still didn't understand something:
If someone extracts the IPA and reverse engineers it wouldn't he have access to all my .h and .m so he can look up anything in there?
You could generate a client certificate for the iPhone app, and use mutual authentication for your SSL handshake. Then you know that data submitted to the server come from a particular user of the app, and that your app is communicating with the correct server.
Regarding your edited update, yes if someone reverse-engineeres your app they can probably work out how the high-scores are protected. But seriously, how much trouble do you expect most people to go to in order to fake a high score in a game? Are you offering a cash prize or something?
If you are using HTTPS then you can just put an identifier key in your POST to the web server, either as a field or perhaps an HTTP header that identifies your app. The entire connection is encrypted so it will be protected. If you do this you will want to encrypt the key even in your binary and decrypt it as you send it over the connection, that way no one will be able to pull it out with a hex editor.
Another approach if all you want is to know that the data comes from an authentic instance of your application is to use message authentication codes (MAC). I leave deciding how strongly the key needs protecting as an exercise to the reader - you know your security requirements better than I do.
You can use CommonCrypto - part of the iOS SDK since forever - to actually generate the MAC.

Best practice to detect iPhone app only access for web services?

I am developing an iPhone app together with web services. The iPhone app will use GET or POST to retrieve data from the web services such as http://www.myserver.com/api/top10songs.json to get data for top ten songs for example.
There is no user account and password for the iPhone app. What is the best practice to ensure that only my iPhone app have access to the web API http://www.myserver.com/api/top10songs.json? iPhone SDK's UIDevice uniqueueIdentifier is not sufficient as anyone can fake the device id as parameter making the API call using wget, curl or web browsers.
The web services API will not be published. The data of the web services is not secret and private, I just want to prevent abuse as there are also API to write some data to the server such as usage log.
What you can do is get a secret key that only you know, Include that in an md5 hashed signature, typically you can structure signatures as a s tring of your parameters a nd values and the secret appended at the end, then take the md5 hash of that...Do this both in your client and service side and match the signature string, only if the signatures match do you get granted access...Since t he secret is only present i n the signature it w ill be hard to reverse engineer and crack..
Here's an expansion on Daniel's suggestion.
Have some shared secret that the server and client know. Say some long random string.
Then, when the client connects, have the client generate another random string, append that to the end of the shared string, then calculate the MD5 hash.
Send both the randomly generated string and the hash as parameters in the request. The server knows the secret string, so it can generate a hash of its own and make sure it matches the one it received from the client.
It's not completely secure, as someone could decompile your app to determine the secret string, but it's probably the best you'll get without a lot of extra work.
Use some form of digital signatures in your request. While it's rather hard to make this completely tamper proof (as is anything with regard to security). It's not that hard to get it 'good enough' to prevent most abuse.
Of course this highly depends on the sensitivity of the data, if your data transactions involve million dollar transactions, you'll want it a lot more secure than some simple usage statistic logging (if it's hard enough to tamper and it will gain little to no gain to the attacker except piss you of, it's safe to assume people won't bother...)
I asked an Apple security engineer about this at WWDC and he said that there is no unassailable way to accomplish this. The best you can do is to make it not worth the effort involved.
I also asked him about possibly using push notifications as a means of doing this and he thought it was a very good idea. The basic idea is that the first access would trigger a push notification in your server that would be sent to the user's iPhone. Since your application is open, it would call into the application:didReceiveRemoteNotification: method and deliver a payload of your own choosing. If you make that payload a nonce, then your application can send the nonce on the next request and you've completed the circle.
You can store the UDID after that and discard any requests bearing unverified UDIDs. As far as brute-force guessing of necessary parameters, you should be implementing a rate-limiting algorithm no matter what.
A very cheap way to do this could be getting the iPhone software to send extra data with the query, such as a long password string so that someone can't access the feed.
Someone could reverse engineer what you have done or listen to data sent over the network to discover the password and if bandwidth limitations are the reason for doing this, then a simple password should be good enough.
Of course this method has it's problems and certificate based authentication will actually be secure, although it will be harder to code.
The most secure solution is probably a digital signature on the request. You can keep a secret key inside the iPhone app, and use it to sign the requests, which you can then verify on the server side. This avoids sending the key/password to the server, which would allow someone to capture it with a network sniffer.
A simple solution might be just to use HTTPS - keeping the contents of your messages secure despite the presence of potential eavesdroppers is the whole point of HTTPS. I'm not sure if you can do self-signed certificates with the standard NSURLConnection stuff, but if you have a server-side certificate, you're at least protected from eavesdropping. And it's a lot less code for you to write (actually, none).
I suppose if you use HTTPS as your only security, then you're potentially open to someone guessing the URL. If that's a concern, adding just about any kind of parameter validation to the web service will take care of that.
The problem with most if not all solutions here is that they are rather prone to breaking once you add proxies in the mix. If a proxy connects to your webservice, is that OK? After all, it is probably doing so on behalf of an iPhone somewhere - perhaps in China? And if it's OK for a proxy to impersonate an iPhone, then how do you determine which impersonations are OK?
Have some kind of key that changes every 5 minutes based on an algorithm which uses the current time (GMT). Always allow the last two keys in. This isn't perfect, of course, but it keeps the target moving, and you can combine it with other strategies and tactics.
I assume you just want to dissuade use of your service. Obviously you haven't set up your app to be secure.