lunes, 27 de octubre de 2014

The Smalltalk Family Tree

Introduction : GraphViz in Pharo

GraphViz is a popular free graph visualization library currently used in many applications. In GraphViz you describe a graph in text format and the software draws a pretty picture of the graph.

A GraphViz package for Smalltalk was originally available in Squeak, but it was outdated in the current Pharo releases (3.0). The package facilitates the creation of graph descriptions in the DOT language of the Graphviz graphing tool. You write the graph using the beautiful Smalltalk syntax, and the GraphViz class generates the output in all available formats (dot,svg,png,jpg,gd,etc).

Now I have uploaded a new Metacello Configuration for GraphViz in Pharo 3.0, available in the Configuration Browser. To use it, GraphViz should be installed and present in the PATH environment variable. More useful information can be found in the original repository (Connectors compatibility is still missing until we get a Connectors version which loads in Pharo 3 or 4). The Configuration loads both stable versions of CommandShell and XML-Parser packages.

A Smalltalk Family Tree

I have collected the Smalltalk implementations I know and grouped them in a graph by what could be considered their "family". Some of them are not supported anymore, others are difficult to find or get executed again. Exotic or very old Smalltalks like Bricktalk, DuoTalk, Marvin, etc. were not included because there are too few references on the web. Now by looking at it in perspective, one could understand why Smalltalk is considered the most evolved and state-of-the-art programming environment. Here is the resulting graph :

Licencia Creative Commons
Smalltalk Family Tree por Hernán Morales Durand se distribuye bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivar 4.0 Internacional.
Basada en una obra en http://80738163270632.blogspot.com/2014/10/the-smalltalk-family-tree.html.

lunes, 20 de octubre de 2014

10 simple survey questions about Smalltalk

Introduction

So I did a short on-line Smalltalk survey to find out where is the technology today, and what could be expected in the future, by asking people about their experiences and expectations with Smalltalk. Any programmer could participate and answer. The survey was designed to a broad developer audience.
Why is important you take this survey? Because you could help to a small(talk) community to uncover answers, to gather feedback and meaningful opinions, and to evolve by telling what you need most. The survey is open until 31/10/2014 at 3:15 a.m.

The survey is not biased towards any particular Smalltalk flavor (I am not affiliated with any particular Smalltalk provider). The following Smalltalk platforms have been included (any other not listed flavor can be added):

Methodology

I have collected a list of well-known forums containig "General Computer Programming" sub-forums, as most forums do not contain a Smalltalk sub-forum. I have rejected all programming sub-forums specific to a particular language, for example: JavaForum, PHPDevForum, "General C++ Forum", etc. Because:

  • Posts with surveys related to other programming language are not commonly accepted
  • They are marked as off-topic or closed.
  • It could be seen as promotion which is not the intent of this survey.

Results

The survey is still running! You can come back after 31/10/2014 and check responses.

lunes, 13 de octubre de 2014

Application Security 2: The CheckPoint Protocol

Introduction

As commented in my previous post, CheckPoint is a security pattern to avoid unauthorized access to a system.

The nice idea of the design pattern is to delegate complex validation behavior into specific classes which can manage events, response actions and statistics, completely transparent to your application. CheckPoints could be used to bypass validations for specific cases too. For example if you are debugging or testing your application, you don't want to be constantly bothered by timeouts and logins, you don't want to bias security statistics, and certainly you don't want to debug into someone's new bug merged in your repository, in the middle of your workflow.

The following sections describe how to use core classes for a typical application scenario.

Basic workflow

Let's assume an application is globally represented by a Singleton class, and it has different states. An state could be "in deployment mode" or "in testing mode". Each of these "modes" contain behaviors, implemented in specific CheckPoint subclasess. This simply means, you can use a Global Application class to answer a default CheckPoint class for your needs.

An example: Our Singleton manages application's state, and so it could be asked which CheckPoint should be assigned to each user, at a specific scenario he is in. This is, CheckPoint instances are associated to user sessions. Initially all newly created users will have a "invalid" or "unregistered" state. When the user begins the registration process, its session is given a CheckPoint instance to behave accordingly.

From here two different security scenarios are possible, depending on the registration state. Each scenario is represented by a CheckPoint subclass:

ASRegisterCheckPoint : Should be assigned while the (candidate) user is not confirmed as user. Maintains a registration object (ASUserRegistration), responsible to hold an unique link identifier, the registration time, and the corresponding candidate instance (ASCandidateUser). To optimize resources, a candidate user manages expiration (#hasExpiredRegistration) and that's a reason why is important to keep a #registrationDate.

ASDeployCheckPoint: This is a "common" CheckPoint which should be used for production systems, and when a registered user signs-in a system. It checks against typical login conditions, which we will se below in the Using the CheckPoint section.

Registering Users

Before anything else, create a repository and mock user to play with:
| cp newRegId |
cp := ASRegisterCheckPoint new.
newRegId := cp registrationId.
cp addNewUser: (ASCandidateUser new
    entityName: 'alphabetic name';
    username: 'alpha3';
    password: 'alphanumeric123';
    registrationId: newRegId;
    yourself).
Trying to add another candidate with the same username will raise an ASUserExists exception. Ideally you should catch and handle it appropiately in the context of your application. You can now query if you can register this candidate:
cp isValidPendingRegistrationId: newRegId.
and register as valid user in your system:
cp registerCandidateAsUser: newRegId.

Using the CheckPoint

Continuing with the Session-based example, login code which uses the CheckPoint could ask for the current user CheckPoint, and perform a global validate and retrieve:
user := self checkPoint 
  loginUserNamed: 'myuser'
  password: 'anypassword'
  machine: '0.0.0.0'.
The message send performs three major steps:
  • Validate authentication settings for the provided parameters
  • Validate if passwords match.
  • Answer the user from the repository
You can also chain exceptions to manage fail conditions, logging messages or block an user:
loginExceptions
 ^ ASEmptyError , ASInvalidUsername , ASEntityNotFound , ASPasswordError , ASMaxUserFailCountError
  , ASMaxMachineFailCountError , ASMaxGlobalFailCountError , ASDenegatedAccess
and manage the exception properly:
[ cpUser := self checkPoint loginUserNamed: usernameString password: passwordString machine: '0.0.0.0' ]
 on: self loginExceptions
 do: [ :ex | ^ self handleFailedLogin: ex ].

CheckPoint verifications

Login an user should perform a number of checks which, many times, are application security specific. The default implementation is naive, but useful for many cases. For specific security requirements, validation settings are customizable by subclassing ASDeployCheckPoint and specializing the method #validateAuthSettingsLogin:password:machine:. This is how looks like as in the current release:

 (userString isEmpty or: [ userString isNil ])
  ifTrue: [ ^ ASEmptyError signal: 'Username' ].
  
 (passwordString isEmpty or: [ passwordString isNil ])
  ifTrue: [ ^ ASEmptyError signal: 'Password' ].
  
 (self isValidIpAddress: ipAddressString)
  ifFalse: [ ^ ASDenegatedAccess signal ].
  
 (self validationSettings allowedUsernameCharacters includesAllOf: userString)
  ifFalse: [ ^ ASInvalidUsername signal: 'Invalid characters ' , userString ].
  
 (self validationSettings allowedPasswordCharacters includesAllOf: passwordString)
  ifFalse: [ ^ ASPasswordError signal: userString ].

(Remember, this is not code checking on User-Agent side, this is Application Security so your application's security can be guarantee independently of UI code).

A first look at Validation Settings

If you have ever worked with an Expert System, you already know what a Rule-Base is, and probably have figured out that all verifications could be easily written using rules. Although currently Application Security does not use rules, it seems a good point to note the direction where our model should be going to (if you want to read a really cool chapter about Rules-Based Expert Systems, try the one from Robbie T. Nakatsu in Diagrammatic Reasoning in AI)

Validation setting objects are maintained by CheckPoints and useful during registration time. They notify authorization/authentication exceptions and answer limit settings like:

  • Maximum size for characters allowed for a user name.
  • Maximim size for characters allowed for a password.
  • Characters allowed by a password.
  • characters allowed by an user name.
  • Expiration days for a password.
  • Valid IP addresses

As they are CheckPoint specific, they could be changed at run-time for an user or a group of users, which is very handy for debugging purposes. And that's all for today, in the following post I will post how to set up password rules to customize validation settings. See you soon.