Saturday, March 6, 2010

Cyberoam login script in python (updated, now with notifications)

            At our institute, we are forced to login into cyberoam and then only we can surf the web. The logging process is either through WEB INTERFACE or using their client provided by them.


I didnt like any of the provided methods and also "the session logs out after every 1 hr" which is very irritating. So, few months ago, I wrote a script that simulates web login by using urllib in python.

This script basically asks u for the username and password first time you run the script and then logs in automatically after the specified interval...



#!/usr/bin/python

#Author: Abhijeet Rastogi (http://www.google.com/profiles/abhijeet.1989)

cyberroamIP = "10.100.56.55" #The IP of the Cyberoam site.
cyberroamPort = "8090" #Set to "" if not using.
never_quit = True #Once started cyberthon will never, even when the cyberoam server cannot be connected.
reconnectAfter = 3500
use_notification = True


import sys
import getpass
from time import strftime
import cookielib
import urllib2
import re
import urllib, sgmllib,time,commands,os
import thread
import threading

try:
 import pynotify
 pynotify.init("Cyberoam Login Script")
except:
 print "You dont have pynotify installed, Notifications will not be shown :-( "
 use_notification = False

username = raw_input("Enter your ID: ")
username = username
passwd = getpass.getpass()

cyberroamAddress = cyberroamIP
if cyberroamPort != "":
 cyberroamAddress = cyberroamAddress+":"+cyberroamPort

#Parsing and logging in too.
import sgmllib

download_quota_remaining = 0

def netUsage():
 url = "http://"+cyberroamAddress+"/corporate/servlet/MyAccountManager"
 data = "mode=1&login_username=&secretkey=&js_autodetect_results=SMPREF_JS_OFF&just_logged_in=1&username="+username+"&password="+passwd+"&select=My+Account&soft_25.x=0&soft_25.y=0"
 cj = cookielib.CookieJar()
 opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
 opener.addheaders = [('Referer','http://10.100.56.55:8090/myaccount.html')]
 usock = opener.open(url, data)
 the_page = usock.read()
 transfer_log = []
 for i in range(1,10):
     start = the_page.find('')
     the_page = the_page[start+53:]
     end = the_page.find('     transfer_log.append(the_page[0:end])
 return transfer_log

def periodicNotification(threadname, show_again_after):
 while True:
  if use_notification == True:
   show_quota = pynotify.Notification("Cyberoam Script", "Remaining Download Quota: %s\nRemaining Upload Quota: %s" % (netUsage()[-1], netUsage()[-4]))
   show_quota.set_timeout(1)
   show_quota.show()
   print "Hello"
   time.sleep(show_again_after)

class MyCyberroamParser(sgmllib.SGMLParser):
 "A simple parser class."

 def parse(self, s):
  "Parse the given string 's'."
  self.feed(s)
  self.close()

 def __init__(self, verbose=0):
  "Initialise an object, passing 'verbose' to the superclass."
     sgmllib.SGMLParser.__init__(self, verbose)
  self.required_entities = ['message','loginstatus','liverequesttime']
  self.frames_attr = []
  self.in_required_entity = False
  self.current_entity = ""
  self.entity_values = {}

 def do_frame(self, attributes):
  for name, value in attributes:
   if name == "src":
    self.frames_attr.append(value)

 def unknown_entityref(self,ref):
  self.current_entity = ref
  if ref in self.required_entities:
   self.in_required_entity=True

 def handle_data(self, data):
  "Try to get the value of entity &message. Used in 2nd pass of parsing."

  if self.in_required_entity:
   self.entity_values[self.current_entity] = data[1:] #To remove the preceeding =
   self.in_required_entity = False

 def get_src(self,index=-1):
  "Return the list of src targets."
  if index == -1:
   return self.frames_attr
  else:
   return self.frames_attr[index]

lastmsg = ""
msgChanged = True
sec2sleepOnError = 6
changeUser = True

try:
 while True: 
  try:
   # Logging in and fetching the Cyberroam login page.
   """
   if changeUser == True:
    line = cred_file.readline()
    cred = line.split(" ")
    cred[1] = cred[1][:-1]
    username = str(cred[0])+"@da-iict.org"
    passwd = str(cred[1])
    #passwd = getpass.getpass()"""
   print "Username in use: "+username 
   f = urllib.urlopen("http://"+cyberroamAddress+"/corporate/servlet/CyberoamHTTPClient","mode=191&isAccessDenied=null&url=null&message=&username="+username+"&password="+passwd+"&saveinfo=saveinfo&login=Login")
  except IOError, (errno, strerror):
   if not silent:
    print "Connection to Cyberoam server timed out. Error(%s): %s" % (errno, strerror)
    print "Retrying in %s seconds" % sec2sleepOnError
    time.sleep(sec2sleepOnError)
    continue
  s = f.read()
  # Try and process the page.
  # The class should have been defined first, remember.
  myparser = MyCyberroamParser()
  myparser.parse(s)
  
  # Get the the src targets. It contains the status message. And then parse it again for entity &message.
  qindex = myparser.get_src(1).index('?')
  srcstr = myparser.get_src(1)[:qindex+1]+'&'+myparser.get_src(1)[qindex+1:]
 
  myparser.parse(srcstr)
 
  message = myparser.entity_values['message']
  message = message.replace('+',' ')
  
  if message=="You have successfully logged in":
   try:
    thread.start_new_thread(periodicNotification,("Notification of Quota",900))
    changeUser = False
    download_quota_remaining = netUsage()[-1]
    transfer_log = netUsage()
    print "Total TRANSFER till now: "+str(transfer_log[2])
    print "Remaining Download QUOTA: "+str(transfer_log[-1])
    print "You have successfully logged in"
    if use_notification == True:
     successful_login = pynotify.Notification("Cyberoam", "Login attempt successful \n Remaining Download QUOTA: %s" % download_quota_remaining)
     successful_login.show()
    time.sleep(reconnectAfter)
   except KeyboardInterrupt:
    time.sleep(0.5)
    username=raw_input("Enter your ID: ")
    username = username+"@da-iict.org"
    passwd= getpass.getpass()
  
  if message == "The system could not log you on. Make sure your password is correct":
   print "Wrong password.. Enter again"
   passwd = getpass.getpass()
   changeUser = False
  
  if message == "DataTransfer limit has been exceeded":
   if use_notification == True:
    data_limit_exceeded = pynotify.Notification("Cyberoam", "DATA-TRANSFER limit for the day exceeded")
    data_limit_exceeded.show()
   print "Download Quota Exceeded"
   username=raw_input("Enter another ID: ")
   username = username+"@da-iict.org"
   passwd= getpass.getpass()
except KeyboardInterrupt:
 pass

16 comments:

  1. Nice script.. I was searching for something like this since long!!
    its nice that now i can auto-login into cyberoam... :)

    ReplyDelete
  2. If you want to learn how to make a login script for sites that require COOKIES, check my other post. http://goo.gl/iJuD

    ReplyDelete
  3. Hi ... Since am from medical field i have limited knowledge abt tech . Can u tell me how to run the script that u have written . pleae mail me at debasish.4frnz@gmail.com

    Currently a using Ubuntu 9.04 jaunty operating system .

    ReplyDelete
  4. really gud one
    i have to change something for continue login
    in my college data limit is 100 mb per account per account
    a have few accounts
    how to change this code such logout on data exceed make login with another account automatically
    i can change each accounts password the same
    then can this codw take userids from a text file and remember the line counter of id text file
    if ne can help! i id is ichigo98357@gmail.com

    ReplyDelete
  5. give me the way to remove the data transfer limit.

    ReplyDelete
  6. hi ,tnks for the script but I have a erroe when i try to run it
    ----------------------------------
    Traceback (most recent call last):
    File "Cyberoam.py", line 128, in
    if not silent:
    NameError: name 'silent' is not defined
    ---------------------------------
    can you fix it

    ReplyDelete
  7. @above
    I have updated the script. Try the new one

    ReplyDelete
  8. can anyone help me, about how to correct the error below when i run the script of cyberoam bypass, Any help? ty
    cyberroamIP = "172.16.0.11" #The IP of the Cyberoam site.
    ^
    IndentationError: unexpected indent

    ReplyDelete
  9. @above
    Thats because python defines its blocks according to indentation. By editing the file you spoiled the indentation. So, be careful while editing the file, make sure that you dont add or remove any spaces from the left of the source code...

    ReplyDelete
  10. still error, any help pls, thanks
    span

    SyntaxError: invalid syntax

    ReplyDelete
  11. hey!!

    error in line 54

    it says


    EOL while searching String

    ReplyDelete
  12. how can i run this script
    please help me

    ReplyDelete
  13. HEY I AM GETTING SYNTAX ERROR FOR THIS- " WHAT 2 DO.............

    ReplyDelete
  14. You dont have pynotify installed, Notifications will not be shown :-(
    Enter your ID: XXXXXXXXX
    Password:
    Username in use: XXXXXXXXX
    Traceback (most recent call last):
    File "Cyberoam.py", line 139, in
    qindex = myparser.get_src(1).index('?')
    File "Cyberoam.py", line 105, in get_src
    return self.frames_attr[index]
    IndexError: list index out of range
    Press any key to continue . . .




    This is the error I am getting.. Pse Help

    ReplyDelete