0

Im trying to make when entering the IP address of the Arduino board, a login screen opens and if the correct information is entered, display the files inside an SD card. I asked a question here twice about this and both were not very well received. After several trials, what I have achieved so far, is to leave the login screen, but ... something curious happens: Login does not work if a micro SD card is inserted.

The code:

#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 117);
EthernetServer server(80);
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;

#define error(s) error_P(PSTR(s))

void error_P(const char* str) {
  PgmPrint("error: ");
  SerialPrintln_P(str);
  if (card.errorCode()) {
    PgmPrint("SD error: ");
    Serial.print(card.errorCode(), HEX);
    Serial.print(',');
    Serial.println(card.errorData(), HEX);
  }
  while(1);
}

struct Millis{
    unsigned long offset = 0;
    unsigned long get(){return millis() - offset;}
    void reset(){offset = millis();}
    void set(unsigned long value){offset - millis() - value;}
};


void setup() {
  Serial.begin(9600);
  pinMode( 8, OUTPUT );                   
  digitalWrite( 9, HIGH );
  if( !card.init( SPI_HALF_SPEED, 4 ) ) error( "card.init failed!" );
  if( !volume.init( &card ) ) error( "vol.init failed!" );
  if( !root.openRoot( &volume ) ) error( "openRoot failed" );
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


#define BUFSIZ 100
Millis lol;

void loop()
{
  char clientline[BUFSIZ];
  int index = 0;
  LEDCunt();
  EthernetClient client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    boolean activo = false;
    index = 0;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        while(!activo){
           activo = login();
        }

        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          //Se comprueba si el tamaño del Buffer es demasiado grande
          if (index >= BUFSIZ) 
            index = BUFSIZ -1;

          //Si no es grande, se continua normalmente el codigo
          continue;
        }

        // Si esta linea se cumple, significa que ya salio el bucle de la condicion anterior.
        // Osea.... ya se encontro el espacio en blanco final (\n,\t)
        clientline[index] = 0;

        // Insertamos el array para proseguir con la solicitacion de directorios de la tarjeta SD (ROOT)
        if (strstr (clientline, "GET / ") != 0) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>Archivos:</h2>");
          //Listamos archivos
          ListFiles(client, 0);
        } else if (strstr (clientline, "GET /") != 0) {

          char *filename;

          filename = clientline + 5; 

          //Limpiamos el array igualando elementos a 0
          (strstr (clientline, " HTTP"))[0] = 0;

          // Cuando demos click al archivo que vamos abrir, imprime el nombre por consola.
          Serial.println(filename);

          if (! file.open(&root, filename, O_READ)) {
            client.println("HTTP/1.1 404 Not Found");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<h2>File Not Found!</h2>");
            break;
          }

          Serial.println("Opened!");

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/plain");
          client.println();

          int16_t c;
          while ((c = file.read()) > 0) {
              client.print((char)c);
          }
          file.close();
        } else {
          //Si no encuentra el archivo o no puede abrirlo
          client.println("HTTP/1.1 404 Not Found");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<h2>File Not Found!</h2>");
        }
        break;
      }
    }
    delay(1);
    client.stop();
  }
}

boolean login(){
  int bufferSize;
  char header[300];
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if(bufferSize < 75) header[bufferSize++] = c;


        if (c == '\n' && currentLineIsBlank) {

          //'arduino:admin' (user:password) encriptado base64

          Serial.println(header);

          if(strstr(header, "YXJkdWlubzphZG1pbg==") != NULL) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: close"); 

            client.println();
            if(strstr(header, "GET / HTTP/1.1")) {
              return true;
            } else {
              return false;
            }

          } else {
            client.println("HTTP/1.1 401 Unauthorized");
            client.println("WWW-Authenticate: Basic realm=YXJkdWlubzphZG1pbg==");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<html>¿Quien eres?</html>"); 
            return false;                    
          }

          bufferSize = 0;
          StrClear(header, 300);

          break;

        }
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
    Serial.println("Login terminado");
  }
}

void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

