Encoding progress from an outside program

ravital

New Member
Hi everyone

I have progress 83b with Openlink 3 installed
and I am trying to write a website that will connect to
an already existing progress database. in the
existing database the users passwords
are encrypted with the encode progress command.
is there a way to decode that from an outside program
in order to allow a user login page? I am working with
ASP 2.0 VB-script to write the page.


thanks

Ravital
ravitala@sitqad.co.il
 

jamesmc

Member
I think that you are stuck on this one unless you can find out the encryption algorythm that PSC uses! The best way I think that this can be done is to take a string and encode it, then try and work backwards to converting the encrypted version back to its original. I gave this half an hours thought some time ago and gave it up as I realised I know nothing about encryption.

I was going to say HTH but I doubt it will!

James.
 

mra

Junior???? Member
Hello Ravital!!

Why not use a public one-way encryption algorithm (like the one used for Linux crypt), and use it instead of the one Progress has. This way you can have the same algorithm everywhere.

Note, that this do not prevent someone from tapping the encrypted string, and use it with a fake login program.


Regards

/Mike
 

Chris Kelleher

Administrator
Staff member
Here's a simple encryption / decryption tool that is posted on http://www.fast4gl.com

I´ve found an interesting way of using Progress encode function not only for encryption but for decryption too. The idea is to use it in a different way, not for directly generating an encrypted code, but to use its output as a random sequence (and thus a random number) like the random function does with a significant difference: it´s possible to control the original seed of the random values. This seed can be a text string which is what the encode function expects to receive. So this seed can be a key entered by the user upon which all the encryption and decryption will be based. Based on this idea I´ve created an utility which is very simple. It´s a public domain program so that it can be freely used and changed. It´s made for encrypting simple text files which doesn´t contain special characters (*.txt, *.bat, *.htm and Progress source code files for example). This condition is due to some methods used by this program that may add/modify/remove asc 10 and asc 13 characters and modify null characters (asc 0). I am sure it´s possible to create an utility that can hand these special characters but it wasn´t my intention because I wanted to be able to directly view and edit the texts to be encrypted or after a decryption. It´s name is Cripto (which comes from "encryption" in Portuguese). Submitted by Paulo Meneghelli Jr.

Code:
&ANALYZE-SUSPEND _VERSION-NUMBER UIB_v8r12 GUI
&ANALYZE-RESUME
&Scoped-define WINDOW-NAME C-Win
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _DEFINITIONS C-Win 
/*------------------------------------------------------------------------

  File: Cripto.w

  Description: Encrypts text files

  Input Parameters:
      <none>

  Output Parameters:
      <none>

  Author: Paulo Meneghelli Jr

  Created: February/2000

------------------------------------------------------------------------*/
/*          This .W file was created with the Progress UIB.             */
/*----------------------------------------------------------------------*/

/* Create an unnamed pool to store all the widgets created 
     by this procedure. This is a good default which assures
     that this procedure's triggers and internal procedures 
     will execute in this procedure's storage, and that proper
     cleanup will occur on deletion of the procedure. */

CREATE WIDGET-POOL.

/* ***************************  Definitions  ************************** */

/* Parameters Definitions ---                                           */

/* Local Variable Definitions ---                                       */

define variable c-main-key       as character                no-undo. /* Key for encryption
                                                                         (defined by the user). */
define variable c-main-tab-char  as character case-sensitive no-undo. /* String with all the characters
                                                                         from asc 1 to asc 255 except
                                                                         10 and 13.
                                                                         All the characters in this string
                                                                         can be encrypted. */
define variable c-main-new-table as character case-sensitive no-undo. /* All the characters from
                                                                         c-main-key arranged in different
                                                                         positions.
                                                                         Encryption will happen in 3 ways:
                                                                         1. All the characters will be
                                                                            replaced by others in a
                                                                            relationship of 1 to 1.
                                                                         2. Depending on the position of
                                                                            a character inside the text a
                                                                            random value will be added to or
                                                                            subtracted from the character.
                                                                         3. Depending on the total number of
                                                                            characters encrypted the
                                                                            encryption will be different.
                                                                         This variable well help the 
                                                                         execution of the first way. */
define variable c-main-seed      as character                no-undo. /* An internal reference for the
                                                                         encryption. It´s based on
                                                                         c-main-key */

/*
** Before a file to be encrypted of decrypted it will be stored in this temp-table.
*/
define temp-table t-line no-undo
       field seq  as integer
       field line as character
       index t-line is primary
             seq.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-PREPROCESSOR-BLOCK 

/* ********************  Preprocessor Definitions  ******************** */

