Router Control v1.1 released

by fkollmann 7/26/2009 12:33:14 AM

After a long time the new Router Control v1.1 is available by now. It contains a lot of more features like monitoring of port forwardings, router hijacking detection and a new diagnostic tool.

Thanks to everyone who gave feedback directly or by uploading the router schema. I want to encourage everyone to enable the new automatic error reporting which anonymously reports bugs to the Schema DB. Please report any issues you encounter (e.g. bugs or missing texts or images).

DOWNLOAD, Screenshots

UPDATE: Hotfix available: v1.1b! Thanks to KTMFactoryRider and the new automatic error reporting I was able to fix a lot of severe bugs during the last days and came up with some critical improvements.

VMware Server/ESXi APIs

by fkollmann 7/24/2009 5:20:08 PM

In one of our projects we use VMware Server 2 and ESXi for automatic deployment of our nightly builds. There are some approaches which can be used:

Photo

VIX API

The easiest way is to use the VIX API which has to be installed (!!) in conjunction with VMware Tasks.

The big plus of this method is that it works even for the VMware Workstation and VMware Server v1.

VI API/vSphere Web Services

You might soon find out that the VIX API might not be sufficient for you. The next step is to use the VI web services:

https://vmserver/sdk/vimService?wsdl

Attention: You cannot simply add this as service reference to a C# project. VMware added some functions to generate a valid client: DOWNLOAD.

There is a SDK available for this contains the documentation (and some samples) but the really cool thing here is that the service can be evaluated live using any browser:

https://vmserver/mob

BTW: Not all functions are implemented on the VMware Server. Invoking the RetrieveServiceContent function will show you all available services (and their instances).

Simple Storage Access

If you need to access files from one of the datastores, there is no need for big API. The following URL format provides access to all files:

https://vmserver/folder/<filepath on datastore>?dsName=<datastore name>&dcPath=<datacenter path>

Since this feels a little bit odd, here is an example: To access the file [standard] ff_int\ff_dev.vmx on VMware Server use the following URL:

https://vmserver/folder/ff_int/ff_dev.vmx?dsName=standard

BTW: As you can see, the dcPath has not to be specified for VMware Server, only for ESXi.

UPDATE: If you specify a directory and not a file, you’ll get a list of all files in that folder.

UPNP broken: AVM Fritz!Box 7270 - Firmware 54.04.76

by fkollmann 7/18/2009 11:59:27 AM

AVM did it: With the latest version of their firmware they broke the UPNP support. One of the device schemas is invalid and so the Windows UPNP stack cannot access it anymore :( .

Creating certificates using BouncyCastle

by fkollmann 7/16/2009 10:55:57 AM

For one of our projects we required some code to automatically…

  • generate a self-signed certificate,
  • ensure that it’s trusted, and
  • install it into the IIS webapp https:443.

To do this the following steps are performed – the following code has been simplified but shows the way:

0) Notes

  • BouncyCastle has been used to generate the key.
  • RandomGenerators is a helper class of us to generate some random data. It’s no big deal to implement them yourselves.
  • ServerManager is a type of "C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll"

1) Find existing certificate

var keyStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);

keyStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);

var certs = keyStore.Certificates.Find(
    X509FindType.FindBySubjectDistinguishedName,
    "CN=" + Environment.MachineName,
    true
    );

// find a valid key
X509Certificate2 cert = null;

foreach (var c in certs)
{
    // a private key is required
    if (!c.HasPrivateKey)
    {
        continue;
    }

    return cert;
}

2) Generate new certificate using BouncyCastle (if non was found)

var kpgen = new RsaKeyPairGenerator();

kpgen.Init(new KeyGenerationParameters(
    new SecureRandom(new CryptoApiRandomGenerator()),
    1024
    ));

var kp = kpgen.GenerateKeyPair();

var gen = new X509V3CertificateGenerator();

var certName = new X509Name("CN=" + Environment.MachineName);
var serialNo = BigInteger.ProbablePrime(120, RandomGenerators.CreateRandom());

gen.SetSerialNumber(serialNo);
gen.SetSubjectDN(certName);
gen.SetIssuerDN(certName);
gen.SetNotAfter(DateTime.Now.AddYears(1));
gen.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
gen.SetSignatureAlgorithm("MD5WithRSA");
gen.SetPublicKey(kp.Public);

gen.AddExtension(
    X509Extensions.AuthorityKeyIdentifier.Id,
    false,
    new AuthorityKeyIdentifier(
        SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(kp.Public),
        new GeneralNames(new GeneralName(certName)),
        serialNo
    ));

gen.AddExtension(
    X509Extensions.ExtendedKeyUsage.Id,
    false,
    new ExtendedKeyUsage(new ArrayList()
    {
        new DerObjectIdentifier("1.3.6.1.5.5.7.3.1")
    }));

var newCert = gen.Generate(kp.Private);

3) Import key to Windows keystore

private static X509Certificate2 ConvertToWindows(X509Certificate newCert, AsymmetricCipherKeyPair kp)
{
    var tempStorePwd = RandomGenerators.GetRandomString(50, 75);
    var tempStoreFile = new FileInfo(Path.GetTempFileName());

    try
    {
        // store key
        {
            var newStore = new Pkcs12Store();

            var certEntry = new X509CertificateEntry(newCert);

            newStore.SetCertificateEntry(
                Environment.MachineName,
                certEntry
                );

            newStore.SetKeyEntry(
                Environment.MachineName,
                new AsymmetricKeyEntry(kp.Private),
                new[] { certEntry }
                );

            using (var s = tempStoreFile.Create())
            {
                newStore.Save(
                    s,
                    tempStorePwd.ToCharArray(),
                    new SecureRandom(new CryptoApiRandomGenerator())
                    );
            }
        }

        // reload key
        return new X509Certificate2(tempStoreFile.FullName, tempStorePwd);
    }
    finally
    {
        tempStoreFile.Delete();
    }
}

4) Ensure the certificate is trusted

if (!cert.Verify())
{
    Console.WriteLine("Enforcing trust on certificate...");

    var keyStore = new X509Store(StoreName.AuthRoot, StoreLocation.LocalMachine);

    keyStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);

    try
    {
        keyStore.Add(cert);
    }
    finally
    {
        keyStore.Close();
    }
}

5) Bind the certificate to the IIS webapp

using (var sm = new ServerManager())
{
    foreach (var site in sm.Sites)
    {
        foreach (var bnd in site.Bindings)
        {
            if ((bnd.EndPoint.Port == 443) &&
                (bnd.Protocol == "https"))
            {
                site.Bindings.Remove(bnd);
                site.Bindings.Add(bnd.BindingInformation, cert.GetCertHash(), "MY");

                break;
            }
        }
    }

    // commit changes
    sm.CommitChanges();
}

 

UPDATE: Changes certificate serial number length form 64 bit to 120 bit to match Microsoft’s makecert default.
UPDATE2: There is a known issue: The certificate created here cannot be added to a binding after being created (via API and IIS7 Manager). The workaround is to always create a new certificate.