void ListFiles(EthernetClient client, uint8_t flags) {
  dir_t p;

  root.rewind();
  client.println("<ul>");
  while (root.readDir(p) > 0) {

    if (p.name[0] == DIR_NAME_FREE) break;

    // omite entradas (archivos) eliminadas
    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;

    // enlista subdirectorios y archivos(solamente)
    if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;

    // imprime espacios en blanco para extension del archivo
    client.print("<li><a href=\"");
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print((char)p.name[i]);
    }
    client.print("\">");

    // imprime el nombre del archivo
    for (uint8_t i = 0; i < 11; i++) {
      if (p.name[i] == ' ') continue;
      if (i == 8) {
        client.print('.');
      }
      client.print((char)p.name[i]);
    }

    client.print("</a>");

    if (DIR_IS_SUBDIR(&p)) {
      client.print('/');
    }

    // imprime la fecha de ultima modificacion si se solicita
    if (flags & LS_DATE) {
       root.printFatDate(p.lastWriteDate);
       client.print(' ');
       root.printFatTime(p.lastWriteTime);
    }
    // imprime el tamaño del archivo si se solicita
    if (!DIR_IS_SUBDIR(&p) && (flags & LS_SIZE)) {
      client.print(' ');
      client.print(p.fileSize);
    }
    client.println("</li>");
  }
  client.println("</ul>");
}

void LEDCunt(){
  if(lol.get() < 700){
    digitalWrite(9,HIGH);
  }
  if(lol.get() > 700){
    digitalWrite(9,LOW);
  }
  if(lol.get() == 1400){
    lol.reset();
  }
}

Here I share a capture about what happens. If I remove the SD card, and I run the code, I will not even leave the login screen because the board will detect that there is no SD card inserted.

enter image description here

For some reason, if the card is inserted, it throws out these strange hieroglyphs and does not throw what it should be (the user and password encrypted by base64).

What exactly happens here? Any issues with the pins that the Ethernet card uses? what should I do?

EDIT: I mean exactly this part

    Authorization:ÀéÊ?®¿Þ-¦Û’õUÞ>jß¿<úgÓzüýMömûÓÚà[Þ·3|i½X9}’u¿ÛöæÛº>tkÿKùN©þ›7ê:úñ¾½íØqÛ‡tÔ¯ï§NÞZÌ?óÔûwóÿ_`û쾈׽‡è¿ïãVû÷«è?-žÏÚzÚ7qÕÿ­ëö[·[ùúxÓ®_Õι÷ÖÝuOÝ{MÝö³S§qÉ÷ü~Ÿþê÷ú¸Ûˆ­ÿlÿ8:míï_m!ﯻÎ÷«ú]<®:Ÿ÷ý>Ÿ®]f›·þÌá\]Ü;Ê­¶ïéÿòÚ;Wû¿˜´B]¹è¶¬µvs}ú~ù¯šWÒ¡¯¸Ç›ÛGë¾Êõ_~î

It should print: "YXJkdWlubzphZG1pbg=="

TwoDent
  • 405
  • 7
  • 26

1 Answers1

1

The "strange hieroglyphs" is Base64 encoding which decodes to (in hex) 61726475696E6F3A61646D696E which in ASCII is: "arduino:admin".

Time to delve into encodongs including ASCII, haxadecimal, Base64 and unicode.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • But what comes out in the capture (not the encrypted base64 of the red circle) that follows after "Authorization:" what is it? – TwoDent Apr 16 '17 at 17:47
  • Authorization: ÀéÊ?®¿Þ-¦Û’õUÞ>jß¿<úgÓzüýMömûÓÚà[Þ·3|i½X9}’u¿ÛöæÛº>tkÿKùN©þ›7ê:úñ¾½íØqÛ‡tÔ¯ï§NÞZÌ?óÔûwóÿ_`û쾈׽‡è¿ïãVû÷«è?-žÏÚzÚ7qÕÿ­ëö[·[ùúxÓ®_Õι÷ÖÝuOÝ{MÝö³S§qÉ÷ü~Ÿþê÷ú¸Ûˆ­ÿlÿ8:míï_m!ﯻÎ÷«ú]<®:Ÿ÷ý>Ÿ®]f›·þÌá\]Ü;Ê­¶ïéÿòÚ;Wû¿˜´B]¹è¶¬µvs}ú~ù¯šWÒ¡¯¸Ç›ÛGë¾Êõ_~î – TwoDent Apr 16 '17 at 17:47
  • That looks like binary displayed as printable characters which really does not work. It is possibly encrypted data. Base64 is an encoding, not encryption, encoding does not require a key to decode, encryption does need a key to decrypt. Base64 is often used to encode binary data to printable characters. – zaph Apr 16 '17 at 18:33