Core to Push notification

Hi,
I want to use the cloud PushingBox.com to send Push notifications on my phone.
Anyone had already tried something ?

Hi @clem

What an interesting service that PushingBox.com is! You can email, tweet, send growl notifications etc. from small micros on the net using http GET or POST. I tried it quickly with email notifications using curl and I think it would be trivial to do this from the Spark Core.

I do worry about PushingBox.com’s security, or lack thereof. The only security is the obscurity of the hex ID that you send in your URL GET or POST request. I guess the good news is that worst attackers can do is send you notifications that you have preprogrammed.

The primary thing you need is code like this:

void sendGetRequest(const char * server, const char * url)
{
    if (myTCP.connect(server, 80)) {
        //Serial1.print("Connected to Server");
        //digitalWrite(D7,HIGH);
        myTCP.print("GET ");
        myTCP.print(url);
        myTCP.println(" HTTP/1.0");
        myTCP.println("Connection: close");
        myTCP.print("Host: ");
        myTCP.println(server);
        myTCP.println("Accept: text/html, text/plain");
        myTCP.println();
        myTCP.flush();
    } 
}
2 Likes

Thank you @bko
I’ll try as soon as I can

For smartphone/tablet push notification, prowl is good, as the api uses https. However, that's problematic with the spark, as there is no library for doing https negotiation (and it's possible that one might never appear).

Edit: for home use, it's probably easier to have the spark send some simple/insecure notification to a raspberry pi, which then does the secure notification forwarding.

Although doing https directly on the core is a bit tricky (with the security overhead), I think it’d be totally feasible to include https support on server-side postbacks

The PushingBox.com service takes in http GET and POST requests without authorization, but with a secret “devid” and then acts as a forwarding proxy to do oauth Twitter posts, or https growl notifications or email, etc. In this way, it is not too different from MailGun or other services that do the action over SSL/TLS connection for you.

So the PushingBox.com server is the secure forwarding service or proxy that @Raldus wants his RaspberryPi to be. I think @Raldus is right that I would personally rather have that forwarding service under my control, since it needs to have my credentials for whatever notification service I am using. But the worst an attacker would seem to be able to do is send bogus notifications.

The only advantage of PushingBox.com is that it is free and here right now with little or no setup. I don’t see how it can be free forever and I would think they will need rate throttling to scale up.

I worked in a company long ago that had the outside temperature from a local thermometer available as a widget at the bottom of your screen. The guy that set this up would occasionally have what he called “firestorms” or “Martian weather” when he would fudge the reading to make it go up to thousands of degrees or down to -200 degrees F slowly over time!

1 Like

No, you misunderstand. I want the communications to be secure, from one end to the other. If pushingbox uses plain http, and not https (or something else like ssh), it’s insecure. “Secret devid’s” are sniffable, and is just a means of insecure “security through obscurity”. Using an insecure channel from the spark to some “secure forwarding service” only/kinda/sorta works if the insecure channel is in your “protected” network (like maybe your home network). If the insecure channel has to go outside and hit the insecure internet to reach the “secure forwarding service”, that’s not secure. The key idea is that the information must be secured by the time it hits the internet, and that is not true if http is used, regardless if “secret devids” are used.

Insecure:

  • spark (insecure http, inside your network) --> Internet --> notification service --> smartphone/tablet

More secure:

  • spark (insecure http, inside your network) --> raspberry pi (secure https) --> Internet --> notification service --> smartphone/tablet

Of course, there’s no guarantee that the notification service --> smartphone/tablet link is secure, but we can hope. :smile:

Perhaps I’m not understanding how pushingbox works, but it seems to only allow predefined messages called “scenarios”, but with variable substitution – you can’t send arbitrary messages. Other notifications like prowl or pushover allow you to send arbitrary messages, and do not restrict you to messages that you have predefined.

Also, being free really isn’t an advantage. Other notification services like prowl or pushover also have free tiers. I especially like prowl, because they allow something like 700000 notifications/month (1000/hour, actually), and each message can be up to 10000 bytes in size. Pushover’s free tier has a limit of something like 7500 notifications/month with a max message size of 512 bytes; on the other hand, pushover is supported by IFTTT, whereas prowl isn’t.

