Blog Home  Sign In RSS 2.0 Atom 1.0 CDF  

  def Softwaremaker() :
         return "William Tay", "<Challenging Conventions />"

  knownType_Serialize, about = Softwaremaker()
 

 Monday, August 21, 2006

For the 4th year in a row, I will be speaking in Microsoft TechED 2006 Asia. This time, the event will return to its original roots back in Kuala Lumpur, Malaysia.

Unlike the previous rounds, I wont touch base on any Level 400 topics and going nitty-gritty into details of <angleBrackets/> messaging or gnarly-XSD'isms. From previous experiences, it doesnt sit too well with the asian crowd. Instead, I am going with a couple of very interesting topics. One focuses on a specific implementation of identity and service-orientation, the other is for the audience to have a better idea on what Web Services are all about first before embarking on that journey.

  • ARC323 Federated Identities and the Metasystem \ Architecture & Team Development Track

This session, I will explain the basis forces driving the concepts of the Identity Metasystem that has the world watching and waiting. How do we plug the missing gaps of the Transactional Internet? Imagine the WWW without passwords. Not only that, I will explain how this infrastructure setup can be used for business transactions other than for authentication. See demos that are not  seen anywhere yet in this region. [Level 300]

  • DEV243 Developing Web Services: Tips & Tricks \ Developer Technology Track

What exactly are Web Services and When and Why do we use them? William explains the basis of SOAP in clear concise terms and coins up some tips to help you in your Web Services Development today and tomorrow. [Level 200]

Of course, there are a whole hosts of reasons for you to attend this mega-event with tons of great speakers talking on some great topics gracing this event. KL has always been a very dynamic city and it should be a good time for all.

And even if browsing through the event site doesnt attract you enough yet, how about this?

I will be giving away 2 FREE MSDN Premium Subscription with Visual Studio Team Suite that is worth US Dollars 30,000 each to 2 lucky souls who will be attending my sessions. I may also give away other goodies like cannot-find and hard-to-get Microsoft Product Platform T-Shirts and NEW books.

So - c'mon - what are you waiting for ? Sign up today and "Change your Destiny" ...

MSTechEDAsia2006.JPG

