CloudforkSSO on Pharo with stunnel

Posted February 23, 2011 by Jan van de Sandt
Categories: Cloudfork

Tags: , , , ,

The latest version of CloudforkSSO (version 1.1.0) on Pharo uses the Zinc-HTTP library. This library contains a good http client. Actually it contains multiple http clients, depending on your requirements you can pick one of them.

One feature Zinc-HTTP doesn’t support (yet?) is secure http. Most of the OAuth and OpenID providers require https connections so this is a problem. There is a good workaround for this: you can use stunnel to handle the https protocol.

I used the following stunnel.conf on OS X:

; protocol version (all, SSLv2, SSLv3, TLSv1)
sslVersion = SSLv3

; security enhancements for UNIX systems
; for chroot a copy of some devices and files is needed within the jail
chroot = /opt/local/var/lib/stunnel/
setuid = nobody
setgid = nogroup
; PID is created inside the chroot jail
pid = /stunnel.pid

; performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
;compression = zlib

CAfile = /opt/local/etc/stunnel/cacert.pem

; SSL client mode
client = yes

[google]
accept = 127.0.0.1:20011
connect = www.google.com:443

[twitter]
accept = 127.0.0.1:20012
connect = api.twitter.com:443

[facebook]
accept = 127.0.0.1:20013
connect = graph.facebook.com:443

The cacert.pem file is required to validate the server certificates. I downloaded a version from http://curl.haxx.se/ca/cacert.pem.

Now the Smalltalk side of things:

Load the latest CloudforkSSO version:

Gofer new
	squeaksource: 'Cloudfork'; 
	package: 'ConfigurationOfCloudforkSSO';
	load.
(Smalltalk at: #ConfigurationOfCloudforkSSO) project latestVersion load: 'Tests'

Instruct CloudforkSSO to use the tunnels for the secure hosts:

	self default httpClient: ((CFHttpClientTunnelAccess new)
		client: CFHttpClientZincAccess new ;
		tunnel: 'www.google.com' through: 'localhost:20011' ;
		tunnel: 'api.twitter.com' through: 'localhost:20012' ;
		tunnel: 'graph.facebook.com' through: 'localhost:20013' ;
		tunnel: 'open.login.yahooapis.com' through: 'localhost:20014' ;
		tunnel: 'openid.hyves-api.nl' through: 'localhost:20015' ;
		yourself )

Also see the example CFServicePharoUtils class>>setupHttpsTunnels. You can test the connection:

CFPlatformServiceUtils default httpClient httpGet: 'https://www.google.com/'

The demo application at http://sso.doit.st is also using stunnel.

Note that there are alternatives for stunnel. One of them is described here.

CloudforkSSO – OpenID and OAuth support for Smalltalk

Posted February 15, 2011 by Jan van de Sandt
Categories: Cloudfork

Tags: , ,

With the CloudforkSSO library you can let the users of your Seaside web application login using their Google or Yahoo accounts. This works using the OpenID2 protocol. CloudforkSSO also contains OAuth support. With this protocol you can ask users for permission to access their data on other websites.

Some providers that you can integrate with:

Google – Google supports OpenID2 and OAuth1. You can use them separately or together. With OpenID2 users can identify themselves using their Google accounts. It is also possible to get some information about the user. For example the user’s name and email address.

Google’s OAuth1 support is really powerful. With it you can access and modify (if the user agrees!) a users calendar, contact, documents and a lot more.

Twitter – Twitter supports OAuth1. You can ask a user for read-only or full permission.

Facebook – Facebook supports OAuth2. You can access the social graph of a user.

A demo of this library runs at http://sso.doit.st.

OpenID2 and OAuth1 are pretty complex protocols. CloudforkSSO implements part of the protocol, enough to support the major providers like Google, Yahoo and Twitter. OAuth2 is a simple protocol. If OAuth2 is all you need CloudforkSSO is probably overkill. A HTTP Client with ssl support is enough.

I developed CloudforkSSO in Pharo Smalltalk. Most providers require secure communication via https. As far as I know, the only HTTP Client for Squeak and Pharo that supports https is WebClient with SqueakSSL. This works fine on Windows but on Ubuntu Linux the SqueakSSL plugin doesn’t work with some providers, for example Twitter and Yahoo. Hopefully this will be fixed soon.

There is also a VA Smalltalk port on VAStGoodies.com which does work on Windows and Linux.

The package Cloudfork-SSO-Seaside contains a demo component that shows how you can use the functionality. Note that for OAuth you need an API key and secret for the provider you want to use. For OpenID it is important to set the correct realm. This is the host and port where your app is running. You can set these configuration properties using the Seaside configuration app:

EC2 AMI with Smalltalk and Seaside: Update 3

Posted October 10, 2010 by Jan van de Sandt
Categories: Cloudfork

Tags: , , ,

Today I published a new version of the Amazon EC2 image with Smalltalk and Seaside. The third version contains the following software:

  • Ubuntu Server 32bit 10.04 LTS (release 2010-09-23)
  • Apache HTTP Server 2.2
  • SqueakVM 4.0.3.2202 Unix VM
  • PharoCore 1.1.1
  • Seaside 3.0

The AMI identification: ami-c2fe0aab

The update to the Ubuntu server makes it easier to run the AMI as a Micro (t1.micro) instance type. This is currently the smallest and cheapest EC2 image type. The image type is very well suited for running Seaside web applications. When your application becomes more popular you can scale by using a bigger instance type or by running multiple instances.

Creating a Seaside runtime image with Pharo

Posted September 8, 2010 by Jan van de Sandt
Categories: Uncategorized

Tags: ,

For the ec2 machine image with Seaside I prepared an image with only the runtime packages of Seaside. The image was based on PharoCore 1.1. This is the core Pharo image without development tools and extra libraries. The Seaside development tools can be very convenient during development but in a production environment they can be a serious security risk. You can disable them but the easiest and safest option is to not load these packages into your runtime image.

This is the recipe I used to setup the image:

1. Download the latest (stable) PharoCore

2. Load the Seaside 3.0 metacello configuration:

Gofer new
	squeaksource: 'MetacelloRepository';
	package: 'ConfigurationOfSeaside30';
	load.

3. Load the Seaside runtime packages we need

((Smalltalk at: #ConfigurationOfSeaside30 ) project latestVersion) 
	load: #( 'Base' 'Seaside-Adaptors-Comanche' 'JQuery-UI' 'Seaside-Examples').

4. Start the Komanche http server on port 8080

(WAComancheAdaptor port: 8080) start

5. Load the VNC Server (for remote image “management”)

Gofer new
	renggli: 'unsorted';
	package: 'RFB';
	load.

And finally I loaded my Seaside app and configured this app as the default app in Seaside.

"Load small demo Seaside app"
Gofer new
	squeaksource: 'Cloudfork';
	package: 'Cloudfork-EC2Demo';
	load.
	
"Make ec2demo the default Seaside app"
WAAdmin defaultDispatcher defaultName: 'ec2demo'.

This “lean-and-mean” Smalltalk image worked fine for me. I also exported the FileLibrary to the Linux file system so the static resources can be served by Apache directly. This is documented in the Deployment chapter of the Seaside book.

Update: Tip from Mariano Martinez Peck
You may want to evaluate a “ScriptLoader new cleanUpForProduction” after downloading PharoCore.
This will clean a lot of stuff and remove a lot of code (like tests) that may not be needed in production environments.

A new public EC2 AMI with Smalltalk and Seaside

Posted August 29, 2010 by Jan van de Sandt
Categories: Cloudfork

Tags: , , ,

This weekend I created a public Amazon Machine Image (AMI) setup as a Smalltalk web server with a Linux SqueakVM, a Pharo 1.1 Smalltalk image and the Apache2 web server. Anyone can use this AMI as a robust and scalable runtime platform for their Seaside applications.

In this article I will try to explain how you can you can use and customize this image. First their are some prerequisites:

Using EC2 is not free, you have to pay for each hour the server runs and you have to pay for storage and bandwidth. Seaside runs fine on the smallest 32bit AMI that costs $0,085 cents per hour. Bandwidth is $0,15 per GB (the first GB is free). You can get a discount on the costs per hour if you reserve you AMI’s beforehand.

The AMI is based on a 32bit Ubuntu 10.04 server AMI. The Ubuntu server is a very minimal install, I have added Apache2 and the SqueakVM. I have also setup a Pharo image with the Seaside runtime packages and Apache2 is configured in such a way that all requests are forwarded to Seaside.

How can you start using this AMI?

Start an EC2 instance using the public AMI ami-0800ea61 (ubuntu-10.04-i386-smalltalk-server-v01). The AMI is available in the US East region. This is the cheapest region :-) When you start the image you have to select a security group. This defines the firewall rules for the AMI. You can select the default group or some other group that allows TCP connections for the ports 22 and 80.

When the image is started it should have a generated a public DNS name. When you enter this name in the address bar of your browser, you should see something similar to http://ec2demo.doit.st If the web page is shown it means that everything is running OK.

You can connect to the running AMI instance using ssh. You should login with the userid ubuntu. No password is required because a private key is used for authentication. The Pharo image that runs on the AMI includes RFB, a VNC server implementation. With a VNC client we can remotely control the Smalltalk image. The best way to do this is to tunnel the VNC connection (port 5900) through ssh:

ssh -i id_rsa-gsg-keypair -L 5900:localhost:5900 ubuntu@ec2demo.doit.st

Now you can connect to the image using a VNC client use display number 0 and the password is seaside. Note that you have to keep port 5900 closed for direct access otherwise this would be very unsecure.

Through the VNC client you have access to the Smalltalk image. You should see a workspace. I used the code in this workspace to build the image from a standard PharoCore 1.1 image. Note that I only loaded the runtime parts of Seaside and some small examples. This image is used for hosting an application and not for development so it is probably safer and more efficient to leave out the development packages.

If the image suits your needs you can just load your packages through Monticello. There is no config web application to configure your Seaside components. You can do this via the workspace or better, make a class side initialize method that does this automatically when the package is loaded. I used the the Apache2 configuration described in the Seaside book (the non-clustered setup for now). You can read the Deployment chapter for more details. You should have you app running within a few minutes.

If the Smalltalk image does not suit your needs you can replace it with another Squeak or Pharo image. The image is stored in the directory /srv/seaside If your new image has a different name you need to update the run script in the same directory.

Of course you can also install more Ubuntu packages. You could install a local database system like MySQL or PostgreSQL. But if you are really into cloud computing you probably don’t want to maintain a database yourself. Instead you can use RDS, an AWS managed MySQL service or SimpleDB. SimpleDB is a key-value store with a simple API and great scalability. You can use the Cloudfork ActiveItem Smalltalk library to persist your Smalltalk objects to SimpleDB.

To setup a nice domain name for your app (like ec2demo.doit.st) you should reserve a static IP using the AWS Console. You can then go to your domain name registrar and update the name servers to point to this IP number.

Ok, this is about it. If you have questions or ideas on how to improve the Smalltalk AMI please let me now. I think the current AMI can be used as a production environment for Seaside apps.

Amazon AWS Region Endpoints in Europe

Posted June 1, 2010 by Ernest Micklei
Categories: Cloudfork

Tags: , , ,

To use the Cloudfork classes for services located in Europe (Ireland), you need to change the serviceUrl property such as:

|sdb|
sdb := CFSimpleDB new.
sdb serviceUrl: 'http://sdb.eu-west-1.amazonaws.com'

Service URL
SimpleDB sdb.eu-west-1.amazonaws.com
SQS eu-west-1.queue.amazonaws.com
EC2 eu-west-1.ec2.amazonaws.com
SNS sns.eu-west-1.amazonaws.com
S3 Set Bucket location constraint to EU
RDS rds.eu-west-1.amazonaws.com

A comprehensive list can be found over at Elastician

Testing Cloudfork AWS SimpleDB based classes

Posted September 20, 2009 by Ernest Micklei
Categories: Cloudfork

Tags: , , , , ,

The Cloudfork framework includes an alternate implementation of CFSimpleBase that stores all items in memory. The CFSimpleDBEmulator was initially created to support the unit testing of the ActiveItem framework. With the exception of some query constructs, it implements the complete api and therefore is suitable for unit testing your own applications as well.

| emulator domain item |
emulator := CFSimpleDBEmulator new.
domain := (emulator createDomain: 'myapp.development') result.
item := CFSimpleDBItem newNamed: 'user.dennis'.
item valueAt: 'birthday' put: '20060916'  ;valueAt: 'hobby' put: 'soccer'.
domain putItem: item.

After running the tests, you can inspect the emulator to see what items have been stored in which domains and what attributes they have. If you store the emulator in some class var then you can keep the data around for development too.

ActiveItem
Because the ActiveItem framework is build on top of SimpleDB, the same emulator class can be used to unit test those applications. ActiveItem uses a globally shared CFSimpleDB instance so you only need to replace that with an emulated instance.

CFActiveItem activateWithSimpleDB: CFSimpleDBEmulator new.

Using the CFActiveItemSerializer you can even dump the items to a local Filesystem for development convenience.

Introducing WinCrypt for VA Smalltalk

Posted July 10, 2009 by Jan van de Sandt
Categories: WinCrypt

Tags:

WinCrypt is a new library for VA Smalltalk on Windows. It makes part of the cryptography functionality that is shipped with the Windows OS easily available from Smalltalk.

The following features are available in the initial version:

  • Symmetric encryption and decryption using RC4, DES, TripleDES and AES-256
  • The MD5, SHA and SHA-256 hash functions
  • The HMAC-MD5, HMAC-SHA and HMAC-SHA-256 message authentication functions.

The API is pretty simple to use. To encrypt a String or ByteArray using a password you can use the class methods defined in WinCryptCipher:

| encryptedBytes |
encryptedBytes := WinCryptAES encrypt: 'my-dirty-little-secret' using: 'puppy'

The results is always a ByteArray. This ByteArray can be decrypted and converted to a String:

| encryptedBytes decryptedBytes |
encryptedBytes := WinCryptAES encrypt: 'my-dirty-little-secret' using: 'puppy'.
decryptedBytes := WinCryptAES decrypt: encryptedBytes using: 'puppy'.
^decryptedBytes asString

The ciphers use a key with a specific size for encryption and decryption. When you provide a password string the key is derived from this password using the MD5 hash algorithm. It is also possible to skip this step and supply your own key.

The WinCrypt library is open source and is published on VAStGoodies.com. The included SUnit tests show how the library can be used. The underlying Windows functions are documented on MSDN.

Secure access to AWS from VisualWorks

Posted July 9, 2009 by Ernest Micklei
Categories: Cloudfork

Tags: , , , , ,

Cloudfork implements the REST API of the Amazon Web Services using both secure (https) and non-secure (http) communication. In order to use the https protocol to access S3,SimpleDB,SQS or EC2, you need to prepare the Smalltalk image by registering a trusted certificate. Without that certificate, your application will produce an error saying “CA Not in Trust Registry!” (CA = Certificate Authority). The steps below describe how to register the correct certificate in a VisualWorks (or WebVelocity) image.

Install HTTPS
Unless already loaded in your image, you need to install the HTTPS parcel (use Parcel Manager).

Export Certificate
Amazon WebServices uses the following root certificate “VeriSign Class 3 Secure Server CA”. You can verify this by inspecting the chain object in the debugger that can be opened if you have a failed secure test.

One way to get this certificate file is to export it from the list of certificates known to your Internet Browser. For FireFox users, open Preferences>Advanced>Encryption>View Certificates. Under VeriSign, Inc., select the certifcate, export it using the format “X.509 Certificate with chain (PEM)” and name it “VeriSignClass3SecureServerCA.pem”.

Import Certificate
The following script will import the Base-64 encoded certificate file.

| certificate registry |
registry := Security.X509.X509Registry default.
certificate := Security.X509.Certificate fromFile:'VeriSignClass3SecureServerCA.pem'.
registry addCertificate: certificate.

Please be aware of what is stated in the VisualWorks SecurityGuide.pdf (page 72): “Adding a CA certificate to your registry is deceivingly simple and does not convey the degree of trust actually involved in that action. Be sure to understand what it is you are trusting a CA to do and ensure that it matches the security requirements of your application.”

Run the Tests
Results of the secure Cloudfork Integration tests should all be in the green now.

Introducing WinHttpClient for VA Smalltalk

Posted June 17, 2009 by Jan van de Sandt
Categories: WinHttpClient

Tags:

WinHttpClient is a new HTTP client library for VA Smalltalk on Windows. This library uses a Windows DLL to perform the HTTP network operations. The DLL is called winhttp.dll and is available on all the current Windows platforms. Using this DLL all the features of the HTTP protocol can be used in an efficient way. This includes support for secure (https) connections.

This is a first release of the Smalltalk library; in this release not all the features are available from Smalltalk yet. But all the common functionality can already be used:

  • HTTP GET, POST and HEAD requests
  • Support for setting custom request headers and access to the response headers
  • Support for secure http (https) including support for client certificates
  • Streaming downloads and uploads
  • Proxy support
  • Server and proxy authentication support

We developed this library because the standard HTTP client of VA Smalltalk is not fully stable on Windows when using secure connections on multi-core systems. Nationaal Spaarfonds (a part of Delta Lloyd Group) has a VA Smalltalk application in production that needs to call secure webservices. This works fine most of the time but sometimes causes the image to freeze. See the Instantiations forum for a discussion of this problem.

WinHttpClient can be plugged into the VA Smalltalk webservice stack as a replacement for the standard HTTP client. Our stress tests show that the stability problems disappear after this switch.

The WinHttpClient library is open source and is available on VAStGoodies.com. If you are interested please try it out. If you have suggestions on how we can improve the API we would love to hear them. Contributions to add missing features are also very welcome.

WinHttpClient API

The API is structured the same way as the Windows winhttp library. You can find the documentation on MSDN: http://msdn.microsoft.com/en-us/library/aa384273(VS.85).aspx

Important concepts are Session, Connection and Request. Before you can do anything with the library you need a Session instance:

| session response |
session := WinHttpSession new.
response := session submitGetRequest: 
	'http://en.wikipedia.org/wiki/Smalltalk'

The WinHttpSession class has a number of submitXXX methods. These methods create and send HTTP requests and handle the responses. They return an instance of WinHttpResponse, this object contains the HTTP status, the HTTP header information and the contents.

If the contents of the response is possibly very large than it is better to use a streaming variant of the submit request which has a write stream as an argument. This method will still answer a WinHttpResponse instance but the contents variable of this instance will be nil.

After you have finished with the session you should send “session release”. This is because the session object contains a handle to a Windows structure that must be freed to prevent memory leaks. The class side of WinHttpSession contains a number of convenience submit methods that handle the release message for you.

WinHttpConnection

If you need to send multiple requests to the same host it is more efficient to work with a connection object instead of a session:

| session connection responses |
session := WinHttpSession new.
responses := OrderedCollection new.
connection := session connectTo: 'en.wikipedia.org'.
[
	responses 
		add: (connection submitGetRequest: '/wiki/Smalltalk');
		add: (connection submitGetRequest: '/wiki/HTTP');
		add: (connection submitGetRequest: '/wiki/Virtual_machine')
] ensure: [ connection release ].
responses

WinHttpRequest

Normally you don’t need to work with requests objects directly, you can just use the submit methods of the session or connection objects. Only when you need to set special options you need to access the request object directly. An example of this is when you want to send a request to a secure web server with an invalid server certificate. The default behavior of winhttp is to refuse the connection and throw an error. For example, if you want to accept certificates with an unknown certificate authority you need to set the “IgnoreUnknowsCA” option:

| url session connection request response |
	
url := 'https://www.securebutinvalid.com' sstAsUrl.
session := WinHttpSession new.
connection := session connectToUrl: url.
	
request := connection openGetRequest: url absolutePath.
request setSecurityOptionIgnoreUnknownCA.
request send.
response := request getResponse.

request release.
connection release.
session release.	
response

Note that we think this part of the WinHttpClient API is a bit awkward. The intention is to improve this in future versions.

Proxy support

WinHttp has support for proxy’s and a number of proxy authentication methods (Basic, NTLM etc). When you instantiate a session you can specify the proxy to use or you can use the defaultProxy class methods to set a default for all sessions.

It is also possible to copy the proxy settings that are configured in Internet Explorer. Use initProxyInfoFromIE class method of the Session class for this.

For more examples on how to use WinHttpClient see the unit tests in WinHttpClientTestApp.

Using WinHttpClient in the VA Webservice stack

The application WinHttpClientWebServiceSupportApp contains classes that can replace the standard HTTP Client with WinHttpClient for calling webservices. Thanks to the flexible way that webservice support is implemented in VA Smalltalk this is quite easy to do. We just have to replace the default HTTP and HTTPS dispatchHandlers with a custom version. We can do this when we create the webservice container:

| container httpHandler secureHttpHandler |

container := SstWSContainer containerNamed: 'test' ifNone: [ SstWSContainer createContainerNamed: 'test' ].
	
httpHandler := WinHttpDispatchHandler new.
secureHttpHandler := WinHttpDispatchHandler new.

container handlerFactory 
	register: httpHandler named: 'wsHttpClientRequestHandler' inNamespace: container handlerFactory globalNamespace;
	register: secureHttpHandler named: 'wsHttpsClientRequestHandler' inNamespace: container handlerFactory globalNamespace.
container

For a full example see the test class WinHttpWeatherForecastTest.

Secure webservices with client certificates

Supporting secure webservices that use HTTPS was very easy with WinHttpClient. But adding support for client certificates involved a bit more work. To set a client certificate for a request another Windows DLL is required: crypt32.dll. This DLL is also shipped with all the current Windows platforms. This DLL contains the functionality to handle certificates and all kinds of secure hashing, encrypting and decrypting functionality. In the future we can make all this functionality available from Smalltalk in a separate project. Currently WinHttpClient uses just a few functions from this DLL to set the correct certificate for a request.

You can tell the WinHttpDispatchHandler to use a client certificate by calling the setter method clientCertificateFilename:. The file you provide must be in one of the supported formats by Microsoft and must contain bot the certificate and the private key.

In the old situation we had the certificate and the private key in two separate pem files. WinHttp cannot handle this. We used openssl to convert the two pem files into a single pfx file:

openssl pkcs12 -export -out testcert.pfx -inkey testcertrsa.pem -certfile testcert.pem


Follow

Get every new post delivered to your Inbox.