&Scoped-define PROCEDURE-TYPE Window

/* Name of first Frame and/or Browse and/or first Query                 */
&Scoped-define FRAME-NAME DEFAULT-FRAME

/* Standard List Definitions                                            */
&Scoped-Define ENABLED-OBJECTS Ed-Text FILL-File Bt-Search Bt-Read Bt-Write ~
Bt-Key Bt-Crypt Bt-Decrypt Bt-Clear 
&Scoped-Define DISPLAYED-OBJECTS Ed-Text FILL-File 

/* Custom List Definitions                                              */
/* List-1,List-2,List-3,List-4,List-5,List-6                            */

/* _UIB-PREPROCESSOR-BLOCK-END */
&ANALYZE-RESUME



/* ***********************  Control Definitions  ********************** */

/* Define the widget handle for the window                              */
DEFINE VAR C-Win AS WIDGET-HANDLE NO-UNDO.

/* Menu Definitions                                                     */
DEFINE MENU MENU-BAR-C-Win MENUBAR
       MENU-ITEM m_Info         LABEL "&Info"         
       MENU-ITEM m_Exit         LABEL "&Exit"         .

DEFINE MENU POPUP-MENU-Ed-Text 
       MENU-ITEM m_Copy         LABEL "&Copy"         
       MENU-ITEM m_Cut          LABEL "Cu&t"          
       MENU-ITEM m_Paste        LABEL "&Paste"        .


/* Definitions of the field level widgets                               */
DEFINE BUTTON Bt-Clear 
     LABEL "C&lear" 
     SIZE 10 BY .95.

DEFINE BUTTON Bt-Crypt 
     LABEL "Encr&ypt" 
     SIZE 10 BY .95.

DEFINE BUTTON Bt-Decrypt 
     LABEL "&Decrypt" 
     SIZE 10 BY .95.

DEFINE BUTTON Bt-Key 
     LABEL "&Key" 
     SIZE 10 BY .95.

DEFINE BUTTON Bt-Read 
     LABEL "&Read" 
     SIZE 10 BY .95.

DEFINE BUTTON Bt-Search 
     LABEL "&Search" 
     SIZE 10 BY .95.

DEFINE BUTTON Bt-Write 
     LABEL "Sa&ve" 
     SIZE 10 BY .95.

DEFINE VARIABLE Ed-Text AS CHARACTER 
     VIEW-AS EDITOR NO-WORD-WRAP SCROLLBAR-HORIZONTAL SCROLLBAR-VERTICAL LARGE
     SIZE 128 BY 13.81
     BGCOLOR 0 FGCOLOR 15 FONT 0 NO-UNDO.

DEFINE VARIABLE FILL-File AS CHARACTER FORMAT "X(256)":U 
     LABEL "File" 
     VIEW-AS FILL-IN 
     SIZE 103 BY 1
     FONT 6 NO-UNDO.

DEFINE BUTTON Bt-Key-Cancel 
     LABEL "&Cancel" 
     SIZE 15 BY .95.

DEFINE BUTTON Bt-Key-Ok 
     LABEL "&Ok" 
     SIZE 15 BY .95.

DEFINE VARIABLE FILL-Key AS CHARACTER FORMAT "X(256)":U 
     LABEL "Key" 
     VIEW-AS FILL-IN 
     SIZE 43 BY 1 NO-UNDO.

DEFINE VARIABLE FILL-Key-Conf AS CHARACTER FORMAT "X(256)":U 
     LABEL "Confirmation" 
     VIEW-AS FILL-IN 
     SIZE 43 BY 1 NO-UNDO.


/* ************************  Frame Definitions  *********************** */

DEFINE FRAME DEFAULT-FRAME
     Ed-Text AT ROW 1 COL 1 NO-LABEL
     FILL-File AT ROW 16.24 COL 7 COLON-ALIGNED
     Bt-Search AT ROW 16.24 COL 115
     Bt-Read AT ROW 17.91 COL 7
     Bt-Write AT ROW 17.91 COL 18
     Bt-Key AT ROW 17.91 COL 37
     Bt-Crypt AT ROW 17.91 COL 56
     Bt-Decrypt AT ROW 17.91 COL 67
     Bt-Clear AT ROW 17.91 COL 86
    WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY 
         SIDE-LABELS NO-UNDERLINE THREE-D 
         AT COL 1 ROW 1
         SIZE 128.2 BY 18.57
         BGCOLOR 1 FGCOLOR 14 .

