DOCUMENT #675
=======================================================================
BEYOND PASSWORDS
=======================================================================
PRODUCT: R:BASE VERSION : 3.1 or Higher
=======================================================================
AREA : DATABASE INTEGRITY CATEGORY: SECURITY
=======================================================================
The R:BASE password system provides control over access to the data
in your database. Often you will also want to control access to the
application or parts of the application. Even information on
application menus can be sensitive information that you do not want
everyone to see. Or, you may want to control access to data beyond
the table level, for example, you may only want users to see and edit
the data that they personally have entered.
Note that if someone is really determined to get in and look at
information in your database you can't keep them out. What you can
do is make it difficult for them. Also, the following procedures
assume that you have already set up a system of R:BASE passwords
restricting access to the database and tables.
Control Access to an Application Through Programming
====================================================
-- Don't allow access to R> prompt or main menu
-- Always exit from the application to DOS
-- Set escape off
-- Disable F3 hotkey
-- Use startup files
The first step in restricting access to data through an application
is to make sure that the application does not allow the user access
to the R> prompt or to the R:BASE main menu. Only allow users access
to data through the application where you have control.
Always exit the application to the operating system (DOS) not to
R:BASE. When creating an application with Express do not pick the
action "Exit" from the options menu, this will exit back to R:BASE.
Instead pick the action "Custom" and enter the command EXIT as the
custom code. This will exit the user from R:BASE to the operating
system when they choose to exit the application.
Always have "Application break" (ESCAPE) set OFF. This will prevent
users from aborting an application by hitting Ctrl-break. Aborting
an application will exit users from the application to R:BASE. By
making sure "Application break" (ESCAPE) is set OFF, you can keep
users from accidentally or purposefully aborting an application and
gaining access to R:BASE outside the application.
Disable the F3 hotkey so that users will not have access to the
database structure (lists of Tables, Columns, Views, Forms, Reports
and Variables). Define a keymap setting the F3 key to
"[Right][Left]". When users press F3 it will do nothing and leave
the cursor in the same position. Save the keymap to the RBASE.CFG
file or invoke it through a script file during application startup.
Note: you can only use this technique to disable the F3 key in
R:BASE 4.0.
Use an RBASE.DAT or other startup file to always initialize the
application when R:BASE is started. The RBASE.DAT or startup file
can be encrypted using CodeLock. Use DOS batch files or an external
menuing system that will automatically place users in the appropriate
directories to start R:BASE and the application.
Keep Unauthorized Users Out of the Application
==============================================
-- Require a password to connect the database
-- Require a password to run the application
-- Create a system_user table to track access to the database
-- Require a password to access menus in the application
By password protecting all tables and views in a database, you can
require a valid user password to be entered in order to connect and
open the database. This will not prevent the application menus from
coming up, however. It just prevents the actions from doing anything
that requires database access. The menus display, but they don't do
anything.
You can use commands in the RBASE.DAT or startup file to require
users to enter a password in order to gain access to the application.
This is not an R:BASE password but one specified in the RBASE.DAT
file itself. You can give users three tries to enter the correct
password, if they don't they are returned to the operating system and
do not gain access to the application or to R:BASE. Here's an example
of code you might use:
USER NONE
SET ESCAPE OFF *(makes sure Ctrl-Break will not abort to R>)
SET VAR vnum INTEGER = 1
WHILE vnum <= 3 THEN
CLEAR VAR vpass,vget1,vdots
SET VAR vnum = (.vnum+1), vget1 TEXT, vpass TEXT, vdots TEXT +
vpos INTEGER=49
CLS FROM 10,20 TO 12,61 BLACK
CLS FROM 9,19 TO 11,60 CYAN
WRITE 'Please enter your password: ' at 10,22 BLACK ON CYAN
LABEL getchar
FILLin vget1=0 USING '' AT 10,.vpos BLACK ON CYAN
IF vget1 <> '[Enter]' THEN
SET VAR vdots = (.vdots+'.'), vpass = (.vpass+.vget1), +
vpos=(.vpos+1)
WRITE .vdots AT 10,49 BLACK ON CYAN
GOTO getchar
ENDIF
IF vpass = 'pword' THEN
RUN application IN application.apx
EXIT
ELSE
SET VAR vmsg = (CTR('Invalid Password. Reenter it.',78)+CHAR(255))
WRITE .vmsg AT 24,1 GRAY ON RED
PAUSE 2
CLS FROM 24 TO 25
CLS FROM 10,48 TO 10,60 CYAN
ENDIF
ENDWHILE
SET VAR vmsg = (CTR('No valid password entered. You cannot access +
system.', 78) + CHAR(255) )
WRITE .vmsg AT 24,1 GRAY ON RED
PAUSE 2
CLS
EXIT
Be sure to encrypt the R:BASE.DAT or startup file with CodeLock so
that the passwords you're checking are not readable by viewing the
file.
You can enhance this by using R:BASE tables to store the passwords.
You assign each person a personal password. The personal password is
stored in an R:BASE table along with the matching R:BASE system
password. This allows you to restrict the number of different R:BASE
passwords you need to assign, but each person can have their own
password. In addition, you can have a user log table which will keep
track of who is using the system, and who has tried to gain access to
the system. Here's an example.
Create two tables:
SECRET table: USERNAME
PWORD personal password
SYSPW system (R:BASE) password
USERLOG table: SYSPW password entered
USERNAME
TIME_IN
DATE_IN
TIME_OUT
DATE_OUT
PCHECK invalid/valid password entered
The command file requires users to enter their name and then their
personal password. It checks the SECRET table for the combination of
name and password and gives 3 chances for the user the enter the
correct password for their name. Each try is logged into the USERLOG
table. R:BASE table passwords (read/modify) are assigned to the two
tables. Again the program code must be encrypted so that the
passwords that are necessary for the program to execute are not
readable.
When the correct password combination is entered, the user starts the
application. If correct combination is not entered, the user is
exited to the DOS prompt.
SET MESSAGES OFF
SET ERROR MESSAGES OFF
USER NONE
SET ESCAPE OFF
SET ERROR VAR verr
SET VAR vnum INTEGER = 1
CLS FROM 10,20 TO 12,61 BLACK
CLS FROM 9,19 TO 11,60 CYAN
WRITE 'Enter your name: ' at 10,22 BLACK ON CYAN
FILLIN vusername=20 USING '' AT 10,39 BLACK ON CYAN
IF vusername IS NULL THEN
SET VAR vmsg = BREAK
ENDIF
CLS FROM 9,19 TO 11,60 CYAN
WHILE vnum <= 3 THEN
CLEAR VAR vpass,vget1,vdots
SET VAR vnum = (.vnum+1), vget1 TEXT, vpass TEXT, vdots TEXT +
vpos INTEGER=49
CLS FROM 10,20 TO 12,61 BLACK
CLS FROM 9,19 TO 11,60 CYAN
WRITE 'Please enter your password: ' AT 10,22 BLACK ON CYAN
LABEL getchar
FILLin vget1=0 USING '' AT 10,.vpos BLACK ON CYAN
IF vget1 <> '[Enter]' THEN
SET VAR vdots = (.vdots+'.'), vpass = (.vpass+.vget1), vpos=(.vpos+1)
WRITE .vdots AT 10,49 BLACK ON CYAN
GOTO getchar
ENDIF
SET USER junk *(the read password for the SECRET table)
CONN concomp
SET VAR vpw = syspw IN secret WHERE pword=.vpass AND +
username=.vusername
SET V vhold=.verr
SET USER none
IF vhold = 0 THEN
SET USER junk *(the modify password for the USERLOG table)
INSERT INTO userlog (syspw,username,time_in,date_in,pcheck) +
VALUES (.vpass,.vusername,.#time,.#date,'VALID')
CLS
SET USER .vpw
RUN application IN application.apx
SET USER junk *(the modify password for the USERLOG table)
UPDATE userlog SET time_out=.#time, date_out=.#date WHERE +
syspw = .vpass AND username = .vusername AND date_in=.#date
EXIT
ELSE
SET USER junk *(the modify password for the USERLOG table)
INSERT INTO userlog (syspw,username,time_in,date_in,pcheck) +
VALUES (.vpass,.vusername,.#time,.#date,'INVALID')
SET USER NONE
DISC
SET VAR vmsg = (CTR('Invalid Password. Reenter it.',78)+CHAR(255))
WRITE .vmsg AT 24,1 GRAY ON RED
PAUSE 2
CLS FROM 24 TO 25
CLS FROM 10,48 TO 10,60 CYAN
ENDIF
ENDWHILE
SET VAR vmsg = (CTR('No valid password entered. You cannot access +
system.', 78) + CHAR(255) )
WRITE .vmsg AT 24,1 GRAY ON RED
PAUSE 2
CLS
EXIT
You can also control access to menu levels in an application. Use
one of the following two techniques, depending on whether you want to
continue modifying the application with Express.
Option 1: Express modifiable
=============================
First create an ASCII file that has one command in it: RUN
application IN application.APX. This file must remain as an ASCII
file. Modify the application, choose to "Insert an action" before
the menu to be restricted. Choose Custom or Macro for the action
and insert password checking code similar to that in the examples
above. If users don't enter the correct password use the QUIT TO
command instead of EXIT; QUIT TO the ASCII file that restarts the
application. This will always take users to the main menu of the
application, even if they are at a third level menu.
When done, you have 2 actions defined for the particular menu
selection that goes to the lower level menu; the first action does
password checking, the second action displays the menu if the
correct password is entered.
Option 2: Not "Expressable"
============================
If continuing to modify the application with Express is not an issue,
use this method. Modify the application and follow the same
procedure for inserting an action, and choose Custom or Macro for the
action. But instead of using QUIT TO ASCII_file when the password is
incorrect, use either SET VAR LEVEL2 = 0 or SET VAR LEVEL3 = 0. Use
LEVEL2 if you checking a second level menu, LEVEL3 if it is a third
level menu. Application Express inserts a RUN command for the
custom/macro code immediately prior to a SET VAR command that
controls the next menu level. The lines of code in the .APP file
look like this:
CASE 'Print reports'
RUN pcheck IN application.apx
SET VAR LEVEL3 INT = 1
WHILE LEVEL3 = 1 THEN
Simply switch the two lines of code, "RUN... " and "SET VAR
LEVEL3...", so the code looks like this instead:
CASE 'Print reports'
SET VAR LEVEL3 INT = 1
RUN pcheck IN application.apx
WHILE LEVEL3 = 1 THEN
Then, if the correct password is not entered, the WHILE condition
fails (variable LEVEL3 =0), the menu is not displayed and the user
returns to the previous menu (either the main menu of the application
of application or the second level menu). Because you are editing the
.APP file you need to CodeLock the file to create a new .APX file to run.
This application is no longer be modifiable in Application Express,
Express won't know about the custom editing you have done to the .APP
file.
Control Data Access Using Forms
===============================
-- Locate only specific fields
-- Use form passwords
-- Use Form, table and field settings to restrict editing
-- Disable Shift-F3 pop-ups
-- Read-only forms
R:BASE forms provide application developers with any number of
techniques for limiting/restricting access to data. First and
foremost is the fact that you, the application developer, limit the
data that is located or displayed on the form. You choose which
columns the user can view and modify by placing or not placing those
fields on the form. By restricting user access to data through forms
you immediately limit the data they can view or edit. There is no
direct access to other columns in the underlying table or view
through the form.
In addition, forms has form, table and field level control on editing
data, its own password system (see article "Passwords - a Primer" in
this issue of the Exchange) and, in 4.0, you can use views.
At the form level (Form settings) a developer specifies that the form
can be used to add new rows or to edit existing rows. The form menu
can be customized or removed altogether. At the table level, Table
settings are used to specify whether users can add new rows, edit
existing rows or delete rows from the table. At the field level,
individual fields in tables can be made non-editable through the
Field settings screen.
To make sure that users only have access to the data you want them to
see, disable the Shift-F3 key for default pop-ups in forms (redefine
the key, see disabling the F3 key above), or define a specific pop-up
for each field in a form. By default, Shift-F3 will pop-up a menu
and display all the current data values in the table for the
particular column. Instead of using Shift-F3, use an Entry/exit
procedure and key pop-ups off of the F2 key. This procedure is
described in the May/June 1992 Exchange in "A Collection of
Entry/Exit Procedures", Conditional multi-column pop-up menu
(document #645 on our automated FAX server, 206-649-2789).
There are many application situations where it's necessary for people
to see data, but not be able to edit it. R:BASE provides a number of
ways to create read-only forms.
1. Use form passwords to create a read-only form by setting a modify
password on the form. If the current user is not the same as the
modify password, the form displays and data appears but the "No
editable data" message displays on line 24.
2. Use Table settings/field settings combinations to create a
read-only form. An individual table on a multi-table form can be
specified as read-only by changing Table settings to NO for "Add new
rows" and "Change data", but you need to be careful when doing this.
If any table on a multi-table form is set to say NO to "Add new rows"
then the form cannot be used to add data. The only exception is if
the table has a same-table lookup defined for it. If the table
settings say NO to "Change data" then users can page up and page down
through the data but they see the message "No editable data" on line
24. The cursor does not land in any fields on the form and you cannot
scroll through NOTE or TEXT fields.
To scroll through NOTE or TEXT fields, define an expression to lookup
the note or text data into a variable, locate the variable on the
form and make the field settings editable. Because it is a variable,
it won't matter if users inadvertently change data, it won't be saved
to the table.
If you don't want your users to see the "No editable data message",
locate a dummy variable for each table on the form. Use Field
settings to make all fields but the dummy variable non-editable. The
dummy variable gives the cursor a place to land.
3. Do not GRANT UPDATE permission to the tables the form is based on.
Users without UPDATE permission are able to view the data but
cannot change it. They see the message "No editable data" and
the cursor does not land in any fields on the form.
4. With R:BASE 4.0, you can use a view to create a read-only form. A
multi-table view is by definition non-editable. When using a
single-table view, GRANT SELECT permission on the view only.