Hi @Raldus

I think we are in violent agreement here!:smiley: The PushingBox.com service is completely bankrupt in terms of over-the-air or wire security. In my first post, I said: [quote=“bko, post:2, topic:2499”]
The only security is the obscurity of the hex ID that you send in your URL GET or POST request.
[/quote]

In addition to all the points you raise, I tried to say that I have to give Pushingbox my credentials or permissions in the form of say an oauth key for Twitter. Should I trust them? I don’t know. This is bad.

The only saving grace is that notifications may not need to be as secure as other things you might do.

My other point is that since we cannot (yet!) do SSL/TLS on the core, any user-code link from the core to the first encrypted host is vulnerable. I think the best thing would be for :spark: to offer a service like Pushingbox that uses their crypto as part of their future business model. The problem with general SSL/TLS is the certificate and key management and if :spark: cores have room for only one cert/key, then having that host be the trusted proxy is really the only workable solution today.

Publishing events generated on a :spark: Core is bubbling, bubbling up to the top of our backlog. We discussed it when planning the current sprint, but there were too many high priority items ahead of it.

I think it’s reasonable to expect the first version of a secure postback from the Spark Cloud within 5–9 weeks, i.e., two to four sprints down the road.

4 Likes

I recently came across stunnel which is exactly the kind of secure SSL tunnel you need on your local host to bridge from unencrypted :spark: core to SSL/TLS host on the net.

Not open-source but generously licensed for personal use. Runs on lots of platforms, but Debian or Raspian are not listed, so there might be some work to do in porting.

@bko Given that you have to run stunnel on another system, it’s probably easier (for basic smartphone/tablet notification) to just have a simple/free notification service running on, well, another system. Send a simple message to another (trusted) local system, (e.g., raspberry pi) and that system can securely forward the message to the smartphone/tablet notification service.

Heck, if you don’t mind using a windows box, you could have the spark send old-style growl UDP messages to growl-for-windows (running on the windows box), which should then forward the message on to your smartphone/tablet. It’s a little work, as md5 checksums have to be computed, but it should work (as long as the spark’s UDP code works properly).

1 Like

I wanted to resurrect this old thread since pushingbox.com just launched an indiegogo funding campaign for their Notifon hardware.

It is a central hub plus a zigbee-based wireless network to sensors or “nodes” and the pushingbox.com service. The early backer price is $124 for a hub and a node. Later backers get it for $139.

This strikes me as pretty pricey given what our beloved :spark: can do and somewhat high relative to Supermechanical’s twine since each sensor needs a node. I don’t think they have improved their security model, either.

They have a nice power architecture though… low power… very simple to think about when it’s battery powered and doesn’t require much thought after that. Pretty simple node activities though. “Notifon is universal. You can use any sensor that has two states, such as a switch, a push button, a magnetic door switch, a relay… Notifon allows you to predefine a set of actions for each state.” so it’s pretty “dumb”.

Cant wait to receive my core, i plan on making my own Notifon for a third of the price!. I already have PushingBox set up with the services and scenarios I want. Spark build has my app ready to flash

Doorbell will

  • notify my phone immediately(ish) using Newtifry (Pro once i figure it out with Pushingbox)
  • communicate with my media player to display the live video in the bottom corner of the screen

Snail Mail will

  • alert me with an email
  • pop up a message on my media player

Once i get this set up ill make try and make a utility monitor, that will notify me of unexpected water use or gas use - ie when the alarm is set.

1 Like

Hi Guys,
Can anyone help me with some code that will let me send a notification thru pushing box?
I’ve been trying to do a similar thing with Prowl, but haven’t gotten very far. Looks like some of you have the pushing box notification working…
Thanks,
Jim

Try this, it should work, but I didn’t get a chance to test it:

const char server[] = "api.pushingbox.com";
const char url[] = "/pushingbox?devid=v0123456789ABCDE";  //replace with your devid
TCPClient myTCP;

void setup() {

}

void loop() {
    sendGetRequest(server, url);
    delay(10000); //be nice every 10 seconds
}