DEFINE FRAME F-Key
     FILL-Key AT ROW 2.19 COL 15 COLON-ALIGNED BLANK 
     FILL-Key-Conf AT ROW 3.38 COL 15 COLON-ALIGNED BLANK 
     Bt-Key-Ok AT ROW 5.29 COL 30
     Bt-Key-Cancel AT ROW 5.29 COL 50
    WITH 1 DOWN KEEP-TAB-ORDER OVERLAY 
         SIDE-LABELS NO-UNDERLINE THREE-D 
         AT COL 8.2 ROW 3.52
         SIZE 69 BY 7.62
         BGCOLOR 3 FGCOLOR 14 
         TITLE "Key".


/* *********************** Procedure Settings ************************ */

&ANALYZE-SUSPEND _PROCEDURE-SETTINGS
/* Settings for THIS-PROCEDURE
   Type: Window
   Allow: Basic,Browse,DB-Fields,Window,Query
   Other Settings: COMPILE
 */
&ANALYZE-RESUME _END-PROCEDURE-SETTINGS

/* *************************  Create Window  ************************** */

&ANALYZE-SUSPEND _CREATE-WINDOW
IF SESSION:DISPLAY-TYPE = "GUI":U THEN
  CREATE WINDOW C-Win ASSIGN
         HIDDEN             = YES
         TITLE              = "Cripto"
         HEIGHT             = 18.57
         WIDTH              = 128.2
         MAX-HEIGHT         = 18.57
         MAX-WIDTH          = 128.2
         VIRTUAL-HEIGHT     = 18.57
         VIRTUAL-WIDTH      = 128.2
         RESIZE             = yes
         SCROLL-BARS        = no
         STATUS-AREA        = no
         BGCOLOR            = ?
         FGCOLOR            = ?
         KEEP-FRAME-Z-ORDER = yes
         THREE-D            = yes
         MESSAGE-AREA       = no
         SENSITIVE          = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.

ASSIGN {&WINDOW-NAME}:MENUBAR    = MENU MENU-BAR-C-Win:HANDLE.
/* END WINDOW DEFINITION                                                */
&ANALYZE-RESUME


/* ***************  Runtime Attributes and UIB Settings  ************** */

&ANALYZE-SUSPEND _RUN-TIME-ATTRIBUTES
/* SETTINGS FOR WINDOW C-Win
  VISIBLE,,RUN-PERSISTENT                                               */
/* SETTINGS FOR FRAME DEFAULT-FRAME
   L-To-R                                                               */
ASSIGN 
       Ed-Text:POPUP-MENU IN FRAME DEFAULT-FRAME       = MENU POPUP-MENU-Ed-Text:HANDLE.

/* SETTINGS FOR FRAME F-Key
   NOT-VISIBLE L-To-R                                                   */
ASSIGN 
       FRAME F-Key:HIDDEN           = TRUE
       FRAME F-Key:MOVABLE          = TRUE.

IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
THEN C-Win:HIDDEN = no.

/* _RUN-TIME-ATTRIBUTES-END */
&ANALYZE-RESUME

 




/* ************************  Control Triggers  ************************ */

&Scoped-define SELF-NAME C-Win
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL C-Win C-Win
ON END-ERROR OF C-Win /* Cripto */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
  /* This case occurs when the user presses the "Esc" key.
     In a persistently run window, just ignore this.  If we did not, the
     application would exit. */
  /*IF THIS-PROCEDURE:PERSISTENT THEN*/ RETURN NO-APPLY.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL C-Win C-Win
