Go Down

Topic: [HELP] More secure Ethercard login. (Read 446 times) previous topic - next topic

quikk

Hello guys. I am working on a project for my home. I need to make a more secure login. I would want to not show the user and the password on the URL when I log in. I mean when you log in the url is http://192.168.1.203/?username=admin&password=adminpassword.
I want to hide that.


This is my code:

Code: [Select]

#include <EtherCard.h>
#include <DS1302.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
#include<Wire.h>
#include<EEPROM.h>

unsigned long taimer;

#define lrojo 8
#define lamarillo 9
#define lverde 10


DHT dht (7, DHT22);
DS1302 rtc(2, 3, 4);
Time tiempo;
LiquidCrystal_I2C lcd(0x27,16,2);

static BufferFiller bfill;
byte Ethernet::buffer[1100];   

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,1,203 };
static byte gwip[] = { 192,168,1,1 };
const  char website[] PROGMEM = "********.sytes.net";
static byte hisip[] = { **,***,**,*** };

byte ledstatus = EEPROM.read(0);
boolean logged = false;
char user[6];
char pass[6];
char pwm[4];

int temp = 0;
int hum = 0;

//------USER & PASS------//
char _USER[6]="admin";
char _PASS[10]="*****";
//-----------------------//

static int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void init_lcd();
void readvalues();
void print_lcd();


void setup() {

Serial.begin(9600);
ether.begin(sizeof Ethernet::buffer, mymac);
 ether.staticSetup(myip);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
if(ledstatus == HIGH){

    digitalWrite(lrojo,HIGH);

}
else if(ledstatus == LOW){
 

    digitalWrite(lrojo,LOW);

 
  }

rtc.writeProtect(true);

dht.begin();
//init_lcd();
}



const char okHeader[] PROGMEM =
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
;

static void homePage(BufferFiller& buf, byte led) {

    Time homepage_t = rtc.getTime();
    char* timehome = rtc.getTimeStr();
    char* onoff;
    long t = millis() / 1000;
    word h = t / 3600;
    byte m = (t / 60) % 60;
    byte s = t % 60;
  if(ledstatus == HIGH){
   
      onoff = "on";
     
   
    }
    else if(ledstatus == LOW){

      onoff = "off";
     
    }
    else{

      onoff = "null";
     
    }
      buf.emit_p(PSTR("$F\r\n"
        "<meta http-equiv='refresh' content='$D'/>"
        "<body style=background-color:#bfbfbf>"
        "<title>Arduino Server</title>"
        "<hr>"
        "<h2 align='center'><big>$S</big></h2>"
        "<hr>"
        "<body align=center><h2 align='center'>Calefaccion: $S</br>"
        "<a href='?led=1'>Encender</a><br>"
        "<a href='?led=0'>Apagar</a> </br></h2>"), okHeader, 500,timehome, onoff);
   
     buf.emit_p(PSTR(
        "<table border='0' align='center' width='25%' text-align='center'>"
        "<tr><td bgcolor='#fcfcfc'><h3 align=center><big>Temperatura</big></h3></td><td bgcolor='#fcfcfc'><h2 align='center'><big>$D C</big></h2></tr>"
        "<tr><td bgcolor='#fcfcfc'><h3 align='center'><big>Humedad</big></h3></td><td bgcolor='#fcfcfc'><h2 align='center'><big>$D %</big></h2></td></tr>"
        "</table>"), temp, hum);

     buf.emit_p(PSTR(
        "<h3 align='center'>Tiempo encendido: $D$D:$D$D:$D$D</h3>"), h/10, h%10, m/10, m%10, s/10, s%10);

}

