CAPTCHA amb COBOL

Degut a la gran expansió que actualment pren el llenguatge COBOL i la interfície de terminal de text he pensat que és molt necessària l'aplicació de la tecnologia CAPTCHA als logins de les aplicacions Cobol.

En aquest post s'ensenyarà com aplicar un Captcha a un programa Cobol. Es mostra un text en ascii-art i l'usuari l'ha de transcriure amb el teclat. Si l'encerta, el programa continua però si el falla, el programa s'atura.

Es recomana el compilador gnucobol però pot funcionar amb qualsevol altre que admeti crides a sistema CALL “SYSTEM” USING

Per a començar, ens cal el següent:

  • Una shell de Unix (Bash, Korn…).
  • El compilador de Cobol gnucobol (pot ser qualsevol altre que admeti CALL).
  • L'entorn del compilador carregat (variable COB_LIBRARY_PATH).
  • El programa figlet.
  • Un editor de text (vi, emacs, …)
  • Poca feina.

Per anar al gra, el que cal afegir al nostre programa, per a que implementi el Captcha, és el següent:

Dins la CONFIGURATION SECTION, afegirem aquest descriptor de fitxers:

FILE-CONTROL.
  SELECT captchafile ASSIGN TO captchafilename
         ORGANIZATION IS LINE SEQUENTIAL.

I dins la FILE SECTION afegirem la definició del descriptor:

     FD captchafile.
     01 FILEGLOBAL.
        02 FILELINE         PIC X(80).
     88 EOFcaptchafile             VALUE HIGH-VALUES.

En la WORKING-STORAGE SECTION afegirem les variables que utilitzem per al Captcha:

     77  captchafilename  PIC X(25) VALUE SPACES.
     01  BANNERCMD        PIC x(22) value "/usr/bin/figlet-figlet".
     01  random-number    PIC X(10).
     01  CAPTCHA          PIC X(10).
     01 ARGV                 PIC X(100) VALUE SPACES.
        88 RECV                         VALUE SPACES.

Ja en la PROCEDURE DIVISION, en la SECTION en la que treballem, afegim:

         ACCEPT random-number FROM ENVIRONMENT "RANDOM2".

☝ Aquesta sentència pren un nombre al·leatori de la variable d'entorn (de la shell Unix) $RANDOM2.

         IF random-number = SPACE OR random-number = LOW-VALUE THEN
          DISPLAY "PROGRAM NOT CORRECTLY INITIATED. ABORTING EXECUTION." LINE 21 COLUMN 2
          CALL "C$SLEEP" USING BY CONTENT 3 END-CALL
          STOP RUN
         END-IF

☝ Aquest bloc controla que s'hagi rebut un nombre des de la variable d'entorn $RANDOM2.

         CALL "SYSTEM" USING
          FUNCTION CONCATENATE(BANNERCMD " " random-number " > /tmp/.rnd-" random-number)
         END-CALL.

         MOVE FUNCTION CONCATENATE("/tmp/.rnd-" random-number) TO captchafilename

         OPEN INPUT captchafile
         READ captchafile
           AT END SET EOFcaptchafile TO TRUE
         END-READ.
         PERFORM UNTIL EOFcaptchafile
           DISPLAY FILELINE LINE CAPTCHA-Y COLUMN 2
           ADD 1 TO CAPTCHA-Y
           READ captchafile
              AT END SET EOFcaptchafile TO TRUE
           END-READ
         END-PERFORM
         CLOSE captchafile
         CALL "CBL_DELETE_FILE" USING FUNCTION CONCATENATE("/tmp/.rnd-" random-number)

I el bloc anterior el que fa és mitjançant un CALL executar el programa figlet i enviar la sortida a un fitxer de text temporal. Seguidament es llegeix (READ) el fitxer i s'imprimeix per pantalla línia a línia (PERFORM… DISPLAY). Finalment s'elimina el fitxer temporal.

         DISPLAY "ESCRIU EL NOMBRE D'AMUNT: " LINE 20 COLUMN 2.
         ACCEPT CAPTCHA AT 2026 WITH TIMEOUT AFTER 20 ON EXCEPTION STOP RUN.

☝ Aquí demanem a l'usuari que escrigui el nombre que apareix al Captcha i ho desem dins la variable CAPTCHA.

         IF CAPTCHA IS NOT EQUAL TO random-number THEN
          DISPLAY "NOT CORRECT. DISCONNECTING." LINE 21 COLUMN 2
          CALL "C$SLEEP" USING BY CONTENT 3 END-CALL
          STOP RUN
         ELSE
          DISPLAY "CAPTCHA SOLVED CORRECTLY. CONNECTING..." LINE 21 COLUMN 2
          CALL "C$SLEEP" USING BY CONTENT 3 END-CALL
         END-IF.

☝ I en el bloc de dalt controlem si l'usuari ha entrat correctament el codi o no. Segons el resultat, el programa agafa un camí (continuar l'execució) o l'altre (STOP RUN).

Aquest procediment és molt millorable. Per exemple, hauriem de poder realitzar programàticament, en Cobol, el següent:

  1. Obtenir el número al·leatori sense recórrer a la variable d'entorn.
  2. Representar-lo amb ascii-art sense fer servir el programa figlet.

Qui s'anima a fer-ho?

Notes:

Fem servir una variable d'entorn $RANDOM2 ja que el programa de Cobol no és capaç de llegir la variable $RANDOM, per tant, abans de la seva execució, assignem el valor de $RANDOM a $RANDOM2 i llavors el programa sí que és capaç de llegir aquesta nova variable.