ON WINDOW-CLOSE OF C-Win /* Cripto */
DO:
  /* This event will close the window and terminate the procedure.  */
  
  APPLY "CLOSE":U TO THIS-PROCEDURE.
  RETURN NO-APPLY.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Clear
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Clear C-Win
ON CHOOSE OF Bt-Clear IN FRAME DEFAULT-FRAME /* Clear */
DO:

  define variable l-conf as logical no-undo.
  
  /*
  ** If there is any data in the editor widget this block confirms if it
  ** will be erased.
  */
  if Ed-Text:screen-value <> "" then do:
    assign l-conf = no.
    message "Do you want to clear the current data?"
            update l-conf
            view-as alert-box question buttons yes-no.
    if not l-conf then
       return.
  end.

  /*
  ** This clears the data
  */
  assign Ed-Text:screen-value   = ""
         FILL-File:screen-value = "".
  
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Crypt
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Crypt C-Win
ON CHOOSE OF Bt-Crypt IN FRAME DEFAULT-FRAME /* Encrypt */
DO:
  /*
  ** This calls the procedure which controls encryption and decryption.
  */
  run proc-crypt (Ed-Text:handle, yes).
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Decrypt
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Decrypt C-Win
ON CHOOSE OF Bt-Decrypt IN FRAME DEFAULT-FRAME /* Decrypt */
DO:
  /*
  ** This calls the procedure which controls encryption and decryption.
  */
  run proc-crypt (Ed-Text:handle, no).
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Key
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Key C-Win
ON CHOOSE OF Bt-Key IN FRAME DEFAULT-FRAME /* Key */
DO:
  /*
  ** This sets the widgets to receive a new key.
  */
  run proc-status-objects ("Key").
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define FRAME-NAME F-Key
&Scoped-define SELF-NAME Bt-Key-Cancel
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Key-Cancel C-Win
ON CHOOSE OF Bt-Key-Cancel IN FRAME F-Key /* Cancel */
DO:
  /*
  ** This sets the widgets to their original state.
  */
  run proc-status-objects ("Back-To-Start").
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Key-Ok
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Key-Ok C-Win
ON CHOOSE OF Bt-Key-Ok IN FRAME F-Key /* Ok */
DO:

  define variable i-cont    as integer   no-undo.
  define variable c-base    as character no-undo.
  define variable i-left    as integer   no-undo.
  define variable i-guess   as integer   no-undo.
  define variable i-char    as integer   no-undo.

  /*
  ** These blocks validate a new key.
  */
  if input frame F-Key FILL-Key = "" or input frame F-Key FILL-Key = ?
     then do:
    bell.
    message "You must enter a key."
            view-as alert-box error.
    apply "entry" to FILL-Key.
    return.
  end.
  if input frame F-Key FILL-Key <> input frame F-Key FILL-Key-Conf then do:
    bell.
    message "Key confirmation doesn´t match the key."
            view-as alert-box error.
    apply "entry" to FILL-Key.
    return.
  end.

  /*
  ** This stores the key for future reference.
  */
  assign c-main-key = input frame F-Key FILL-Key.
  
  /*
  ** This generates a list of characters arranged in a random order.
  ** This will help to perform one of the methods used for encryption which
  ** relates one character to exactly one another.
  ** But this isn´t the only method which will be used.
  */
  session:set-wait-state("general").
  assign c-base           = encode(c-main-key)
         c-main-new-table = "".
  do i-left = length(c-main-tab-char) to 1 by -1:
    assign i-guess = ((100 * asc(substring(c-base, 1, 1)) +
                       asc(substring(c-base, 2, 1)))
                      modulo i-left) + 1
           c-base  = encode(c-base)
           i-char   = 0.
    do i-cont = 1 to length(c-main-tab-char):
      if substring(c-main-new-table, i-cont, 1) = "" then do:
        assign i-char = i-char + 1.
        if i-char = i-guess then do:
          assign substring(c-main-new-table, i-cont, 1) =
                   substring(c-main-tab-char, i-left, 1).
          leave.
        end.
      end.
    end.
  end.
  
  /*
  ** This is the initial seed for the generation of random numbers.
  */
  assign c-main-seed = c-base.
  session:set-wait-state("").

  apply "choose" to Bt-Key-Cancel. /* This just leaves the edition of the key */
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define FRAME-NAME DEFAULT-FRAME
&Scoped-define SELF-NAME Bt-Read
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Read C-Win
ON CHOOSE OF Bt-Read IN FRAME DEFAULT-FRAME /* Read */
DO:

  /*
  ** These are the validations which must be done before reading a file.
  */
  if FILL-File:screen-value = "" then do:
    bell.
    message "You must enter a file."
            view-as alert-box error.
    return.
  end.
  if search(FILL-File:screen-value) = ? then do:
    bell.
    message "The file was not found."
            view-as alert-box error.
    return.
  end.
  
  /*
  ** This tries to read a file and states if the reading was successful or not.
  */
  if Ed-Text:read-file(FILL-File:screen-value) then do:
    bell.
    message "The file was read successfuly."
            view-as alert-box information.
  end.
  else do:
    bell.
    message "An error ocurred while reading the file."
            view-as alert-box error.
  end.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Search
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Search C-Win
ON CHOOSE OF Bt-Search IN FRAME DEFAULT-FRAME /* Search */
DO:

  define variable c-file as character no-undo.
  define variable l-ok   as logical   no-undo.

  /*
  ** This looks for a file. It it doesn´t exist it´s a new file.
  */
  system-dialog get-file c-file
                filters "All (*.*)" "*.*"
                create-test-file
                title "Select a file"
                update l-ok
                in window {&window-name}.
  if l-ok then
    assign FILL-File:screen-value = c-file.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Bt-Write
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Bt-Write C-Win
ON CHOOSE OF Bt-Write IN FRAME DEFAULT-FRAME /* Save */
DO:

  define variable l-conf as logical no-undo.

  /*
  ** These are the validations before writing a file.
  */
  if FILL-File:screen-value = "" then do:
    bell.
    message "You must enter a file."
            view-as alert-box error.
    return.
  end.
  if search(FILL-File:screen-value) <> ? then do:
    assign l-conf = no.
    bell.
    message "This file already exists. Overwrite it?"
            update l-conf
            view-as alert-box question buttons yes-no.
    if not l-conf then
      return.
  end.
  
  /*
  ** This tries to save the file and states if it was saved successfuly or not.
  */
  if Ed-Text:save-file(FILL-File:screen-value) then do:
    bell.
    message "The file was saved successfuly."
            view-as alert-box information.
  end.
  else do:
    bell.
    message "An error ocurred while saving the file."
            view-as alert-box error.
  end.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME Ed-Text
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL Ed-Text C-Win
ON ANY-PRINTABLE OF Ed-Text IN FRAME DEFAULT-FRAME
DO:
  /*
  ** Many times the foreground color was becoming black.
  ** This code keeps it white.
  */
  if length(self:selection-text) = 0 then
    apply chr(last-event:code) to self.
  else
    self:replace-selection-text(chr(last-event:code)).
  assign self:fgcolor = 15.
  return no-apply.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define FRAME-NAME F-Key
&Scoped-define SELF-NAME FILL-Key
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL FILL-Key C-Win
ON ENTRY OF FILL-Key IN FRAME F-Key /* Key */
DO:
  /*
  ** Anytime the focus is moved to this widget the key value is cleared.
  */
  assign self:screen-value = "".
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME FILL-Key-Conf
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL FILL-Key-Conf C-Win
ON ENTRY OF FILL-Key-Conf IN FRAME F-Key /* Confirmation */
DO:
  /*
  ** Anytime the focus is moved to this widget the key value is cleared.
  */
  assign self:screen-value = "".
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME m_Copy
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL m_Copy C-Win
ON CHOOSE OF MENU-ITEM m_Copy /* Copy */
DO:

  /* Option Copy after right-clicking the mouse on the editor */

  do with frame default-frame:
    if length(Ed-Text:selection-text) = 0 then do:
      bell.
      message "There is no selected text."
              view-as alert-box error.
      return.
    end.
    assign clipboard:value = Ed-Text:selection-text.
  end.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME m_Cut
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL m_Cut C-Win
ON CHOOSE OF MENU-ITEM m_Cut /* Cut */
DO:

  /* Option Cut after right-clicking the mouse on the editor */

  do with frame default-frame:
    if length(Ed-Text:selection-text) = 0 then do:
      bell.
      message "There is no selected text."
              view-as alert-box error.
      return.
    end.
    assign clipboard:value = Ed-Text:selection-text.
    Ed-Text:replace-selection-text("").
  end.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME m_Exit
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL m_Exit C-Win
ON CHOOSE OF MENU-ITEM m_Exit /* Exit */
DO:

  /* This exits this program */

  apply "window-close" to {&window-name}.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME m_Info
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL m_Info C-Win
ON CHOOSE OF MENU-ITEM m_Info /* Info */
DO:

  /*
  ** This is the message shown when a user selects the menu item "Info" of the menu bar
  */

  message "This is a public domain program and can be"
          "freely copied and modified for better serving the"
          "needs of anyone who wishes to use it."
          chr(13) chr(13)
          "Its usage is proper only for text files (.txt, .htm, etc)."
          chr(13)
          "Binary files or with special characters"
          "(.bmp, .exe, .doc, etc) can´t be encrypted"
          "by this program because some control characters are"
          "lost or modified during file reading, saving, encryption and decryption."
          chr(13) chr(13)
          "The misuse of this program can damage your files."
          "No responsibility about any damage can be related"
          "to me (the author of this program)."
          chr(13) chr(13)
          "For more information, e-mail me."
          chr(13) chr(13)
          "Paulo Meneghelli Jr" chr(13)
          "pmenegh@uol.com.br"
          view-as alert-box information.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define SELF-NAME m_Paste
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CONTROL m_Paste C-Win
ON CHOOSE OF MENU-ITEM m_Paste /* Paste */
DO:

  /* Option Paste after right-clicking the mouse on the editor */

  do with frame default-frame:
    if clipboard:num-formats = 0 then do:
      bell.
      message "There is nothing to paste."
              view-as alert-box error.
      return.
    end.
    if length(Ed-Text:selection-text) > 0 then
      Ed-Text:replace-selection-text(clipboard:value).
    else
      Ed-Text:insert-string(clipboard:value).
  end.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&Scoped-define FRAME-NAME DEFAULT-FRAME