void sendGetRequest(const char * server, const char * url)
{
    if (myTCP.connect(server, 80)) {
        myTCP.print("GET ");
        myTCP.print(url);
        myTCP.println(" HTTP/1.0");
        myTCP.println("Connection: close");
        myTCP.print("Host: ");
        myTCP.println(server);
        myTCP.println("Accept: text/html, text/plain");
        myTCP.println();
        myTCP.flush();
    } 
}

PushingBox seems to just be a wrapper for other services like Prowl:

As others have pointed out a less secure one as well, using HTTP.

It seems like it would be most efficient to use HTTPS to communicate directly with Prowl. Since Push Notifications are a big part of IoT connectivity, I would be interested to know what the Spark Team’s vision is for the easiest path to achieve this feature with the Spark Core.

I definitely don’t want to have a computer up and running in my house 24-7 acting as a middle man between my IoT device (Spark Core) and the internet.

@zachary now that Spark.publish() is out, how do you see this filling the need here? Will Tinker get an overhaul that will allow it to subscribe to published events? I.e., using the Spark platform, you can be push notified directly (forget Prowl).

BKO,
Thanks buddy, it’s up and running, and quicker than the email notification I was using.
I’ll still try to get prowl to work, since right now I’m telling Pushingbox to tell Prowl to notify my iPhone.
I’m trying to lessen the number of steps to get the best response time.
Jim

Right now, the most secure way is to use a proxy, since the spark can't do https. One way is to have the spark send (insecure) messages to a pc running growlforwindows, and growlforwindows can handle the secure messaging part to prowl.

(I have partially-working code for this. It successfully sends one message then asplodes trying to send another one. Can someone point me to the post that describes the blinking LED colors? I'm getting a flashing red followed by a partial reboot (breathing cyan but program is dead).)

This is what i plan on using when i get my core… completely untested, but derived from other forum posts. I could have done the XBMC part thru pushing box too and saved a fair amount of code, but i can use an internal ip for the server and leave the internet part out and have it more secure…

int doorbell = D0; // Doorbell button connects to D0 on the core
unsigned long Lockout; // used to stop flooding servers

// XBMC Setup
char xbmcServer[] = "enter.server.here";
int xbmcPort = 80;
char xbmcScript[] = "/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22Addons.ExecuteAddon%22,%22params%22:{%22addonid%22:%22script.securitycam%22},%22id%22:%221%22}}";
char xbmcUser[] = "Uesrname";
char xbmcPass[] = "Password";

// Pushing Box Setup
char serverName[] = "api.pushingbox.com";
char deviceID[] = "EnterDeviceIDhere";

void setup() {
    
    pinMode(doorbell, INPUT_PULLUP); // other side of doorbell will connect to ground to pull low
    Lockout = millis();

}

void loop() {
    
    if (millis() >= Lockout){  // check how long its been since last pushed
        if(digitalRead(doorbell) == LOW) {  //read the doorbell button
            delay(50);
            if(digitalRead(doorbell) == LOW) {  // debounce check again to make sure 
                Lockout = millis() + 15000; // set up the lockout period 15 seconds before it will run again
                runXbmcScript(xbmcServer, xbmcPort, xbmcScript, xbmcUser, xbmcPass);  // opens up a script in xbmc that displays an ip camera 
                sendToPushingBox(serverName, deviceID); // sends push notification to mobile phone or sends email using pushingbox
            }
        }
    }

}


void runXbmcScript(char *hostname, int port, char *url, char *username, char *password) {
  TCPClient client;
  client.connect(hostname, port);
  client.print("GET ");
  client.print(url);
  client.println("HTTP/1.0");
  client.print("Host: ");
  client.println(hostname);
  if (username != NULL) {
    //NOTE! make sure username and password are already base64 encoded here!
    client.print("Authorization: Basic ");
    client.print(String(username) + String(":") + String(password));
  }
  client.println("Content-Length: 0");
  client.println();
  client.flush();
  client.stop();
}

void sendToPushingBox(char *serverName, char *deviceID) {
    TCPClient client;
    client.connect(serverName, 80);
    client.print("GET /pushingbox?devid=");
    client.print(deviceID);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(serverName);
    client.println("User-Agent: Arduino");
    client.println();
    client.flush();
    client.stop(); 
  }