Monday, August 21, 2006 8:56:10 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, August 11, 2006

    Many people have asked how we can retrieve and process a token sent by a subject or a Security Token Service. Just to showcase the non-intrusiveness of Microsoft Cardspace, in that we can easily incorporate a Cardspace "Sign-in with Cardspace" into your website today such as this or this, I have shown snippets of how we can do so via php here.

    As an another example of non-intrusiveness, I have also got a simple working sample that you can use to integrate into your ASP.NET 2.0 page today.

    Of course, this is a hack job and there are no try catch and the xml parsing code is hastily done. To summarize, I wont win the elegance award here  ... but you can get it to work on .NET 2.0 (or maybe even 1.1) ...

    Of course, this is a hack job and there are no try catch and the xml parsing code is hastily done. To summarize, I wont win the elegance award here  ... but you can get it to work on .NET 2.0 (or maybe even 1.1) ...

        [BEGIN]
        'This will get you your encrypted token
        Dim str As Stream
        str = Request.InputStream
        Dim sr As New StreamReader(str)
        Dim s As String = sr.ReadToEnd
        s = Server.HtmlDecode(Server.UrlDecode(s))

        'the stream will be ASCII encoded
        Dim u8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding

        Dim fs As New FileStream("C:\temp\CardspaceXMLToken.xml", FileMode.Create)
        'Remove the "xmlToken="
        Dim i As Integer = s.IndexOf("<")
        s = s.Substring(i)
        fs.Write(u8.GetBytes(s), 0, u8.GetBytes(s).Length)
        fs.Flush()
        fs.Close()
        '--------------------------------
        'The will decrypt that request token and return a Signed Security SAML Token
        Dim encryptedDoc As New XmlDocument()
        encryptedDoc.Load("C:\temp\CardspaceXMLToken.xml")

        'Check for <EncryptedData> element
        If encryptedDoc.GetElementsByTagName _
        ("EncryptedData", "
    http://www.w3.org/2001/04/xmlenc#").Count = 0 Then Return

        Dim encryptedD As XmlElement = CType(encryptedDoc.GetElementsByTagName _
        ("EncryptedData", "
    http://www.w3.org/2001/04/xmlenc#")(0), XmlElement)

        'Check for @Algorithm attribute and make sure its http://www.w3.org/2001/04/xmlenc#aes256-cbc
        If encryptedD.ChildNodes(0).Attributes("Algorithm") Is Nothing Or _
        encryptedD.ChildNodes(0).Attributes("Algorithm").Value <> _
        "
    http://www.w3.org/2001/04/xmlenc#aes256-cbc" Then Return

        Dim a As New RijndaelManaged

        'Check for <KeyInfo> element
        If encryptedD.ChildNodes(1).Name <> "KeyInfo" Then Return

        'Check for <EncryptionMethod> element
        Dim encryptedM As XmlElement = CType(encryptedDoc.GetElementsByTagName _
        ("EncryptionMethod", "
    http://www.w3.org/2001/04/xmlenc#")(1), XmlElement)

        'Check for @Algorithm attribute and make sure its http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p
        If encryptedM.Attributes("Algorithm") Is Nothing Or _
        encryptedM.Attributes("Algorithm").Value <> _
        "
    http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" Then Return

        'Check for <CipherData\CipherValue>
        If encryptedD.GetElementsByTagName("CipherValue", _
        "
    http://www.w3.org/2001/04/xmlenc#").Count = 0 Then Return

        'Retrieving the Encrypted Symmetric Key and the Security Token
        Dim e_SymmKey As String = encryptedDoc.GetElementsByTagName _
        ("CipherValue", "
    http://www.w3.org/2001/04/xmlenc#")(0).InnerText
        Dim e_SecurityToken As String = encryptedDoc.GetElementsByTagName _
        ("CipherValue", "
    http://www.w3.org/2001/04/xmlenc#")(1).InnerText

        Dim rsaCsp As New RSACryptoServiceProvider
        Dim privatecert As New X509Certificates.X509Certificate2
        privatecert.Import("Softwaremaker.NET.SSL.pfx", "Softwaremaker_NET_SSL_pfx_password",     X509Certificates.X509KeyStorageFlags.Exportable)
        rsaCsp.FromXmlString(privatecert.PrivateKey.ToXmlString(True))

        'Now we have the Symmetric Key
        Dim DecryptedStrAsByt() As Byte = _
        rsaCsp.Decrypt(System.Convert.FromBase64String(e_SymmKey), True)

        'Moving on to use the Symmetric Key to decrypt Token
        Dim rijndaelM As New RijndaelManaged
        rijndaelM.Mode = CipherMode.CBC

        Dim swmDecryptor As ICryptoTransform
        swmDecryptor = rijndaelM.CreateDecryptor(DecryptedStrAsByt, Nothing)

        'Define memory stream which will be used to hold encrypted data.
        Dim cipherTextBytes As Byte()
        cipherTextBytes = System.Convert.FromBase64String(e_SecurityToken)

        Dim memoryStream As MemoryStream
        memoryStream = New MemoryStream(cipherTextBytes)

        ' Define memory stream which will be used to hold encrypted data.
        Dim cryptoStream As CryptoStream
        cryptoStream = New CryptoStream(memoryStream, swmDecryptor, CryptoStreamMode.Read)

        ' Since at this point we don't know what the size of decrypted data
        ' will be, allocate the buffer long enough to hold ciphertext;
        ' plaintext is never longer than ciphertext.
        Dim plainTextBytes As Byte()
        ReDim plainTextBytes(cipherTextBytes.Length)

        ' Start decrypting.
        Dim decryptedByteCount As Integer
        decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)

        ' Close both streams.
        memoryStream.Close()
        cryptoStream.Close()

        ' Convert decrypted data into a string.
        ' Let us assume that the original plaintext string was UTF8-encoded.
        Dim plainTextToken As String
        plainTextToken = System.Text.Encoding.UTF8.GetString(plainTextBytes, 16, _
                                            decryptedByteCount - 16)

        return plainTextToken
        [END]
        '--------------------------------

    Of course, you would have to verify the signed token yourself BUT this decryption process is definitely a step in the right direction

    If you have benefitted from these sample snippets, maybe you can pay-it-forward by implementing and then sharing the signature-verification codes with me here? I am too lazy ... .

     

    Friday, August 11, 2006 6:18:49 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, August 09, 2006

    I believe some hardcore Microsoft Cardspace fanatics out there may have tried out Kim Cameron's IdentityBlog Cardspace demo on php. The tutorials can code samples can be found via his blog here. As of this time, I dont think he has updated it to work with the WinFX July CTP drop.

    If you had played with those php samples, you will realize that nothing much has changed for the WinFX July CTP drop, we are still using the same version of WS-Trust and WS-Security Specifications specifications. While WS-Security has been pretty much baked, as the advanced WS-* specifications reach a better level of maturity and acceptance, it wont change as frequent anymore.

    The only change to take note is the <object> element in the html page. The way claims are presented on a html page is now space-delimited and not comma-delimited as it was before.

    <object type="application/x-informationcard" name="xmlToken" id="xmlToken">
    <param name="tokenType" value="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" /><param name="issuer" value="http://schemas.microsoft.com/ws/2005/05/identity/issuer/self" /><param name="requiredClaims" value="http://schemas.microsoft.com/ws/2005/05/identity/claims/givenname http://schemas.microsoft.com/ws/2005/05/identity/claims/surname http://schemas.microsoft.com/ws/2005/05/identity/claims/emailaddress http://schemas.microsoft.com/ws/2005/05/identity/claims/privatepersonalidentifier" /></object>

    I have been showing the php demos in my presentations around the Asia-Pacific circuits for some time now. One of the questions I frequently get asked is how do we get the RSA private key of the https site (Relying party) we are using to authenticate our users. While Kim has shown some briefs snippets of his php code here (It is fairly obvious why the entire Private Key cannot be disclosed here),

    // Cardspace_demoprocessing.php
    // Put your own PEM private key here and
    // use the right password (for the demo
    // we don't use MySql to store this stufffunction get_settings($key)
    {
        if ($key == "infocard_key") {

    $retVal = "-----BEGIN RSA PRIVATE KEY-----
    Proc-Type: 4,ENCRYPTED
    DEK-Info: DES-EDE3-CBC,9266952B733BFBE0


    Z4WmpirV4dXvYjNmfSN99Iu4iYzUWa4/CPZG0NParYSVHMOhb4lsS6iISjgniGG9
    zhA862KDwsYUjgoyAIXfJAd5Z3hXiyJYdkygF/DUgeQFcwQjsWmkguq27EDHW6nS
    .
    .
    .
    3GkQxPLzTMFZYm7haU3WH+QYnNxz2bG0esUmB/YECXDCqFTbrUm/DUPd4YiI2HiL
    +j40vRpPzY6ngd1QNOfd5jkin7sjW1YlsEsRPV8OzEJvNmBZF274Cw==

    -----END RSA PRIVATE KEY-----";

        }
        else if ($key == "infocard_opener"){
            $retVal = "xY8O<|aBB";
        }
        else {
            $retVal = NULL;
        }
        return($retVal);
    }

    he did not show how he got that RSA Key.

    There are, of course, a few ways to get that key. But since we are on the subject of Open-source and php being the flavour of the day, I thought why not show the readers how to get it using another popular utility out there called "OpenSSL". I am using version 0.9.8b the OpenSSL binaries/executables.

    Once that is all downloaded, installed and setup - I used this command to retreive the RSA Private Key into a PEM file:

    Openssl pkcs12 -in Softwaremaker.NET.Pte.Ltd_300607_SSLCert.pfx -out cert.pem -nodes

    You will, of course, replace the "Softwaremaker.NET.Pte.Ltd_300607_SSLCert.pfx" with your own site's SSL digital certificate. The -nodes flag just tells the output not to have a passphase lock on the resulting PEM file. Of course, you can if you want to if you are afraid of others being able to view your site's Private Key from the php code file. The output cert.pem will contain the output:

    Bag Attributes
        1.3.6.1.4.1.311.17.2: <No Values>
        localKeyID: 01 00 00 00
        Microsoft CSP Name: Microsoft RSA SChannel Cryptographic Provider
        friendlyName: 1a9c651d1153bf0e58ac3ff34c9fce1f_615cbd1c-54d4-4ea0-b0d4-5c14115c3abb
    Key Attributes
        X509v3 Key Usage: 10
    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQDElLoxJcOzWT0jHT6uvdDHpDBnZLa4AE/gznjcKuSIT880MAmL
    ADVIoDP/0MPDucexjWCtJ33msRCmi2TOQ86dPhyc/kfrmpTnjG+Kwi7tR5x07rAM
    ...
    XLj+knD7VxrZvE/CBJP5PgjuvqfcbiSGf4R8dVB/nVm6tw==
    -----END RSA PRIVATE KEY-----

    Bag Attributes
        localKeyID: 01 00 00 00
        friendlyName: Default Web Site
    subject=/C=SG/ST=Singapore/L=Singapore/O=Softwaremaker.NET Pte Ltd/OU=Software Development and Architecture Research Unit/CN=swmvm2k3
    issuer=/CN=Softwaremaker.NET Pte Ltd
    -----BEGIN CERTIFICATE-----
    MIIE1DCCA7ygAwIBAgIKYVFrDgABAAAACDANBgkqhkiG9w0BAQUFADAkMSIwIAYD
    VQQDExlTb2Z0d2FyZW1ha2VyLk5FVCBQdGUgTHRkMB4XDTA2MDYzMDAyMjkyNFoX
    ...
    Gl+c093/wY1RT9FhAyK0vpP/H9rFzyrCZbuyL69tWkTI1DGTuZHW5g==
    -----END CERTIFICATE-----

    Once you got the above output, you just have to replace the "-----BEGIN RSA PRIVATE KEY-----..." until the "-----END RSA PRIVATE KEY-----" with your own in the php code file (Cardspace_demoprocessing.php).

    Hope this helps someone out there.

    Wednesday, August 09, 2006 6:17:25 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Monday, August 07, 2006

    The trouble with being part of the early adopters curve is that most of the time, your time is spend very unproductively trying to figure out, if samples dont work well, the reason why.

    Is it a bad installation? bad configuration? corrupted downloads? or just simply the fact that the product team, while in a rush to get things out, forgot to update or remove the "deprecated" samples ?

    While working very deeply with Microsoft Cardspace for a few months now and I mean doing "real" work for "real" clients, I would be one of the first to keep up to date on the new and upcoming Cardspace technicals.

    While downloading and installing the July CTP SDK Cardspace samples, I found out that both the Cardspace SDK samples could not work at all - out of the box. I installed the CTP and the SDK twice to make sure that I didnt screw up the first time around (that means an hour of unproductive time wasted).

    I was rather shocked when I found out that the Cardspace SDK samples have been deprecated BUT have not been removed by the team in time and my frustrations grew when the new working samples have not been uploaded in time as promised.

    Who can I blame ? - No one forced me to be part of the Early Adopter's curve and no one asked me to download the July CTP SDK and its samples. Afterall, it is supposed to be an eagerly-anticipated drop. That said, the previous samples, in some way or another, have not been working too well at all. Some works perfectly on the local machine but have some troubles going out to the wild, while others like the June CTP, had its own host of problems.

    So, what better way to do this than to roll-up-your sleeves and do-it-yourself ? While doing some reflecting, I found out some of the Cardspace July CTP SDK samples had not had its config and script files updated.

    • The setup scripts had some errors. > set InfoCardServiceName="idsvc". Therefore, it is "net start idsvc". I answered my own post here.
    • For the Simple Infocard sample under Basic\Bindings\WS\Infocard\Simple. Service config should have their behavior element changed as such. The issuedTokenAuthentication element is a key change/update.

        <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceCredentials">
              <serviceCredentials>
                <serviceCertificate findValue="Whatever_you_are_using" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
         <issuedTokenAuthentication allowUntrustedRsaIssuers="true"/>
              </serviceCredentials>
              <serviceDebug includeExceptionDetailInFaults="False" />
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
          </serviceBehaviors>
        </behaviors>

          <service name="Microsoft.ServiceModel.Samples.CalculatorService"
        behaviorConfiguration="ServiceCredentials">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="requireInfoCard"
           contract="Microsoft.ServiceModel.Samples.ISecureCalculator" >
              <identity>
                <certificateReference findValue="Whatever_you_are_using" x509FindType="FindBySubjectName"
           storeLocation="LocalMachine"
           storeName="My" />
              </identity>
            </endpoint>
      <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
          </service>

       <bindings>
      <wsHttpBinding>
       <binding name="requireInfoCard">
              <security mode="Message">
                <message clientCredentialType="IssuedToken" establishSecurityContext="true" negotiateServiceCredential="true" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>

    • For the app config. Take note:

      <system.serviceModel>
        <client>
          <endpoint address="http://swmvm2k3/ServiceModelSamples/service.svc/"
                    bindingConfiguration="requireInfoCard"
                    binding="wsHttpBinding"
                    contract="ISecureCalculator"
                    behaviorConfiguration="ClientCredentials">
        <identity>
         <certificateReference
            findValue="Whatever_you_are_using" x509FindType="FindBySubjectName"
            storeLocation="CurrentUser" storeName="TrustedPeople" />
        </identity>
       </endpoint>
        </client>

        <bindings>
          <wsHttpBinding>
            <binding name="requireInfoCard">
              <security mode="Message">
                <message clientCredentialType="IssuedToken" establishSecurityContext="true"/>
              </security>
            </binding>
       </wsHttpBinding>
        </bindings>

        <behaviors>
          <endpointBehaviors>
            <behavior name="ClientCredentials" includeExceptionDetailInFaults="true">
              <clientCredentials>
                <serviceCertificate>
                  <defaultCertificate findValue="Fabrikam" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="TrustedPeople" />
                  <authentication revocationMode="NoCheck" certificateValidationMode="PeerOrChainTrust" trustedStoreLocation="CurrentUser" />
                </serviceCertificate>
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
      </system.serviceModel>

    • For the \UsingWSFederation sample. Here are the changes to the service config. Take note of the issuedTokenAuthentication element:

        <services>
          <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="ServiceCredentials">
            <endpoint address="" binding="wsFederationHttpBinding" bindingConfiguration="requireInfoCard"
     contract="Microsoft.ServiceModel.Samples.ISecureCalculator" >
            </endpoint>
     <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
       </service>
        </services>

        <bindings>
          <wsFederationHttpBinding>
            <binding name="requireInfoCard">
              <security mode="Message">
                <message issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" issuedKeyType="AsymmetricKey">
                  <claimTypeRequirements>
          <clear />
                    <add claimType  ="http://schemas.microsoft.com/ws/2005/05/identity/claims/emailaddress"/>
      <add claimType  ="http://schemas.microsoft.com/ws/2005/05/identity/claims/privatepersonalidentifier"/>
                  </claimTypeRequirements>
                  <issuer address="http://schemas.microsoft.com/ws/2005/05/identity/issuer/self"/>
                </message>
              </security>
            </binding>
          </wsFederationHttpBinding>
        </bindings>

        <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceCredentials">
              <serviceCredentials>
                <serviceCertificate findValue="Fabrikam" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
        <issuedTokenAuthentication allowUntrustedRsaIssuers="true"/>
              </serviceCredentials>
       <serviceDebug includeExceptionDetailInFaults="False" />
       <serviceMetadata httpGetEnabled="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>

    • Client config as follows:

      <system.serviceModel>
        <client>
          <endpoint address="http://swmvm2k3/servicemodelsamples/service.svc"
           bindingConfiguration="WSFederationHttpBinding_ISecureCalculator" binding="wsFederationHttpBinding"
                    contract="ISecureCalculator" behaviorConfiguration="ClientCredentials">
        <identity>
         <certificate encodedValue="Do a svcutil and you will see the light ..." />
        </identity>   
          </endpoint>
        </client>

        <bindings>
          <wsFederationHttpBinding>
          <binding name="WSFederationHttpBinding_ISecureCalculator" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
     maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
     messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
     maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <reliableSession ordered="true" inactivityTimeout="00:10:00"
     enabled="false" />
     <security mode="Message">
     <message algorithmSuite="Default" issuedKeyType="AsymmetricKey" isuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"
           negotiateServiceCredential="true">
           <claimTypeRequirements>
            <add claimType="http://schemas.microsoft.com/ws/2005/05/identity/claims/emailaddress"
             isOptional="false" />
            <add claimType="http://schemas.microsoft.com/ws/2005/05/identity/claims/privatepersonalidentifier"
             isOptional="false" />
           </claimTypeRequirements>
           <issuer address="http://schemas.microsoft.com/ws/2005/05/identity/issuer/self" />
          </message>
         </security>
        </binding>
          </wsFederationHttpBinding>
        </bindings>

        <behaviors>
          <endpointBehaviors>
            <behavior name="ClientCredentials" includeExceptionDetailInFaults="true">
              <clientCredentials>
                <serviceCertificate>
                  <defaultCertificate findValue="Whatever_you_are_using" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="TrustedPeople" />
                  <authentication revocationMode="NoCheck" certificateValidationMode="PeerOrChainTrust" />
                </serviceCertificate>
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors></system.serviceModel>

    With that all done, you should be able to get both Cardspace samples in the July CTP SDK running, which will give you some relief that, at least, the installation is fine.

    Hope this helps someone out there. Now, moving on to fix the sts.labs.live.com and the relay.labs.live.com issues ... <sigh />

    Monday, August 07, 2006 6:16:28 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, August 02, 2006

    While running the setup scripts for the Message Security (Certificate) samples for the July CTP of WCF, I came across an error that barks an "not finding file/folder" exception:

    Upon further investigation into the setup batch scripts reveal this:

    for /F "delims=" %%i in ('"%MSSDK%\bin\FindPrivateKey.exe" My LocalMachine -n ...

    where I discovered the variable %MSSDK% was not defined in file.

    So add this line to the variable settings on the top of the batch script:

    set MSSDK=C:\Program Files\Microsoft SDKs\Windows\v6.0

    This should help solve the puzzule of the missing directory name ...

    Wednesday, August 02, 2006 6:15:22 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • Via John Lam from his post and I quote:

    Jaroslaw Rzeszotko wrote a number of ‘great programmers’ to see if they could answer a number of questions about what it takes to become a great programmer. He then blogged the answers.

    Linus, said this in his answer to the question: What do you think will be the next big thing in computer programming? X-oriented programming, y language, quantum computers, what?

    For example, I personally believe that “Visual Basic” did more for programming than “Object-Oriented Languages” did. Yet people laugh at VB and say it’s a bad language, and they’ve been talking about OO languages for decades.

    And no, Visual Basic wasn’t a great language, but I think the easy DB interfaces in VB were fundmantally more important than object orientation is, for example.

    Read the rest of his answer to get the context.

    Perhaps this will give a little more ammunition to the VB team to return VB to its roots :)

    Many people I know pooh-pooh VB and they always do it comparatively...

    • "Oh you know - WTF is a VB.NET Array ?"
    • "It is such a childish language..."
    • ...

    ... right ... as compared to ?

    While I am definitely not the first to heap praise, I wont be so quick to critique it as well. I fully agree with Linus' comments. One must not forget its place in the computing world. It has done lots for computer programming and has gotten it to the mainstream. I use the same analogy for Windows 95/98. Many people pooh-pooh it, always on hindsight. Too many of us forget what it has done for the computer world in the late 90s and early 2000s. I doubt the propagation, adoption and the use of the Personal Computer or the Internet would be the way it is today without those platforms.

    Crappy as it seems with comparison to today's tools and resources, I think the world would not be able to afford to laugh at it if it wasnt there in the first place.

    Wednesday, August 02, 2006 6:14:13 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions