General 07 Aug 2008 12:19 am

Comments Disabled

Due to the increasing amount of comment spam I’ve had to deal with recently, all the entries on the development log are now comment locked. Since I’ve stopped working on the site for various reasons, I don’t expect this site is seeing a lot of traffic anyway.

My apologies in advance if somebody has come by and is dying to comment on my entries (okay, or not) but spam is the sad reality of the Internet these days and I don’t have time to deal with it on a site I’m no longer maintaining.

Apache & FastCGI & Ruby on Rails 18 Jan 2007 07:37 pm

Apache + FastCGI on Windows

I thought my development environment was set up and working properly but when I began to write my Ruby code, I discovered that it was not. When accessing Rails controllers, I would see the generic Rails server error message instead of my view.

After following a few dead ends – searching for the error message in the Apache log on Google, switching back and forth between CGI and FastCGI and writing a test application in a directory without a space in its path (hey, you never know) – I stumbled on a post similar in nature to my problem on the TextDrive Community Forum. As one of the replies in that thread advised, advance cash loan overnight,overnight cash advance,advance cash overnightpayday us fast cash loan,fast cash payday loanadvance cash loan onlinecash advance servicescash advance nowcash advance loangewinn spieleeuropa casino bonuscasino club bonuscasino slot gamesslots gratisbaccarat spielencasino online deutschcasino games pro 2007kasino spielenpokerstars bonuspoker ohne geldonline poker roomsonline poker javatexas holdem setpoker texas holdpoker game mactwo feet texas holdemholdem poker softwarepoker spiel kaufenholdem poker tipspoker regeln zum ausdruckenstrip poker online gametornei di poker on linepoker texano gratispoker gamepoker in linea gratis,poker in linea,poker lineastreet poker gratistornei poker on linetexas holdem poker downloadpoker texas holdem gratispoker texas holdem,3c texas holdem poker,texas holdem poker regolegiochi 7 card studscuola poker onlinegiochi poker texasstrip poker livepoker online in italianoeurobet pokerpoker online downloadpoker texas holdem,texas holdem,texas holdem calculatorforum poker onlinegiochi on linegioco poker italianogiochi poker gratis da scaricarepoker sexi gratis I ran “ruby dispatch.fcgi” from my test application’s public directory and I discovered that the fcgi Ruby Gem is not installed on my system (Ruby Gems are software modules that expand Ruby’s functionality, much like the CPAN library for Perl). Oops.

After some more cingular free go phone ringtones free phone ringtones nextel ringtones cd ringtones for alltel cell phone 24 free ringtones компютриfree alltel ringtones 2 pac ringtones free kyocera ringtones 24 ringtones theme boost download free mobile ringtones new ringtones send free ringtones to your phone download nextel ringtones software free phone ringtones verizon wireless download free mobile ringtones real music ringtones crazy download free frog ringtones mobile phone ringtones download free sprint ringtones c139 free motorola ringtones Googling, I found the FastCGI and Apache2 for Windows XP entry on the Rails Wiki which helpfully points out Ruby for Apache, an installer that includes a precompiled binary of the fcgi gem. Installing Ruby for Apache did the trick and now my application is nice and snappy (and running under FastCGI).

DBDesigner 4 & MySQL & Ruby on Rails 11 Jan 2007 11:39 pm

Still More Schema Trouble

I had to change the schema again. I’d forgotten how picky Rails is.

As I discovered at a very helpful typepad user’s site, each User has_one Account. Each Account belongs_to one User. The user_id must be stored in the record for the account rather than the other way around.

I’ve uploaded the new SQL script.

DBDesigner 4 & MySQL & Ruby on Rails 11 Jan 2007 11:13 pm

Small Schema Glitch

Consistency, consistency, consistency.

I’ve had to update my SQL script since some of the tables didn’t have underscores separating the words – when working in Ruby, by default, database tables should have words separated by underscores and the corresponding models should use camel case so that all the Rails “magic” works as it should, e.g. Table name: email_addresses; Model name: EmailAddresses.

I also discovered extraneous foreign keys in the schema as exported by DBDesigner – I don’t need (and in fact can’t use) the foreign keys “students_user_id” and “faculty_user_id” since Rails won’t know how to update them and the foreign key constraints will fail.

Back to modeling.

DBDesigner 4 & MySQL & MySQL Workbench & Ruby on Rails & SQLyog 11 Jan 2007 10:42 pm

Basic Database Schema

Well, I have the database schema to support most of the current site features ready to go.

After the ridiculous headache with SQLyog, I discovered MySQL Workbench which looked like the answer to my prayers. It doesn’t work yet. “Alpha” is stretching it, guys – Alpha software is supposed to be finished and going through internal testing. MySQL Workbench doesn’t even seem to be able to delete objects yet.

