What do I mean by scripting an internet connection? Lets have a look at the following NetCat conversation:

Code:
C:\>nc XXX.XXX.XXX.XXX 80
HEAD / HTTP/1.1
HOST: www.awebsite.co.uk

HTTP/1.1 200 OK
Date: Sat, 27 Apr 2002 12:23:56 GMT
Content-Type: text/html
Connection: close
Server: Microsoft-IIS/4.0
Via: 1.1 webcacheB09 (NetCache NetApp/5.2.1R1D3)
What I wanted to do is write a piece of code to script this sort of conversation. And as the handle suggests I'm writing the tutorial from the standpoint of an NT Syadmin (why else would I be so paranoid about my security?!?). I make no apology here for that bias. In fact under [Insert Branding here]-X there are enough ways to do this without the nececity for any such tutorial. So this one is for those of you that still confess to owning a Windows box (after all, we can't all be 'l33t' - some of us have to work for a living ).

You can of course do this in pearl, but only in your target installation includes the perl binaries. This was why I chose WSH as the language for this application. WSH is installed on mosts windows boxes and I wanted an app that was reusable on as many windows boxes with the absolute minumum of fuss.

Why should I wish to do with such a script? Well /I/ can think of a 1001 uses for such a bit of code (which let's face it is why I bothered to write it) but I feel sure that you can think of a use or two aswell . If not then I will include some case studies that I have coded since writing the origional app to give you some ideas.

Why am I making this freely availible? Well, I wrote it on my own time and what goes around comes around. Plus the Microsoft Documentation on this subject is (unsurprisingly) piss poor. Sharing knowledge is what the Internet is about after all. If you like the code and find it useful (or even just appreciate that I'm sitting down on a satuday afternoon to write this tutorial) then as a 'noob' to this site I could really use your AntiPoints

In WSH we need to create an instance of the winsock control. The instatiation code and some basic methods/properties are as follows:
Code:
Set tcpClient=WScript.CreateObject("MSWinsck.winsock","wsPop_")
tcpClient.Protocol = sckTCPProtocol
tcpClient.RemoteHost = host 
tcpClient.RemotePort =  port
tcpClient.Connect
This creates an object called tcpClient and sets the protocol, host and port properties of that object. The last line, the connect method, connects the tcpClient object to the host and port specified.

In the instantiation code we see the section ("MSWinsck.winsock","wsPop_"). What this does is set the ("Name.OfObject","Callback_"). The callback part is the part that identifies the prefix of subroutines that will handle the events for this object. Have a look at the following two subs.
Code:
Sub wsPop_DataArrival(Byval b)

  dim strdata
  tcpClient.GetData strData,vbstring
  
  'Returned data is now in strData 
  'as a vbString (otherwise it's garbage)
  'for you to process

end sub

Sub wsPop_Connect()

  'I am now connected

End Sub
The DataArrival and Connect events are fired from the MSwinsock control and execution is passed to the subroutine entitled Callback_EventName, where 'Callback_' is the name you specified in ("Name.OfObject","Callback_") and EventName is the name of the event (figures) being fired.

The main problem here is that because the script is batch excuted you have to impose all sorts of checks and balance to ensure that the script is still running when these events are fired, and do sensible thing when they are not!

The other problem is that when you do get a script running it causes a bizzare exception on the target machine. Let me put you out of your misery. After much greif with this I managed to talk to Andrew Clinick at Microsoft, and the long and the short of it is this: In WSH the mswinscript object licence is in design mode. If you have Visual Studio installed this is fine because you have the licence to run the winsock control in design time. But if we have to rely on Visual Studio being installed then we may as well have used pearl.

To get round the licencing issue with this control you create an OCX wrapper for the Winsock object. If you don't want to follow the argument here or you don't have Visual Studio installed then don't worry. I have done this for you and the new control is included in the .zip file which you can download from below. There are however 2 changes required to the code above to make the new control work.

Code:
Set tcpClient=WScript.CreateObject("MSWinsck.winsock","wsPop_")

Changes to

Set tcpClient=WScript.CreateObject("SBWinsck.winsock","wsPop_")

Sub wsPop_Connect()

changes to

Sub wsPop_Connected()
Register the sbwinsock.ocx control using the regsvr32 command.

If you want to skip the rest of the conversation about the SBWinsock control press {CTRL}F and search down the page for the phrase {rantover}.

Still with me? Boy, you're keen! Ok - the point here is that VS allows you to create controls of your own that run in either run time /or/ design time licence. But on the target machine the MSwinsock control has to be in run time to work (because the target machine does not have a design time licence). We can do this by creating an instance on mswinsock within our own control which places the mswinsock object in a run time state. As the user control has no licence to worry about (because we wrote it) and our control uses the mswinsock control with run time licence, it all works.

In VB add a winsock control to the form (Project | Components | Microsoft winsock control 6.0) and name the control Winsk. Now add the following code to the control.

Code:
Event Connected()
Event DataArrival(bytesTotal As Long) 'MappingInfo=Winsk,Winsk,-1,DataArrival

Public Property Get Protocol() As ProtocolConstants
  Protocol = Winsk.Protocol
End Property

Public Property Let Protocol(ByVal New_Protocol As ProtocolConstants)
  Winsk.Protocol() = New_Protocol
  PropertyChanged "Protocol"
End Property

Public Property Get RemoteHost() As String
  RemoteHost = Winsk.RemoteHost
End Property

Public Property Let RemoteHost(ByVal New_RemoteHost As String)
  Winsk.RemoteHost() = New_RemoteHost
  PropertyChanged "RemoteHost"
End Property

Public Property Get RemotePort() As Long
  RemotePort = Winsk.RemotePort
End Property

Public Property Let RemotePort(ByVal New_RemotePort As Long)
  Winsk.RemotePort() = New_RemotePort
  PropertyChanged "RemotePort"
End Property

Public Sub Connect()
  Winsk.Connect
End Sub
The reason for the change of the mswinsock event name from connect to connected in the sbwinsock is because the mswinsock control uses the connect identifier /twice/ (!!!), once as a method and once as an event. This causes errors when compiling the control and so to get round this in the sbcontrol I renamed the connect event to connected.

{rantover}

So now let's put all of this together in a nice reusable package. To make it flexible I wanted my script to be able to accept input either from the command line (using standard streams) of from an external file or from a combination of both.

For the script file I used the following conventions (for use with -f [file] option). Lines with * begin interactive user input session. Interactive sessions are ended with a !. Lines beginning with # are comments. Values in [name] format will be requested from user.

An example. This script is for POP3 communication (if this makes no sence may I recomend a trip to www.w3.org or a google search for the term 'rfc'):
Code:
# Requests value of [User Name] and begins pop3 conversation
user [User Name]
# Requests value of [password] and sends it
pass [Password]
# Get a list of mail messages on this server
list
# Allow interactive user input (so user can retr mail)
*
# Once the user quits the interactivce input (with !) send the quit command
# End the pop3 conversation
quit
The vanilla version of this code can be downloaded from ftp://195.8.181.206/tcputil.zip with sample scripts for www/pop3/smtp/ftp/whois communication. The usage for the script is as follows:
Code:
Usage: tcputil <--Host|-h [Host Name]>
        [--Port|-p [Port Number or www|ftp|smtp|pop3] Default: 80
        [--Delay|-d] Page Time Out delay (in seconds) Default: 3 Seconds
        [--file|-f] Get commands from an external file.
        [--buffer|-b] Buffer server responses
        [--notbuffer|-!b] Display server responses as they arrive
        [--Verbose|-v]
        [--debug|-vv]
        [--Help|/?]>

Example:
   tcputil -h xxx.xxx.xxx.xxx -p 80 -f myscript
Ok - so now we know how to script an Internet connection I have some case studies that domonstrate the utilisation of this method for the less imaginative of you. These are two scripts that are included in the file ftp://195.8.181.206/AO_case_study.zip.

The first script is DMOZ.vbs. The DMOZ is the open directory project that provides data for half the search engines on the net including Google, yahoo, lycos, netscape etc. To protect themselves from people writing batch software to submit urls the submission requires the base64 value of the IP address of the submitter. What this script does is parse the meta content of the website you supplied with the -s option, load the page before the submission from the DMOZ and parse out this code, and then submits the whole lot to the DMOZ submission page. You also have to specify where the link is to be submitted using the -w option.

NOTE. I am certainly not condoning /anyone/ to write a batch url insert program. Each of these steps could have been performed with a web browser, and I am simply demonstrating that they could have also been done with a script. This script only submits /one/ site at a time, and in practice requires that you go to the site manually to find where you want to post your site anyway.

The second script is called bashinc.vbs. I wrote this script to check /my own/ iis installation for files in common locations that were not parsed by any isapi filter, and could therefore be downloaded as plain text. Include files are very suceptible to this under a standard IIS instalation. I also included a -e extended checking option to also check .txt/.vbs/.js/etc extentions.

NOTE. Neither am I condoning the use of this script for any other use that for the testing of /your own/ IIS installation. Sysadmins concerned about this issue should open the MMC and under the home directory configuration add the .inc extention and set the extention to be processed by the asp.dll (you can copy the setting from the .asp extention)

Ok - so thats it. If you found any of this useful all antipoints are gratefully accepted. Till next time - look both ways and don't talk to strangers.