CustomAuth.cpp Get User Info and Decode It

GetUserInfoAndUpdateCookie

This function pulls the user information out of the cookie. It parses out the credentials from the cookie and passes them along to the DecodeAndDecryptCredentials function. In return, it gets the plain username and password, and uses those to log the user into the server.

The LogonUser function used essentially logs the user in the same as Basic authentication. So anything you might have been doing with Basic authentication you should be able to do with this, and then some.

Then the user information is set along with the token used for impersonation.

DecodeAndDecryptCredentials

This is the function where you would put your decryption code. That is, if you encrypted the credentials in the first place, which I HIGHLY suggest you do.

The login page I used was a ASP.NET page, so I used encryption that could be encoded/decoded in both .NET and C++.

CustomAuth.cpp Logon/Logoff

ProcessLogon

The first part of this function checks for the login cookie. It does not do any verification of the data in the cookie here, only that it exists, because if the data was not verified, the cookie would be deleted elsewhere.

If the cookie exists, then we set the url that the user will be directed to now that they have logged in. This is where the DEFAULT_USE_SUCCESS_URL information could be used, but I’m not going to go into that.

Then the user is redirected with a 302 response to the successful login page specified with a Location header.

ProcessLogoff

This is what I used to get all of my debugging information while I was learning. By using the built-in logoff page, I could insert information from elsewhere in the filter to the logoff page.

If using the built-in logoff page, then a 200 response is sent while printing out the logoff page to the Response Buffer. During this process, I would print out the content of the g_userName variable, which could have anything from seeing if HTTPS was enabled, to the actual username (which is why the variable is named that, I just never changed it), to seeing if any variables are holding the information you expect.

Otherwise, the user is given a 302 response and redirected to the logoff page defined in the .ini file.

Then, the login cookie is deleted. The cookie is what is used to log the user in or allow them to be logged in automatically the next time they visit the site. Removing the cookie will not log them out of the server, but will prevent them from automatically logging in next time.

CustomAuth.cpp

These next few posts I’m going to discuss the changes between the original CustomAuth.cpp and the version I modified. I’m only going to talk about the changes I made and talk about 1-2 functions in each post. If a function is in the code but I don’t talk about it, then it wasn’t changed, is fairly simple, and can be figured out while looking at the code. Besides, Microsoft/people who wrote the code did a great job with comments.

HttpExtensionProc

This function is the entry point of the filter where all the commands are given. It is the entry point for IIS and decides what to do with each request.

First, the function checks to see if authentication has already taken place and passes the request along. It also grabs the url for use later on. Then it checks to see if it is a Logon or Logoff request and passes to request to each appropriate function for handling, ProcessLogon or ProcessLogoff. If we are using the built-in login page, then it checks for that and passes the request to the SendBuiltinLogonPage function where the login page will be returned.

Now, if nothing else has been done, then we check for the login cookie. If the cookie is found, then an attempt is made to log out the user from the server. If that was successful, then the credentials are pulled from the cookie with the GetUserInfoAndUpdateCookie function. The user is then logged into the server, the cookie and user information is cleared, and the request is passed along. If a cookie is found, the user is logged off of the server to make sure their credentials are correct.

After any processing, the request is then passed along for IIS to handle like any other request.

ISAPI Tools and CustomAuth.h

I’m so bad at this blogging thing. It’s just documentation and I’m the type that enjoys coding. So I keep getting distracted by actually working on current projects. However, slowly and surely, I will get these posts made.

The ISAPI Tools part of the CustomAuth project are the original classes created by Microsoft. I never modified those classes, but took advantage of them throughout the project. So, with the original and modified versions, you can use the ISAPI Tools classes as they are.

Very few changes have taken place within the CustomAuth.h file. I moved the includes and prototypes from the CustomAuth.cpp file and put them in the header. I did this simply because it was the way I was taught to organize my code and I feel more comfortable with it. It is more aesthetically pleasing to me and helps me read through the code.

A few defines have changed. The “#define MODULE_NAME” was split into two seperate defines, INI_NAME and DLL_NAME. This was done so that you could change the names of the DLL and INI as needed, so the .ini file name was not tied to the .dll file name.

The LOGON and LOGOFF defaults were set to 0, since I think you should use a custom login and logoff page for encryption.

DEFAULT_USE_CLIENT_IP and DEFAULT_LOGON_TIMEOUT were removed since the IP was no longer being used for encryption and the timeout can be set on the cookie, rather than within the filter.

DEFAULT_USE_SUCCESS_URL was added if you want to disable the use of redirection. Currently this define is not being used anywhere, but the option is there with some changing of code.

Then the DELETE_COOKIE content has changed alittle. The addition of a domain to the cookie allows it to be accessed from any subdomain under that domain, rather than being limited to a single specific site. This is a limitation for the filter that it is set to a single domain and cannot work cross-domain.

Finally, a few more global variables have been added to the list and a comment was added above the built in logoff page define. By inserting that code into the logoff page, within the CustomAuth.cpp you could print out some information on logoff. This helped me in the beginning since I didn’t (and still don’t) know how to access the information printed out with the WriteDebug function.

CustomAuth Overview

Since there is already an excellent overview for the original CustomAuth, I’m not going to re-invent the wheel. However, that overview is in a help file for CustomAuth on Windows Server 2003 and I could not find it anywhere on the web. So for the purpose of sharing that useful information to as many people as possible, I have taken that overview and put it into a word doc. This information will be skipping ahead of what I’m going to discuss in this post, but most of it is relevant.

CustomAuth Documentation

So after reading the initial documentation above, you should have a general understanding of the original purpose of the original CustomAuth.

The way CustomAuth works is based on denied permissions to access a file on a web server. When someone that is not authenticated tries to access a webpage, they access the page’s physical file using the anonymous user account (IUSR_*). This authentication method denies access to that page for the anonymous user, thus throwing a 401 denied access error response. Since CustomAuth is actually two parts, an ISAPI Filter and an ISAPI Extension, the filter portion is what catches this 401. The filter sees that this error was thrown and replaces that response to the user with a 302 redirection response to the login page, which is set in the CustomAuth.ini file.

One of the modifications added to the CustomAuth filter is the ability for redirection back to the original page trying to be accessed. This is done by adding the original url as a querystring variable added on to the login page url. So instead of just redirection to www.domain.com, we instead redirect to www.domain.com?url=www.domain.com/stuff/page.aspx. Then the login page can take that url and redirect to it instead of the normal login success url defined in the CustomAuth.ini file.

So the filter portion has redirected the user to the login page. The login page will take the user’s credentials and put them into a cookie. Normally the credentials would be in cleartext and each time the server reads the cookie it would be in cleartext. Using SSL is suggested, which with CustomAuth, SSL can be used while giving the functionality of Basic authentication. I suggest using some form of encryption along with SSL, which will provide more security, however you will need encryption that can be decrypted inside the filter which is written in C++.

Once the user logs in and the cookie is created, the ISAPI extension checks for the cookie and pulls the credentials from it. It then attempts to log the user into the server with those credentials. If the login fails, the user is redirected back to the login page. If the login was successful, the user is redirected to the login success page or the original page they were trying to access. Now any file the user has ACL read access to can be viewed, since they are no longer using the anonymous user credentials but their own ACL permissions. Additional permission restrictions can be applied to the user inside the website code as well, so instead of permission being granted or denied based on ACL permissions, they are instead given or denied based on a user group or database entry.

Since the credentials are stored in a cookie, the user will no longer need to login as long as that cookie persists. Also, if the cookie is setup with a specified domain, such as .domain.com, any subdomain that has the CustomAuth filter installed on it will automatically log the user in as well. So if two websites have the filter installed, books.domain.com and cooking.domain.com, if the user logs into one of the sites, they will automatically be logged into the other if they visit it.

Now the user can also log out of the server with CustomAuth. A simple link needs to be provided that the user can click and log off. When the user logs off, they will be redirected to a specified log off page set in the CustomAuth.ini file.

This was a very basic overview of CustomAuth and the modified CustomAuth on the flow of how it works. There is alot missing here, but hopefully it will give an idea of the general steps involved in this authentication process. More to come.

Modified CustomAuth

First the code, then the tweaks, and last the headaches.

First I will do a sort of overview, then I’ll go into the code and talk about what I changed, what I took out, and why I changed those sections. I’ll make detours and jump ahead if it seems right to me to do so, but if it seems confusing, just skip it and come back later. All of this information could just be very confusing or it may be way too simple, I don’t know, but here it is.

Cleaned Custom Auth

Change the extension from .doc to .zip and unzip the project. This is the baseline code that I will be building up from and will not work in its current state. Just open it up, take a look, perhaps compare it to the unmodified CustomAuth, and try to get comfortable with what is going on. If your eyes glaze over, that is fine, with time and repeated viewings, it will become clearer.

The ISAPI Filter Adventure Begins!

I haven’t posted in a long time due to work, hobbies, and just being lazy. But I’m here now, and that’s all that matters.

Anyway, the next series of posts is going to be about my experiences modifying CustomAuth, a Microsoft ISAPI Filter/Extension. I’m going to try to make my posts shorter, each post talking about a different modified section of code or problem I encountered. Also, if you don’t have to, I would advise against implementing this form of authentication. There is not very much documentation that I have found (thus why I’m posting it here) on the subject, it is not supported, requires a great deal of customization, and generally you should try to find a supported solution or one with lots of documentation.

To start, you can try to get the Microsoft Server SDK, which will give you the source code for the CustomAuth Filter. It will also give you the ISAPI Tools files for it as well. I haven’t tested this version of the SDK, but I think this should be right.

Download Windows Server 2003 R2 Platform SDK

A great reference for this topic is David Wang, whose blog provides more advanced and generally ideological solutions rather than specific fixes. A specific blog post discusses the compiling of the CustomAuth files which I will be going over in a later post.

HOWTO Install and Use CustomAuth on IIS6

Overall a great help to me and a wonderful blog on the subject of ISAPI and IIS, although his responses do seem to be full of contempt for the person asking the question. The idea I get from the blog is that only those with enough experience with this subject should be trying these methods, yet from what I have found, how can anyone get experience when so little information is available. But I digress.

If all else fails, here is the CustomAuth project that can be opened and compiled in VS 2003.

CustomAuth

Simply change the extension from .doc to .zip and unzip it. I don’t know why I didn’t think about doing this with my earlier posts to get past the upload restrictions of WordPress. I understand why the restrictions are in place, but it also seems these blogs are not very ‘code’ friendly. I mean, not even .txt files are allowed for upload, what is with that?

ACL random reset

Short post while I get my stuff together to begin posting a series of posts on one topic.

So, the strange issue of Access Control Lists (ACLs) being reset seemingly randomly on a file. Now, if this file happens to be used on a website, those ACL resets might interfere with the operation of the website, which was the case in my situation.

My scenario was the default.asp file on a website. This file needed to have a couple of ACLs set properly in order to allow access to the needed user groups. However, through the course of about 3 weeks, anywhere between a couple hours and a few days, the ACLs would be reset back to what they were before the user groups were added.

Turned out to be that the owner of the file was set to one of our developers. So, whenever this person would access this file, it would reset the ACL permissions. Why this would happen when the person accessed the file, I don’t know. But if you seem to be having random resets of ACLs on a file, try checking the owner of the file.

Ant Colony Optimization

This is the project I did in VB.NET because doing visuals in a console application wouldn’t work too well, I knew VB.NET, and VB.NET has some simple and easy to use drawing capabilities. I say simple because I’m not an artist and not much beyond circles is needed to illustrate the point of the project. For the code, I include the class and code behind I used for the project.

Ant Food Gathering Code

This program is a very simple representation involving a drawing plane and different colored circles. So the GUI of this program is a picturebox, some text boxes to change the properties, and a start button. What is being used is fairly simple and can be easily picked out of the code (I hope), so I’m not going to go into detail on any of that since this is about programming.

So in the worddoc, the first section of code is the code behind of the form in the program. I setup my global variables for the brushes and initialize the drawing surfaces in the AntSim_Load function. In the code for the Start button click event, it is simply pulling the input for the different properties from the GUI text boxes and then starting the timer. The timer goes off at a set interval which updates our little ant world.
Every time we update, the ant world gets updated through the world class and then everything is drawn to the picturebox. The food, ant’s and home base are straight forward, we just see the x and y coordinates where they are located and draw them. If the ant has food, we draw a colored circle to show this. If the food mounds are out of food, we stop drawing them. The pheromone sprays are the same, except scaled down. So if our picturebox is 100×100, the pheromone bounds are 25×25 and I just multiply by 4. This cuts down on processing while looping through and checking which pheromone cells are active. It also keeps everything in a nice grid so pheromones don’t overlap and look like a giant blob and there is no need to create or delete pheromones, simply setting them to active or invisible. This was an easier transition from the previous artificial life projects which involved cells.