static void login(BufferFiller& buf){
  buf.emit_p(PSTR(
        "<html><head>"
        "<meta charset=utf-8/>"
        "<title>Arduino login</title>"
        "<style type=text/css>"
        "body {"
          "background: #606060;"
        "}"
        "form:after {"
          "content: \".\";"
          "display: block;"
          "clear: both;"
        "}"
        ".container { margin: 25px auto; width: 900px; }"
        "#content {"
          "background: #f9f9f9;"
          "border: 1px solid #c4c6ca;"
          "margin: 0 auto;"
          "padding: 25px 0 0;"
          "position: relative;"
          "text-align: center;"
          "text-shadow: 0 1px 0 #fff;"
          "width: 400px;"
        "}"
        "#content h1 {"
          "color: #7E7E7E;"
        "}"
         "#content h3 {"
          "color: #fffcfc;"
        "}"
        "#content form input[type=\"submit\"] {"
        "margin: 20px 0 35px 15px;"
        "padding: 6px 15px 6px 35px"
        "border-radius: 20px"
        "box-shadow: 0 1px 0 #ccc inset"
        "color: #ccc"
        "widht 150px"
        "}"
        "</style>"
        "</head>"
        "<body>"
        "<div class=container>"
        "<section id=content>"
            "<form>"
              "<h1>Login</h1>"
              "<div>"
                "<input type=text placeholder=Username id=username name=username maxlength=5 required>"
              "</div>"
              "<div>"
                "<input type=password placeholder=Password id=password name=password maxlength=10 required>"
              "</div>"
              "<div>"
                "<input type=submit value=Login>"
              "</div>"
            "</form>"
            "</section>"
           "</div>"
           "<h3 align=center> Temperatura: $D C</h3>"
           "<h3 align=center> Humedad: $D % </h3>"
        "</body></html>"), temp, hum);
}

void loop() {
 
  tiempo = rtc.getTime();
  readvalues();
  //print_lcd();
 
   word len = ether.packetReceive();
    word pos = ether.packetLoop(len);
    boolean this_time=false;
    boolean home_charge=false;
    // check if valid tcp data is received
    if (pos) {
        bfill = ether.tcpOffset();
        char* data = (char *) Ethernet::buffer + pos;
        if(ether.findKeyVal(data + 6, user , sizeof user , "username")>0)
          if(ether.findKeyVal(data + 6, pass , sizeof pass , "password")>0)
            if(strncmp(user,_USER,5)==0 &&strncmp(pass,_PASS,5)==0){
              logged=true;
              this_time=true;
            }
        ether.findKeyVal(data+6, pwm , sizeof pwm , "pwm");
        Serial.println(data);
          if(strncmp("GET / ", data, 6)==0 or logged==false)
            login(bfill);
          else if (this_time==true){
                homePage(bfill, ledstatus);
          }
          else if (strncmp("GET /?led=0", data, 11) == 0) {
       
              if(ledstatus == HIGH) {
                digitalWrite(8, LOW);
                ledstatus = LOW;
                EEPROM.write(0,ledstatus);
              }
                     homePage(bfill, ledstatus);//configPage(data, bfill);
          }
          else if (strncmp("GET /?led=1", data, 11) == 0) {
             
              if(ledstatus == LOW) {
                digitalWrite(8, HIGH);
                ledstatus = HIGH;
                EEPROM.write(0,ledstatus);
              }
              homePage(bfill, ledstatus);
          }
          else if (strncmp("GET /?pwm", data, 9) == 0) {
              homePage(bfill, ledstatus);
              Serial.println(pwm);
              analogWrite(5, atoi(pwm));
          }
          else{
              bfill.emit_p(PSTR(
                  "HTTP/1.0 401 Invalido\r\n"
                  "Content-Type: text/html\r\n"
                  "\r\n"
                  "<h1>Wrong username/password!</h1>"));
          }
        ether.httpServerReply(bfill.position()); // send web page data
    }
 

}

robtillaart

#1
Mar 01, 2018, 06:00 pm Last Edit: Mar 01, 2018, 06:28 pm by robtillaart
you should implement a challenge response system

The hosts says 458793645293 and then you know the answer is 34987653809243
Every number has an unique response based upon a hidden formula/algorithm.

What is a challenge response system?
A simpler example shows the working

<example>
The response is sum of odd digits  followed by sum of even digits in reverse

The challenge is  159756 
sum of odd digits = 15
sum of even digits = 18
reverse -> 81

so response becomes 1581
</example>


As every login presents a new challenge (which can be any number of digits or bytes) a succesful login will not be repeated before a long time. By adding a date/timestamp in the response formula the response on the same challenge will be different at different moments in time.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

quikk

I can't understand it at all... how do I use that on my code?

Kong

#3
Mar 05, 2018, 04:22 pm Last Edit: Mar 05, 2018, 04:32 pm by Kong
You're using GET on the website, change that into POST.
On the html part, change line 183 "<form>" into "<form method="post">"
On the Arduino part, change GET into POST

I think you have to make some extra changes in your code to grab your data, see: https://www.w3schools.com/tags/ref_httpmethods.asp

The trick is to get rid of the html header. After the header there is an empty line, after that comes your data. So look for twice an \n (new line sign).
GET is easier to implement...

Go Up