I then discovered DBDesigner 4 which, again, looked like the answer to my prayers. I fired it up and discovered, to my dismay, that it only supports connections to MySQL 4 and we’re using MySQL 5. Fortunately it also supports exporting SQL scripts which I can then import into MySQL using the command line tools.

In any case, I’m exporting SQL script files from DBDesigner and that’s working reasonably well for now. The only changes I have to make to the DBDesigner scripts are to remove a compound private key (”user_id”) from the “students” and “faculty” table definitions since Rails doesn’t like compound keys. In the schema, “users” is a generalization of “students” and “faculty” since students and faculty (and any other user types we might pick up along the way) do have attributes in common (e.g. First Name, Last Name).

In case anybody is curious, I’ve uploaded the script that creates the Rocket Surgeons site database.

In my experience, the database is the hardest part of building Rails applications but I haven’t created an application with quite this level of customisation before so we’ll see how it goes.

Next up, creating models and defining relationships.

MySQL & Ruby on Rails & SQLyog 15 Dec 2006 12:33 am

SQLyog vs. MySQL BIT values – fight!

One very nice thing about Rails is that it handles boolean values very well – the Rails framework will automatically convert MySQL BIT values into pretty HTML checkboxes and handle all the back-end code to keep them updated*.

Well, it turns out SQLyog – the graphical MySQL client I’m using to build the site database – doesn’t properly support BIT values. Looks like I’m going to have to alter the MySQL tables manually to set the default value for certain attributes, and I’m going to have to manually edit the correct values into existing records.

As bad as it was (it crashed a lot and was apparently violating the MySQL AB licensing terms), the discontinued “MySQL Front” client did actually properly support BIT values.

It’s one thing after another, it seems.

*Very occasionally, you have to call the update-attributes function from your controller to save checkbox state manually but only if you’re straying from the common-case functionality of the Rails controllers.

Apache & FastCGI & Ruby on Rails 14 Dec 2006 10:50 pm

Apache 2.2 and FastCGI

Well, learning about mod_rewrite took a lot less time than I thought it would – there was a nice overview of the options that relate to Rails on the Rails Wiki. I’ve learned enough about mod_rewrite to know that what I want to do is not easily do-able so we’ll stick with the solution we have and change the pages over one by one on the testing site.

It looks like the live site is going to be moved from static to dynamic in one huge leap. I am not dealing with this on there because I know something will break.

Now to the actual point of this post: Apache 2.2 and the official distribution of FastCGI do not get along.

Ruby on Rails is s-l-o-w using the standard CGI module – and by slow I mean excruciating – so I decided to switch to FastCGI. Turns out there’s no stable, pre-compiled version of mod_fastcgi for Apache 2.2. Sweet. I uninstalled Apache 2.2 and moved to Apache 2.0 to get things working on my development machine.

Downgrade, reconfigure, start server and… everything worked, first try. Bonus!

I’m glad all this stuff is taken care of on the web host so I won’t have to fiddle with it.

Apache & Ruby on Rails 14 Dec 2006 07:25 pm

mod_rewrite OH GOD!

If I return from the Christmas break stark raving mad, blame Apache mod_rewrite. Oh, and let’s not forget the blame that Ruby on Rails shares for this.
For reference, any of the following are fine but I wouldn’t suggest mixing them:

  • Following the W3C’s advice about using URIs that won’t change, e.g. /homework/ instead of /homework.shtml.
  • Installing and using Ruby on Rails to convert parts of a mainly static site into a dynamic one.
  • Not understanding anything about how mod_rewrite works.

Because I followed the W3C’s advice (which is sound advice, by the way – good URIs don’t change), nearly everything on the Rocket Surgeons site is an index.cgi / index.html / index.shtml / default.css file inside a directory so that the section can be called by name.

When a Rails project is installed, by default it captures every directory and tries to map it to a Ruby controller.

I can override this behaviour on a file-by-file / directory-by-directory basis using mod_rewrite directives but I haven’t the first clue how mod_rewrite works so I can’t come up with a cleaner, more efficient, less error-prone way to fix this.

I have it working now (by overriding all 9 of the static directories) but I’ll definitely have to learn more about mod_rewrite before too long, otherwise the combination of these three things will drive me to the brink of insanity.

New Features & Security 13 Dec 2006 09:52 pm

User Auth

Well, here goes. I’ve been putting this off for ages but it’s time to finally get in gear and get user auth working.

Now, by user auth I technically mean two things. Firstly, user auth is user authentication – are you who you say you are? Secondly, user auth is user authorization – do you have permission to do what you are asking to do?

What I’m working on right now is user authentication.

User authentication is a somewhat complicated beast because you have to make the login sequence as secure as you can without horribly inconveniencing the user.

What I would really like to do is use SSL so I only have to worry about the security of the database and the scripts, not the security of the transmission line but since an SSL certificate and a static IP from our web host would cost about $50 USD a year, it’s not in the cards right now. Eliminating the possibility of using SSL, it looks like I’ll be using challenge-response authentication.

Basically, how challenge-response authentication works is this:

  1. The server (in this case the Rocket Surgeons web host) issues a “challenge”. For our purposes, this will be a single-use session id generated by the login script or possibly by the web server itself.
  2. The client receives the challenge, modifies it in some way that’s known to both the server and the client (for example, combining it with a value both the server and client know, then running it through a one-way encryption scheme, commonly known as “hashing“) and returns this “response” to the server.
  3. If the response is what the server expects, the session ID becomes the user’s login token. The client can present this token to the server and the server knows that the user is who they say they are.

For a user to log in to the Rocket Surgeons site:

  1. The server issues the challenge by including a session ID in the login page (or by setting a cookie, if the user has them enabled) and storing the IP address to which the challenge was sent. Unused session IDs will expire after a certain amount of time, meaning the user only has that amount of time to complete the login process. If the session times out, the user can always request a new session ID and try again.
  2. When the user has typed their information into the login page, JavaScript will be used to check the values on the login page to make sure they’re valid before sending them to the server. This is for the user’s convenience, since they’ll be checked again by the server before being processed – information sent from the user’s client can’t be trusted for a variety of reasons, for example the user may not have JavaScript turned on or they may be using a browser that has a broken JavaScript implementation; the user may also be a jerk who’s trying to break the site on purpose.
  3. The client’s response for our implementation will be very similar to the one used on LiveJournal, except it will use a different hashing algorithm. The client will calculate the SHA-1 hash of the user’s password, join it to the session id, then run the resulting string through the SHA-1 algorithm again. This hash will be sent to the server, along with the user’s username.
  4. Once the server receives the information, it will check that the user’s response was correct by performing the “response” calculations itself. Finally, the IP address of the client is checked to make sure that the IP address that sent the correct response is the one to which the challenge was issued. This prevents malicious users from logging in as somebody else by sending data they “overheard” to the server, which is called a replay attack.
  5. In-use session IDs expire after the user has been inactive on the site for a specific amount of time, unless they’ve explicitly asked to stay logged in indefinitely and they have cookies enabled. The server will also check that the user’s session ID and IP address match the ones they used to log in for every action that requires authentication. This prevents malicious users from being logged in as another user by copying a session ID and sending it to the server.

There are three drawbacks to this approach.

The first drawback is that password hashes can’t be “salted” in the database. Salting a hash is basically just mixing the data you want to hash with a known (but random) value before running it through the hashing algorithm. Salting hashes helps prevent certain types of attacks against the password database. Since every user has their own “salt”, even if two users pick the same password, the hashes of their passwords will be different, meaning that Alice has no way to tell from the hash itself if her password is the same as Bob’s. Salting also helps against dictionary attacks, where an attacker guesses at what the password could be using a list of words. The attacker would have to know the salt of every user whose password he wanted to break.

The second drawback of challenge-response authentication has to do with initially setting a password – in order to figure out the correct response to a challenge, the server has to have the user’s hashed password. In order to have the user’s hashed password, the user has to send it to the server. If an attacker were listening at just the right time, it would be possible to steal this hashed password while it was being sent and use it to log into the system.

The third (and most important) drawback of challenge-response authentication is that it does nothing to prevent a type of attack called a “man-in-the-middle” attack, where an attacker pretends to be the server while talking to the client and pretends to be the client while talking to the server. The client will happily send all the information a man-in-the-middle needs to break into the user’s account, thinking it is talking to the server. All the man-in-the-middle has to do is pass messages between client and server and wait for the password information to be sent. Once the man-in-the-middle logs in, they can change the password on the user’s account and the account is theirs.
The salting problem is not a huge problem since the password database itself is reasonably secure – in order to steal the database, an attacker would have to break into our web host first.

The initial password setting problem is a little bit more worrisome but frankly, we don’t have very many users and it can be worked around by requiring the user to activate their account by e-mail before logging in for the first time.

I know of no real solution for the third problem (except using SSL). For an account to be stolen however, the user’s network would have to be compromised. Since we have so few users anyway, I could always manually reset any compromised accounts. Hopefully by the time the site is starting to get unmanageable numbers of accounts, we’ll have an SSL certificate.

So here goes. We’ll see how long this takes.