Next is the world class. This class takes care of everything within the ant world so that from the form code behind we only have to call one function and draw the results. The class constructor takes input of the length and width of the picturebox being used, the number of ants we want, the number of food nodes, and how much food is in each food node, then initializes all of these elements. The NextStep does just that, takes the world of ants to the next generation. All this function does is do the NextStep functions for each ant, pheromone, and food node. Then the class has get and set properties for each variable that might need to be accessed.

The ant class is where most of the action takes place, with each ant being his own agent in the world. The ant class has 2 enums, the AntState and Directions, defining which states the ant can be in and directions it is possible to move. Then there are the various variables used for the class, the most interesting being the hisWorld variable. This is the only value passed into the constructor, allowing the ant to store and be aware of the world he is in by a World class reference value. Of course this is passed by reference so he is seeing the world he is actually in all the time, rather than a copy of the world if we used by value. All ants in this world begin their life searching for food.
In the NextStep function, we see which state the ant is in and do certain actions for each and at the end, move the ant. In the Search state, we randomly decide of the ant should change which direction he is moving, which allows the ant to move in straight lines rather than turning all the time. Next we check for food and pheromone in the current cell he is in to see if he should head home with his food or chase the pheromones. If the ant is heading home with food he has, he should lay a pheromone trail for other ants to follow. When he reaches home, he drops the food and continues searching. If he has found some pheromones, then he chases that to the food.
In order to find food, the ant has to be aware of his world. In the FindFood function, he looks around the world and sees if any of the food nodes are near enough for him to take a chunk of the food home. When he takes the food, he sets off a pheromone burst to mark the food and because he is so excited he found food. We use functions to check the distance to the food, remove some food from the food node, set his new X, Y cooridates for his target destination, and then trigger the pheromone burst. I think these are fairly self explanatory functions and variable changes.
The FindPhero function is how the ant looks for nearby pheromones. First a search range is set, which is the ants current location +-5 in each direction, divided by 4 to fall within the pheromone grid range and makes sure the values fall within a valid range. Then it checks the pheromone grid for active pheromones within that range, converts it back to the normal grid size, and checks to see if the ant is actually within range of the active pheromone. Then it stores the first and second strongest pheromones in order to move the ant towards the food, rather than randomly following the pheromone either to home or the food. Now, in my program, I made it so that the ants might not detect the pheromone. He might not pick up the smell, so I gave a random chance to not detect the pheromone if the pheromone strength was below a certain threshold. Then the ant takes actions to either chase the pheromone towards the food or keep searching. And if the ant is near food, he should just go for it.
The move function is fairly simple at this point. If the ant move state is Self, it means it isn’t moving, so we use the same searching as the nextStep function. Any other move state, we simple move the X or Y coordinates 1 space in the proper direction. Then we make sure the ant is still within the world and correct it as needed.
The TargetDir function gets which direction the current target is located. So it does coordinate comparisons from the ant and target to find the needed direction.
Finally is the Distance function which is the good ol’ math distance formula and some properties to be used from the World class as needed.

Now the Pheromone class is similar to the Ant class, with variables, get and set methods, etc. The class only has 3 unqiue functions starting with the nextStep function. This nextStep function just increments a ticker which represents the amount of time the pheromone has been active. If the pheromone has been active too long, it fades away. I added a chance for the pheromone to linger after its time so that all the pheromones set at the same time don’t all disappear at the same time.
The InitialBurst function is what happens when the ant first finds food. It gets excited and kinda goes crazy to let his buddies know where some food is located. We setup the pheromone strength max and radius of the burst, making sure the radius is within our world limits. Then we set all the pheromones within the burst radius, setting each range of pheromones separately. The pheromones closest to the food are the strongest, but don’t last as long due to their strength. The strength fades the farther away, but the duration increases.
Finally is the trail function. This function activates the pheromones along the way back to home base. The trail pheromones all last the same amount of time, so the first created is the first to disappear. The strength of the pheromone uses the ant’s trail tick value, which increases as it moves along, in order to create a trail that can be followed. So the trail tick value is subtracted from the strength value each time, so that as the trail time increases, the strength of the pheromone decreases. This makes sure that the trail will lead other ants to the food rather than back home.

Last is the Food class, which really doesn’t do much on its own other than sit there. When an ant collects some food from it, it decreases its food amount. That is it.

Artificial Life programming was one of the most interesting and enlightening classes I took while getting my degree. I just want to thank my teacher Phil for presenting the subject in an easy-to-learn fashion and teaching the class in the first place. This post finishes all I wanted to post about artificial life programming at the moment, but I may come back to it later.

Genetic Algorithm

The genetic algorithm was my favorite of the artificial life projects I did. Though the others were neat, they were more random and hit/miss for the input vs output, where genetic algorithms have a purpose. In my mind, also lend towards a more useful general programming technique. Though I feel that my code for this project is messy and way too long for a word doc, I’m still going to post it to help beginner artificial life programmers since that is what I am.

Also, I considered doing an explination of this genetic algorithm, but then I realized I would just be repeating what I had read online about the subject. So, I will just say check out the wikipedia entry and look up information on mutations, bias, genetic algorithms, and any other term you don’t understand as I go through this.

Genetic Algorithm Code

Now as you have seen, I use a DefaultActions function to call all the other functions. I do this simply so I can make one function call elsewhere and keep all the genetic algorithm code to itself.

Now the function of this genetic algorithm is to find the best solutions to the problem of “With X number of coins and a goal of X dollars, how many of each coin do you need?” So with 100 coins and a goal of $5, how many pennies, nickels, dimes, quarters, half-dollars, and dollars will you need?

First there are all the input functions, then one output function. All the input functions take their input and check to make sure it is a valid value, if it isn’t, I decided to simply insert a default value.

Now most of the input functions are fairly simple and similar. They ask for what they want with an example, “Input the number of coins (Ex: 100)”, take the input, check its value and replace it if needed. I’m going to explain the ones that I think need explination.

The bias function is fairly simple and easy to understand, but what is the bias? Well, the bias in the genetic algorithm is like selecting the best of the crop. This number tells us how much of the top percent do we want to use to select our parents. Do we take only the strongest by doing 10%, or do we widen our selection to 30%? Taking only the best will not always be the best option, since it is essentially limiting the gene pool.

The population size is the number of groups of coins we have in each generation. In the InputPopulation function, we get the population from the user, and then resize the coin arrays to that population. Then we call the InitializeCoins function which takes the arrays of CoinSets, our coin value holding struct, and sets all the values to 0. Then we call the RandomStart function. This function fills our coinArray with a random number of coins. I believe my comments in the RandomStart function explain what is going on, and if they don’t, let me know and I’ll try to do better.

In the inputCoins function, we get which coins are going to be used. The user has 6 options of coins to use or not use and inputs those values. I store the values in a string and parse through it right there in the function. If any values are present, we know we are using that type of coin, and set the boolean value to true.

Next we have a very important function which is used in the RandomStart function, which I skipped over, the CalculateScore function. This function is the most important because it lets us know if what we are doing is getting near or far from our end goal. It helps answer the question “Are the coins in our group closer or farther away from the goal of $5 with 100 coins?” Now, since we are using coins and the coins have set values (.05, .10, etc), it is really easy to get a score in this genetic algorithm example. If used elsewhere, it will be much harder to calculate a score or even have a correct end goal. Anyway, as I state in the functions comments, I do some extra work to try to make a more interesting looking score, but in the end it is just for show.

The output function does exactly that, outputs the coin group values for each generation. It checks to see if we have found a solution, if not, continues outputting and going with the next generations. One of the functions used here I will not discuss, the shellSort function, but if you do a Google search for ‘Shell Sort’, you can find information on it, but pretty much it sorts the array quickly. The next function, NextGeneration, does all the rest of the work.

The NextGeneration function takes the bias number and starts selecting parents from the previous generation to make the new generation of values. With each new generation, there is some mutation chance. If we do have a mutation, the Mutate function simply randomly changes the number of coins of each kind in the group.

I hope this explained more about the program and genetic algorithms in programming than added to the confusion.

Now, aside from the focused aspect of this example program, genetic algorithms can be used for decision in many programs. When you want some sort of random element, but still want control over it, you can use a genetic algorithm. Since the output will be determined by previous input, you can control the randomness to be within your previously set limits. An example could be a “Link of the Day” section on a website. Based on the health of the previous or other links on the site (health could be popularity, # of clicks, etc), the “Link of the Day” is chosen from that pool of links.

Since I enjoy games, I see more examples of where genetic algorithms could be used. It can be used in the normal biological sense, such as having mutations for enemies that have different colored skin, strength, skill level from their “parents” or previously encountered monsters of their kind. It could also be used in level development for random levels; taking criteria for openings, required edges, and importance. That way the levels are designed towards an optimal level, but still contain random elements to enjoy.