&UNDEFINE SELF-NAME

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _MAIN-BLOCK C-Win 


/* ***************************  Main Block  *************************** */

/* Set CURRENT-WINDOW: this will parent dialog-boxes and frames.        */
ASSIGN CURRENT-WINDOW                = {&WINDOW-NAME} 
       THIS-PROCEDURE:CURRENT-WINDOW = {&WINDOW-NAME}.

/* The CLOSE event can be used from inside or outside the procedure to  */
/* terminate it.                                                        */
ON CLOSE OF THIS-PROCEDURE 
   RUN disable_UI.

/* Best default for GUI applications is...                              */
PAUSE 0 BEFORE-HIDE.

/* Now enable the interface and wait for the exit condition.            */
/* (NOTE: handle ERROR and END-KEY so cleanup code will always fire.    */
MAIN-BLOCK:
DO ON ERROR   UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
   ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
  RUN enable_UI.
  
  run proc-list-chars. /* Definition of the list of characters which can be encrypted */
  
  run proc-status-objects ("Key"). /* The first action will be asking a key for encryption.
                                      This key can be any string and will define how the encryption
                                      will be done. */
  
  apply "choose" to menu-item m_Info in menu MENU-BAR-C-Win.
  
  /*IF NOT THIS-PROCEDURE:PERSISTENT THEN*/
    WAIT-FOR CLOSE OF THIS-PROCEDURE.
  quit.
END.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


/* **********************  Internal Procedures  *********************** */

&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE disable_UI C-Win _DEFAULT-DISABLE
PROCEDURE disable_UI :
/*------------------------------------------------------------------------------
  Purpose:     DISABLE the User Interface
  Parameters:  <none>
  Notes:       Here we clean-up the user-interface by deleting
               dynamic widgets we have created and/or hide 
               frames.  This procedure is usually called when
               we are ready to "clean-up" after running.
------------------------------------------------------------------------------*/
  /* Delete the WINDOW we created */
  IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(C-Win)
  THEN DELETE WIDGET C-Win.
  IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE enable_UI C-Win _DEFAULT-ENABLE
PROCEDURE enable_UI :
/*------------------------------------------------------------------------------
  Purpose:     ENABLE the User Interface
  Parameters:  <none>
  Notes:       Here we display/view/enable the widgets in the
               user-interface.  In addition, OPEN all queries
               associated with each FRAME and BROWSE.
               These statements here are based on the "Other 
               Settings" section of the widget Property Sheets.
------------------------------------------------------------------------------*/
  DISPLAY Ed-Text FILL-File 
      WITH FRAME DEFAULT-FRAME IN WINDOW C-Win.
  ENABLE Ed-Text FILL-File Bt-Search Bt-Read Bt-Write Bt-Key Bt-Crypt 
         Bt-Decrypt Bt-Clear 
      WITH FRAME DEFAULT-FRAME IN WINDOW C-Win.
  {&OPEN-BROWSERS-IN-QUERY-DEFAULT-FRAME}
  DISPLAY FILL-Key FILL-Key-Conf 
      WITH FRAME F-Key IN WINDOW C-Win.
  ENABLE FILL-Key FILL-Key-Conf Bt-Key-Ok Bt-Key-Cancel 
      WITH FRAME F-Key IN WINDOW C-Win.
  {&OPEN-BROWSERS-IN-QUERY-F-Key}
  VIEW C-Win.
END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE proc-conv C-Win 
PROCEDURE proc-conv :
/*------------------------------------------------------------------------------
  Purpose:     Core of encryption/decryption.
  Parameters:  Editor handle, flag (encrypts/decrypts), output: error (yes/no)
  Notes:       
------------------------------------------------------------------------------*/

define input  parameter h-ed     as handle  no-undo.
define input  parameter l-cryp   as logical no-undo.
define output parameter l-error  as logical no-undo.

define variable i-cont     as integer                  no-undo.
define variable c-base     as character                no-undo.
define variable i-guess    as integer                  no-undo.
define variable i-char     as integer                  no-undo.
define variable c-char     as character                no-undo.
define variable i-pos-txt  as integer                  no-undo.
define variable i-nbytes   as integer                  no-undo.


/*
** At first the contents of the editor will be copied to the temp-table
*/
run proc-create-table (h-ed, output l-error, output i-nbytes).
if l-error then /* The error condition will be raised when a line is larger the 30 K */
  return.

