wlalias 1.0 released - Create email aliases for Domains for Windows Live

September 2, 2012 at 5:08 AMJoshua Harley
Update: wlalias 1.5 has been released!

Well, in less than 72 hours after having David convince me to write the tool, I've already published version 1.0 of wlalias. Actually, it was closer to 48 hours, but who's counting? Really though, it isn't all that impressive. I had most of the core code already written all I had to do was add command line parameters, fluff, error checking, fluff, and licensing. In case you're wondering, I personally call it wail-lias even though that's not how it's written. If you're not interested in the rest of this text and want to download it, the compiled binary is available in the project's download section.

Speaking of licensing, my previous post about that was a bit off. I decided to keep using the Microsoft Public License (Ms-PL) as my license and keeping within my other projects. As usual, the license comes with no warranty or guarantees and pretty much lets you do what you want with it, including selling it. I'll admit, I'd be very sad if someone did that, but it's not like I could stop them anyway.

All right, getting down to it, the tool is very basic and can handle herself in the basic situations in which she was designed to run. The output and printed help are both very basic and things in which I plan on improving in the future. I promise (not legally binding though!) that there are no bugs or viruses and that no communication is sent back to me or any of that stuff (take a look for yourself if you want). The three basic situations that the tool is designed for are:

  1. Listing known aliases for a member.
  2. Adding a new alias for a member (up to 15, Microsoft's rule).
  3. Removing an alias for a member.

Administrative Credentials

This isn't explained very well in the program itself, but you'll need to provide some admin credentials to use the remote service. By administrative credentials I mean that you'll need to use an account that not only manages the domain the user's account logs in with but it will also need to manage the domain of the alias. If the alias you're adding or removing exists in the same domain as the user's login domain, you'll generally be fine. If you're adding or removing a domain that is not related to the login domain, you'll need to make sure your admin account can manage both (i.e. both domains are listed when you log in to domains.live.com).

Listing known alaises

Ok, this one is pretty straight forward, you'll run wlalias list email@address to show the currently assigned aliases for the user. The documentation states that the parameter is the "fully qualified member's name" which I've found to be their login email address. If the user is found and is a part of your managed domains the aliases will be printed.

C:\wlalias\bin>wlalias list test_user@gibixonline.com

Please provide administrative credentials for the domain to manage.
Username: come-on.really?@gibixonline.com
Password:

Known aliases for test_user@gibixonline.com
    test_user3@gibixonline.com
    test_user5@gibixonline.com

Adding a new alias

Creating an alias is just as straightforward as the rest of the application. In this case you'll run wlalias add login@email newalias@email and provide the admin credentials as usual. Just as a note, both the login email and the new alias must be "fully qualified" as described above. Sadly the application has to do a little guess work here since Microsoft is lying. When calling the CreateAlias method the documentation says:

Return Value

An XML block that contains a list of alternative names. The following is an example of the XML block. [...]

Well, as much as I'd love to believe that, I've never, ever received an XML block of alternative names. All I get back s a hash of some sort that doesn't correlate with anything that I know of. I've followed all of their directions as best I could and can't seem to find where the problem might be. I suppose I can use Fiddler and see if it's actually returning the wrong data or if it's the implementation, but that's for another day. Instead, the application will then call to list the aliases a second after creation and see if the alias is in the list and let you know accordingly.

C:\wlalias\bin>wlalias add test_user@gibixonline.com test_user6@gibixonline.com

Adding alias test_user6@gibixonline.com to account test_user@gibixonline.com.
If this is incorrect, press ^C or press escape in the password entry.

Please provide administrative credentials for the domain to manage.
Username: teehee.heehee@gibixonline.com
Password:

Creating alias...done.

The server returned: 0003CEEB822590A9

According to the docs the server should've returned the alias
as the result. Since it didn't, I'm checking the alias list of
the user name to see if it's listed.

The alias was found.

Removing an alias

After the previous two sections, this one will be the shortest. It's very close to the previous command except that you give it the address to remove, wlalias remove login@address alias@address. It takes two parameters: the fully qualified login name and the alias to remove. There is no return value from this call so all I have to go on is the fact that the server didn't return an error when being called.

C:\wlalias\bin>wlalias remove test_user@gibixonline.com test_user5@gibixonline.c
om

Removing alias test_user5@gibixonline.com from account test_user@gibixonline.com
.
If this is incorrect, press ^C or press escape in the password entry.
Please provide administrative credentials for the domain to manage.
Username: maybe?.nahnope@gibixonline.com
Password:
C:\wlalias\bin>

That's it, there's no output. Well, it'll mention something if it failed via HTTP. I suppose it could've checked like it did during creation but I didn't add it this time.

Future

While the tool is functionally complete, I do plan on making a few modifications in the future. As I was testing, I got tired of typing in the password and realized that this tool cannot be easily automated at this time. I was thinking of allowing you to store the username and password in envrionment variables and using those if they exist. Honestly, I just didn't want to deal with handling a password coming in via the command line. Also, with my current method, your password is secured and only exists in a readable format for less than a second (during the Authentcation() call). If I allow automation, that means your password will exist as a full string in memory that I won't be able to clear when I'm done. My other thought is to clean up the output and make it a bit easier to read. I was also thinking of expanding this to allow some other management of Windows Live, but we'll see.

If you made it this far, I congratulate you. You must have missed the download link I put in the first paragraph. The official download source of the application will always be on the project's repository, so be sure to download it from there.

If you have any issues, please feel free to create a new issue on wlalias' issue tracker. If I remember right, you won't need to sign up to create one. If you want, you can also contact me through my blog and I'll try to respond.

I can only hope that you find this tool useful. Once again, download wlalias 1.0 and create aliases with (relative) ease!

Creating email aliases for Domains for Windows Live

August 31, 2012 at 12:53 AMJoshua Harley
Update: wlalias 1.5 has been released!

So I recently switched from using Google Apps for your domain to the Domains for Windows Live (starting to think I have that named wrong). As part of the move I needed to be able to create aliases for my account ro receive all of my email proper. Ater a ton of searching I stumbled on a post that mentioned that while you can't create aliases through the web interface you can create aliases if you use their web application programming interface. Continuing my search I eventually found the API documentation and quickly whipped up a program that could communicate with the API to accomplish my goal and create aliases.

Fast forward about three weeks later and my best friend is needing to create aliases too, and quite a bit of them too from what I hear. Now, I originally wrote my tool for my use only (and one time use at that too) but I tried to modify it so my friend could use it without needing Visual Studio or any other programming tools. While it did launch, it didn't seem to work (which makes no sense) but after a bit of talking, and hearing his frustration on how hard this is, he convinced me to create a full blown utility program to help everyone manage aliases with Windows Live.

So, without further ado, I present to you the first alpha version of wlalias. Wlalias is a .Net Framework 4 application written in C#. It is completely open source and public domain, and is tentatively licensed under the MS-PL license. Basically, you're free to download it and make changes, but you cannot use it in any commercial project that makes money. This tool is something I am doing in my own time and I do not provide any warranty or guarantee that my tool will work. Hell, for all I know it could manage to blow up your computer - but, it wouldn't be my fault.

Currently only the listing of aliases has been done (it is the only non-committal operation out there I'm working with) and it can be downloaded right now for testing. For your viewing pleasure, I've included a censored screenshot of it listing my current aliases. Yes, for whatever reason, Windows Live lists my phone number as an alias.

Enjoy!

Elevating COM objects from .Net

September 10, 2011 at 9:43 PMJoshua Harley

While I was working on one of my personal projects I needed to do some administrative tasks from a program launched as a normal user. Since I try to follow best practice to the best of my ability I knew I had to write an external module that could elevate to handle the administrative tasks required.

After doing quite a bit of research I came across two possible methods

  1. Create a new external program with <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> in the embedded manifest and pass all of the information needed through the command line.
  2. Create a COM object and elevate the object when using it. Information would be passed through COM object calls in real time and allows the caller to handle problems.

Obviously because I like a challenge and I'm a sadist, I decided on option number two, creating and elevating a COM object. Following the directions generously provided by Christoph Wille I was able to successfully create and register a .Net COM object that was able to be elevated. Unfortunately after elevating the object I was unable to invoke any methods and kept getting an odd exception (I think it was 0x80070005, Access Denied, I didn't keep notes for it – so it may be I'm mixing them up).

Honestly, I didn't get the .Net method 100% working, no matter how I ran the commands the methods with the [ComRegisterFunction] and [ComUnregisterFunction] never executed, so I had to finish registration by hand (without those extra registry entries, the COM object won't elevate). As part of my troubleshooting and because of the actions I needed to take when elevated I switched from a .Net component to an ATL component. This simplified development since I could incorporate the registry entries directly into the .rgu file.

Thinking I've solved all of the problems I wrote the ATL COM component, coded it to the best of my ability, set up the .Net calling code and tried it out. Guess what... 0x80070005 Access Denied. At this point I was going insane, everything I tried and everything I did was being denied when it was elevated. If I launched the object under the normal user I was able to interact with it. Elevate it? BOOM access denied. *sigh*

Continuing to research and try to find the problem, I eventually read the small nugget of information about Over-The-Shoulder elevation. Having been on this page many, many times trying to find the information I need, I felt quite stupid when I realized the information I needed was right there the whole time.

For such servers, COM computes a security descriptor that allows only SELF, SYSTEM, and Builtin\Administrators to makes COM calls into the server. This arrangement will not work in OTS scenarios. Instead, the server must call CoInitializeSecurity, either explicitly or implicitly, and specify an ACL that includes the INTERACTIVE group SID and SYSTEM.

Totally makes sense right? Well, to break it down simpler, the default security on the COM object is such that only SYSTEM and Administrators have access to the COM object when elevated, and even though you just gave it permission, your limited user process can't access it. Turns out to properly allow a limited process access to the elevated COM object you need to grant Local Activation to the INTERACTIVE SID.

After using the Component Services snap-in (dcomcnfg) and manually granting the right permissions and confirming that it worked I looked for a way to make the change programmatically, and what do you know, there's an example right there on that same MSDN article!

Below is the code I use to set up the proper security for the COM object (grants local activation to INTERACTIVE and SYSTEM, grants local and remote activation to the Built-in Administrators and SELF SIDS) and is executed through the DllRegisterServer function that ATL calls when registration is to occur. The registry entries required for elevation are handled by ATL when it processes the .rgu file.

STDAPI DllRegisterServer(void) {
  // (0x3 = Local Access, 0x7 = Local + Remote Access)
  // See http://msdn.microsoft.com/en-us/library/ms693364(VS.85).aspx
  static const wchar_t comSDDL[] =
      L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)(A;;0x7;;;BA)(A;;0x7;;;PS)";
  bool perUser = false;
  ULONG securityDescriptorSize = 0;
  SECURITY_DESCRIPTOR* securityDescriptor = NULL;

  // Determine if the registration is per user.
  ATL::AtlGetPerUserRegistration(&perUser);

  // registers object, typelib and all interfaces in typelib
  HRESULT hr = _AtlModule.DllRegisterServer();

  // Only set up the elevation moniker if it is a system-wide install.
  // (Elevation doesn't work on per-user COM)
  if (SUCCEEDED(hr) && !perUser) {
    hr = E_FAIL;
    if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(comSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR*)&securityDescriptor, &securityDescriptorSize))
      return E_FAIL;

    ATL::CRegKey rootAppId;
    ATL::CRegKey appId;
    if (ERROR_SUCCESS == rootAppId.Open(HKEY_CLASSES_ROOT, L"AppID", KEY_READ | KEY_WOW64_32KEY) &&
        ERROR_SUCCESS == appId.Open(rootAppId, _AtlModule.GetAppIdT(), KEY_WRITE | KEY_WOW64_32KEY) &&
        ERROR_SUCCESS == appId.SetBinaryValue(L"AccessPermission", securityDescriptor, securityDescriptorSize)) {

        hr = S_OK;
    }
    LocalFree(securityDescriptor);
  }
  return hr;
}

Posted in: Programming

Tags: , ,

Http:BL anti-spam plugin for blogengine.net

July 27, 2011 at 12:16 AMJoshua Harley

With the recent update to blogengine.net 2.5 and a somewhat renewed interest in blogging I decided to port my Http:BL anti-spam plugin from my old custom blog engine to blogengine.net.

The Http:BL (DNS blacklist) is run by the people at Project Honeypot. Rather than using normal HTTP requests like Akismet, Stopforumspam, and others it instead uses a DNS query to determine whether a given IP address is considered spam or not. (If you're interested in how the query works, you can check out the API, it's pretty well documented.) With my previous engine, about 80% of the blocked spam was blocked by Http:BL so I am hoping that this plugin will work as well as it used to. Once I've confirmed it works and there aren't any bugs I plan on packaging it up and putting it on the new blogengine.net gallery.

If you would like to try it out now, just sign up for an API key, download the extension, and place it in the App_Code\Extensions directory of your site, enable and configure it and you should be good to go.

Posted in: Programming

Tags: ,