/*
** The number of characters to be encrypted will change how the encryption will happen
*/
assign c-base = encode(c-main-seed + encode(string(i-nbytes))).

for each t-line
    by t-line.seq:                            /* All records of the temp-table */
  do i-pos-txt = 1 to length(t-line.line):    /* All characters of each record */
    /*
    ** This assign generates a random value (i-guess) and prepares the seed for the next random value
    */
    assign c-char   = substring(t-line.line, i-pos-txt, 1)
           i-guess = ((100 * asc(substring(c-base, 1, 1)) +
                       asc(substring(c-base, 2, 1)))
                      modulo length(c-main-tab-char)) + 1
           c-base  = encode(c-base).
    /*
    ** There are two methods used inside this block:
    ** 1. A single character is changed to another character using a relationship of 1 to 1.
    ** 2. A random value is added to or subtracted from the asc value of the character depending
    **    on its position in the text file.
    ** When encrypting the step (1) will be executed before the step (2).
    ** When decrypting the steps will be inverted and they will have an opposite effect.
    */
    do i-cont = 1 to 2:
      if i-cont = 1 and l-cryp or
         i-cont = 2 and not l-cryp then do:
        if index(c-main-tab-char, c-char) <> 0 then
          if l-cryp then
            assign c-char = substring(c-main-new-table, index(c-main-tab-char, c-char), 1).
          else
            assign c-char = substring(c-main-tab-char, index(c-main-new-table, c-char), 1).
      end.
      else do:
        if index(c-main-tab-char, c-char) <> 0 then do:
          if l-cryp then do:
            assign i-char = index(c-main-tab-char, c-char) + i-guess.
            if i-char > length(c-main-tab-char) then
              assign i-char = i-char - length(c-main-tab-char).
          end.
          else do:
            assign i-char = index(c-main-tab-char, c-char) - i-guess.
            if i-char < 1 then
              assign i-char = i-char + length(c-main-tab-char).
          end.
          assign c-char = substring(c-main-tab-char, i-char, 1).
        end.
      end.
    end.
    assign substring(t-line.line, i-pos-txt, 1) = c-char. /* The caracter is replaced */
  end.
end.

run proc-read-table (h-ed). /* This brings the contents of the temp-table to the editor */

/*
** The editor is set back to its original condition
*/
assign h-ed:cursor-offset = 1.
h-ed:set-selection(1, 1).

END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE proc-create-table C-Win 
PROCEDURE proc-create-table :
/*------------------------------------------------------------------------------
  Purpose:     Add records to a temp-table from an editor widget
  Parameters:  Editor handle, output: error (yes/no), output: i-bytes (number of bytes stored)
  Notes:       
------------------------------------------------------------------------------*/

define input  parameter h-ed    as handle  no-undo.
define output parameter l-error  as logical no-undo.
define output parameter i-bytes as integer no-undo.

define variable c-line as character no-undo.
define variable i-ini   as integer   no-undo.
define variable i-end   as integer   no-undo.
define variable i-line as integer   no-undo.


/*
** Clearing the temp-table
*/
for each t-line:
  delete t-line.
end.
assign i-bytes = 0.

do i-line = 1 to h-ed:num-lines: /* For each line of the editor */

  /*
  ** Selection of a line in the editor widget
  */
  assign i-ini = h-ed:convert-to-offset(i-line, 1)
         i-end = (if i-line = h-ed:num-lines then
                    h-ed:length + 1
                  else
                    h-ed:convert-to-offset(i-line + 1, 1)).
  h-ed:set-selection(i-ini, i-end).
  assign c-line = h-ed:selection-text.

  /*
  ** chr(10) and chr(13) are ignored
  */
  do while index(c-line, chr(13)) > 0:
    assign substring(c-line, index(c-line, chr(13)), 1) = "".
  end.
  do while index(c-line, chr(10)) > 0:
    assign substring(c-line, index(c-line, chr(10)), 1) = "".
  end.
  
  /*
  ** Creation of a record
  */
  create t-line.
  assign t-line.seq   = i-line
         t-line.line = c-line
         i-bytes       = i-bytes + length(c-line)
         no-error.

  /*
  ** Error condition
  */
  if error-status:error then do:
    assign l-error = yes.
    return.
  end.

end.


END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE proc-crypt C-Win 
PROCEDURE proc-crypt :
/*------------------------------------------------------------------------------
  Purpose:     Procedure for the encrypt and decrypt buttons
  Parameters:  Editor handle, flag (yes for encrypting, no for decrypting)
  Notes:       
------------------------------------------------------------------------------*/

define input parameter h-ed   as handle  no-undo.
define input parameter l-cryp as logical no-undo.

define variable l-error as logical no-undo.


/*
** Validates if the key for encryption/decryption was informed
*/
if c-main-key = "" then do:
  bell.
  message "You need to enter a key for encryption/decryption."
          view-as alert-box error.
  return.
end.

/*
** Performs the encryption/decryption
*/
assign h-ed:hidden              = yes
       {&window-name}:sensitive = no.
session:set-wait-state ("general").
run proc-conv (h-ed, l-cryp, output l-error).
session:set-wait-state ("").
assign {&window-name}:sensitive = yes
       h-ed:hidden              = no.

/*
** Displays a message informing if the encryption/decryption succeeded or not
*/
bell.
if l-cryp then
  if l-error then
    message "An error ocurred while encrypting."
            view-as alert-box error.
  else
    message "The encryption was successful."
            view-as alert-box information.
else
  if l-error then
    message "An error ocurred while decrypting."
            view-as alert-box error.
  else
    message "The decryption was successful."
            view-as alert-box information.


END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE proc-list-chars C-Win 
PROCEDURE proc-list-chars :
/*------------------------------------------------------------------------------
  Purpose:     Generates a string with all the characters which can be encrypted
               Chr(10) and Chr(13) aren´t included.
  Parameters:  <none>
  Notes:       
------------------------------------------------------------------------------*/

define variable i-char as integer no-undo.

assign c-main-tab-char = "".

do i-char = 1 to 255:
  if i-char = 10 or i-char = 13 then
    next.
  assign c-main-tab-char = c-main-tab-char + chr(i-char).
end.

END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE proc-read-table C-Win 
PROCEDURE proc-read-table :
/*------------------------------------------------------------------------------
  Purpose:     Moves the contents of the temp-table to an editor widget
  Parameters:  Editor handle
  Notes:       
------------------------------------------------------------------------------*/

define input parameter h-ed as handle no-undo.

define variable i-last as integer no-undo.


assign h-ed:screen-value = "". /* Clearing the editor */

/*
** A line-feed won´t be added to the last line
*/
find last t-line no-error.
if not available t-line then
  return.
assign i-last = t-line.seq.

/*
** Inserts each record from the temp-table in the editor widget
*/
for each t-line
    by t-line.seq:
  h-ed:insert-string(t-line.line + 
                     (if i-last = t-line.seq then
                        ""
                      else
                        chr(10))).
end.

END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME


&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE proc-status-objects C-Win 
PROCEDURE proc-status-objects :
/*------------------------------------------------------------------------------
  Purpose:     Defines widgets status
  Parameters:  Status
  
  Notes:       Possible status:
               
               Start
               Back-To-Start
               Key
------------------------------------------------------------------------------*/

define input parameter c-status as character no-undo.


/*
** Can it be viewed?
*/
assign frame default-frame:hidden = no
       frame F-Key:hidden         = not (c-status = "Key").


/*
** Is it sensitive?
*/
assign frame default-frame:sensitive = (c-status = "Start" or
                                        c-status = "Back-To-Start")
       frame F-Key:sensitive         = (c-status = "Key").
do with frame default-frame:
  assign Bt-Crypt:sensitive    = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Bt-Decrypt:sensitive  = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Bt-Write:sensitive    = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Bt-Read:sensitive     = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Bt-Search:sensitive   = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Bt-Key:sensitive      = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Bt-Clear:sensitive    = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         Ed-Text:sensitive     = (c-status = "Start" or
                                   c-status = "Back-To-Start")
         FILL-File:sensitive   = (c-status = "Start" or
                                   c-status = "Back-To-Start").
end.
do with frame F-Key:
  assign Bt-Key-Cancel:sensitive   = (c-status = "Key")
         Bt-Key-Ok:sensitive       = (c-status = "Key")
         FILL-Key:sensitive        = (c-status = "Key")
         FILL-Key-Conf:sensitive   = (c-status = "Key").
end.


/*
** Initial values
*/
if c-status = "Start" then do with frame default-frame:
  assign Ed-Text:screen-value     = ""
         FILL-File:screen-value   = "".
end.
if c-status = "Key" then do with frame F-Key:
  assign FILL-Key:screen-value      = ""
         FILL-Key-Conf:screen-value = "".
end.


/*
** Focus
*/
if c-status = "Start" then do with frame default-frame:
  apply "Entry" to Ed-Text.
end.
if c-status = "Key" then do with frame F-Key:
  apply "Entry" to FILL-Key.
end.

END PROCEDURE.

/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME
 
Top