Example #1
0
    def _enableStaticProvisioning_GXP1450(self, vars):
        try:
            # Login into interface
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
            response = opener.open(
                'http://' + self._ip + '/cgi-bin/dologin',
                urllib.urlencode({
                    'Login': '******',
                    'P2': self._http_password,
                    'gnkey': '0b82'
                }))
            body = response.read()
            if 'dologin' in body:
                logging.error('Endpoint %s@%s GXP1450 - dologin failed login' %
                              (self._vendorname, self._ip))
                return False

            response = opener.open('http://' + self._ip + '/cgi-bin/update',
                                   urllib.urlencode(vars) + '&gnkey=0b82')
            body = response.read()
            if 'dologin' in body:
                logging.error(
                    'Endpoint %s@%s GXP1450 - dologin failed to keep session' %
                    (self._vendorname, self._ip))
                return False
            return True
        except socket.error, e:
            logging.error('Endpoint %s@%s GXP1450 failed to connect - %s' %
                          (self._vendorname, self._ip, str(e)))
            return False
Example #2
0
def register(client, fetch):
    # Agree Page
    agree_page = fetch("/ucp.php?mode=register", step="Agree Page")
    form_token = agree_page.find("input", {"name": "form_token"})
    if form_token is not None:
        form_token = form_token['value']
    else: return
    form_data = {'form_token': form_token, 'agreed': 'I agree to these terms'}
    params = urllib.urlencode(form_data)

    # Register Page
    register_page = fetch("/ucp.php?mode=register", params, step="Register Page")
    form_token = register_page.find("input", {"name": "form_token"})
    if form_token is not None:
        form_token = form_token.get('value', "")
    else: return
    creation_time = register_page.find("input", {"name": "creation_time"}).get('value', "")
    form_data = {'username': client.name,
                 'email': client.email,
                 'new_password': client.password,
                 'password_confirm': client.password,
                 'lang': 'en',
                 'tz': 'America/Creston',
                 'tz_date': 'GMT-07:00 - 24 Apr 2013, 20:29',
                 'tz_copy': 'UTC',
                 'form_token': form_token,
                 'creation_time': creation_time,
                 'agreed': 'true',
                 'change_lang': '0',
                 'submit': 'Submit'}
    params = urllib.urlencode(form_data)
    # Save Registration
    fetch("/ucp.php?mode=register", params, step="Save User")
    def _enableStaticProvisioning_GXP140x(self, vars):
        try:
            # Login into interface and get SID. Check proper Content-Type
            cookiejar = cookielib.CookieJar(
                cookielib.DefaultCookiePolicy(rfc2965=True))
            opener = urllib2.build_opener(
                urllib2.HTTPCookieProcessor(cookiejar))
            # response = urllib2.urlopen('http://' + self._ip + '/cgi-bin/dologin',
            response = opener.open(
                'http://' + self._ip + '/cgi-bin/dologin',
                urllib.urlencode({'password': self._http_password}))
            body = response.read()
            content_type = response.info()['Content-Type'].rsplit(';', 1)[0]
            if content_type <> 'application/json':
                logging.error(
                    'Endpoint %s@%s GXP140x - dologin answered not application/json but %s'
                    % (self._vendorname, self._ip,
                       response.info()['Content-Type']))
                return False

            # Check successful login and get sid
            jsonvars = cjson.decode(body)
            if not ('body' in jsonvars and 'sid' in jsonvars['body']):
                logging.error('Endpoint %s@%s GXP140x - dologin failed login' %
                              (self._vendorname, self._ip))
                return False
            sid = jsonvars['body']['sid']

            # Post vars with sid
            vars.update({'sid': sid})
            # response = urllib2.urlopen('http://' + self._ip + '/cgi-bin/api.values.post',
            response = opener.open(
                'http://' + self._ip + '/cgi-bin/api.values.post',
                urllib.urlencode(vars))

            jsonvars = self._parseBotchedJSONResponse(response)
            if jsonvars == None:
                logging.error(
                    'jsonvars vacio %s@%s GXP140x - vars rejected by interface - %s - %s - %s'
                    % (self._vendorname, self._ip, urllib.urlencode(vars),
                       jsonvars['body'], sid))
                return False

            if not ('response' in jsonvars and jsonvars['response'] == 'success' \
                    and 'body' in jsonvars and 'status' in jsonvars['body'] and jsonvars['body']['status'] == 'right' ):
                logging.error(
                    'Endpoint %s@%s GXP140x - vars rejected by interface - %s - %s - %s'
                    % (self._vendorname, self._ip, urllib.urlencode(vars),
                       jsonvars['body'], sid))
                return False

            return True
        except cjson.DecodeError, e:
            logging.error('Endpoint %s@%s GXP140x received invalid JSON - %s' %
                          (self._vendorname, self._ip, str(e)))
            return False
Example #4
0
 def _send_email(self, check):
     check_name = check['check']
     hostname = check['hostname']
     if check['status'] is True:
         status = 'UP'
     else:
         status = 'DOWN'
     subject = "[stalker] %s on %s is %s" % (check_name, hostname, status)
     data = {
         "from": "Stalker <%s>" % self.from_addr,
         "to": self.recipients,
         "subject": subject,
         "text": "%s" % check
     }
     headers = {
         'Authorization': 'Basic %s' % self.basic_auth_creds,
         'Content-Type': 'application/x-www-form-urlencoded'
     }
     try:
         post_data = urllib.urlencode(data)
         req = urllib2.Request(self.url, post_data, headers)
         response = urllib2.urlopen(req)
         result = response.read()
         response.close()
         self.logger.info('Mailgun: %s' % result)
         return True
     except Exception:
         self.logger.exception('Mailgun notification error.')
         return False
Example #5
0
 def _send_email(self, check):
     check_name = check['check']
     hostname = check['hostname']
     if check['status'] is True:
         status = 'UP'
     else:
         status = 'DOWN'
     subject = "[stalker] %s on %s is %s" % (check_name, hostname, status)
     data = {"from": "Stalker <%s>" % self.from_addr,
             "to": self.recipients,
             "subject": subject,
             "text": "%s" % check}
     headers = {
         'Authorization': 'Basic %s' % self.basic_auth_creds,
         'Content-Type': 'application/x-www-form-urlencoded'
     }
     try:
         post_data = urllib.urlencode(data)
         req = urllib2.Request(self.url, post_data, headers)
         response = urllib2.urlopen(req)
         result = response.read()
         response.close()
         self.logger.info('Mailgun: %s' % result)
         return True
     except Exception:
         self.logger.exception('Mailgun notification error.')
         return False
Example #6
0
    def _getAuthOpener_LXP150(self, http_user, http_pass):
        ''' Create an authenticated opener for the LXPx50 series.

        The LXPx50 HTTP authentication is again weird. First, a request must be
        sent to the phone with a Cookie with a SessionId set to a random number
        between 0 and 99999. Sending 0 works just as well. The first request must
        be a GET that asks the phone to calculate a hash for a specified username
        and password. The hash is embedded inside a HTML fragment in the response.
        Next the hash must be sent as a new Cookie in a POST request that also
        includes the original SessionId number and the UserName as cookies. A
        successful login returns a response with the phone status, including the
        phone model. Additionally, the response after a successful login includes
        a brand new SessionId that must be replaced in the opener cookie.
        '''
        cookiejar = cookielib.CookieJar(cookielib.DefaultCookiePolicy(rfc2965=True))
        sesscookie = cookielib.Cookie(None, 'SessionId', '0', None, False,
            self._ip, False, False,
            '/', False, False, str((int)(time.time() + 3600)),
            False, 'SessionId', None, None)
        cookiejar.set_cookie(sesscookie)
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
        response = opener.open('http://' + self._ip + '/fcgi/do?' + urllib.urlencode({
            'action': 'Encrypt',
            'UserName' : http_user,
            'Password' : http_pass}))
        body = response.read()
        m = re.search(r"id=hcSingleResult type=hidden value='(.+?)'", body)
        if m is None:
            return (None, None)
        encrypted_password = m.group(1)

        sesscookie = cookielib.Cookie(None, 'UserName', http_user, None, False,
            self._ip, False, False, '/', False, False, str((int)(time.time() + 3600)),
            False, 'UserName', None, None)
        cookiejar.set_cookie(sesscookie)
        sesscookie = cookielib.Cookie(None, 'Password', encrypted_password, None, False,
            self._ip, False, False, '/', False, False, str((int)(time.time() + 3600)),
            False, 'Password', None, None)
        cookiejar.set_cookie(sesscookie)
        response = opener.open('http://' + self._ip + '/fcgi/do?id=1',
            'SubmitData=begin%26Operation%3DCreateSession%26DestURL%3Did%6021%26SubmitData%3Dend')

        # Find new SessionId value. What, no Set-Cookie header?
        body = response.read()
        m = re.search(r"id=hcSessionIdNow type=hidden value='(.+?)'", body)
        if m != None:
            sesscookie = cookielib.Cookie(None, 'SessionId', m.group(1), None, False,
                self._ip, False, False,
                '/', False, False, str((int)(time.time() + 3600)),
                False, 'SessionId', None, None)
            cookiejar.set_cookie(sesscookie)
        else:
            logging.error('Endpoint %s@%s LXPx50 failed to authenticate - new session ID not found in response' %
                (self._vendorname, self._ip))
            return (None, None)

        # Subsequent requests must NOT have the UserName/Password cookies
        cookiejar.clear(self._ip, '/', 'UserName')
        cookiejar.clear(self._ip, '/', 'Password')
        return (opener, body)
Example #7
0
 def _build_url(self, method, **args):
     """Call the Eventful API's METHOD with ARGS."""
     # Build up the request
     args['app_key'] = self.app_key
     if hasattr(self, 'user_key'):
         args['user'] = self.user
         args['user_key'] = self.user_key
     args = urllib.urlencode(args)
     return "http://%s/json/%s?%s" % (self.server, method, args)
Example #8
0
 def _build_url(self, method, **args):
     """Call the Eventful API's METHOD with ARGS."""
     # Build up the request
     args['app_key'] = self.app_key
     if hasattr(self, 'user_key'):
         args['user'] = self.user
         args['user_key'] = self.user_key
     args = urllib.urlencode(args)
     return "http://%s/json/%s?%s" % (self.server, method, args)
Example #9
0
    def _enableStaticProvisioning_GXP140x(self, vars):
        try:
            # Login into interface and get SID. Check proper Content-Type
            response = urllib2.urlopen(
                'http://' + self._ip + '/cgi-bin/dologin',
                urllib.urlencode({'password': self._http_password}))
            body = response.read()
            if response.info()['Content-Type'] <> 'application/json':
                logging.error(
                    'Endpoint %s@%s GXP140x - dologin answered not application/json but %s'
                    % (self._vendorname, self._ip,
                       response.info()['Content-Type']))
                return False

            # Check successful login and get sid
            jsonvars = cjson.decode(body)
            if not ('body' in jsonvars and 'sid' in jsonvars['body']):
                logging.error('Endpoint %s@%s GXP140x - dologin failed login' %
                              (self._vendorname, self._ip))
                return False
            sid = jsonvars['body']['sid']

            # Post vars with sid
            vars.update({'sid': sid})
            response = urllib2.urlopen(
                'http://' + self._ip + '/cgi-bin/api.values.post',
                urllib.urlencode(vars))

            jsonvars = self._parseBotchedJSONResponse(response)
            if jsonvars == None:
                return False

            if not ('response' in jsonvars and jsonvars['response'] == 'success' \
                    and 'body' in jsonvars and 'status' in jsonvars['body'] and jsonvars['body']['status'] == 'right' ):
                logging.error(
                    'Endpoint %s@%s GXP140x - vars rejected by interface - %s'
                    % (self._vendorname, self._ip, body))
                return False

            return True
        except cjson.DecodeError, e:
            logging.error('Endpoint %s@%s GXP140x received invalid JSON - %s' %
                          (self._vendorname, self._ip, str(e)))
            return False
Example #10
0
    def _enableStaticProvisioning_BT200(self, vars):
        try:
            # Login into interface
            cookiejar = cookielib.CookieJar(
                cookielib.DefaultCookiePolicy(rfc2965=True))
            opener = urllib2.build_opener(
                urllib2.HTTPCookieProcessor(cookiejar))
            response = opener.open(
                'http://' + self._ip + '/dologin.htm',
                urllib.urlencode({
                    'Login': '******',
                    'P2': self._http_password,
                    'gnkey': '0b82'
                }))
            body = response.read()
            if 'dologin.htm' in body:
                logging.error('Endpoint %s@%s BT200 - dologin failed login' %
                              (self._vendorname, self._ip))
                return False

            # Force cookie version to 0
            for cookie in cookiejar:
                cookie.version = 0

            response = opener.open('http://' + self._ip + '/update.htm',
                                   urllib.urlencode(vars) + '&gnkey=0b82')
            body = response.read()
            if 'dologin.htm' in body:
                logging.error(
                    'Endpoint %s@%s BT200 - dologin failed to keep session' %
                    (self._vendorname, self._ip))
                return False

            return True
        except urllib2.HTTPError, e:
            logging.error(
                'Endpoint %s@%s BT200 failed to send vars to interface - %s' %
                (self._vendorname, self._ip, str(e)))
            return False
Example #11
0
 def _setNetworkConfig_V1(self):
     try:
         if self._dhcp:
             postvars = {
                 'dhcp': 'on',
                 'Settings': 'Save',
                 'ignore_dhcp_findings': '',
             }
         else:
             postvars = {
                 'dhcp':
                 'off',
                 'ip_adr':
                 self._static_ip,
                 'netmask':
                 self._static_mask,
                 'gateway':
                 self._static_gw,
                 'dns_server1':
                 self._static_dns1,
                 'dns_server2':
                 self._static_dns2,
                 'Settings':
                 'Save',
                 'ignore_dhcp_findings':
                 'dns_server1 dns_server2 gateway ip_adr netmask',
             }
         response = urllib2.urlopen(
             'http://' + self._ip + '/advanced_network.htm',
             urllib.urlencode(postvars))
         htmlbody = response.read()
         if 'CONFIRM_REBOOT' in htmlbody:
             response = urllib2.urlopen(
                 'http://' + self._ip + '/advanced_network.htm',
                 'CONFIRM_REBOOT=Reboot')
             htmlbody = response.read()
             response = urllib2.urlopen(
                 'http://' + self._ip + '/confirm.htm', 'REBOOT=Yes')
             htmlbody = response.read()
             logging.info('Endpoint %s@%s set network config - rebooting' %
                          (self._vendorname, self._ip))
             return (True, True)
         else:
             logging.info(
                 'Endpoint %s@%s set network config - not yet rebooting' %
                 (self._vendorname, self._ip))
             return (True, False)
     except urllib2.URLError, e:
         logging.error('Endpoint %s@%s failed to connect - %s' %
                       (self._vendorname, self._ip, str(e)))
         return (False, False)
Example #12
0
    def _setupAtcomAuthentication(self):
        http = httplib.HTTPConnection(self._ip)

        noncesources = ('/', '/right.htm')
        for noncesource in noncesources:
            http.request('GET', noncesource, None, {'Connection' : 'keep-alive'})
            resp = http.getresponse()
            htmlbody = resp.read()
            if not resp.status in (200, 404):
                logging.error('Endpoint %s@%s failed to fetch nonce for HTTP configuration - got response code %s' %
                    (self._vendorname, self._ip, resp.status))
                http.close()
                return (None, None)
            elif resp.status == 200:
                m = re.search(r'<input type="hidden" name="nonce" value="([0-9a-zA-Z]+)">', htmlbody)
                if m != None: break
        if m == None:
            logging.error('Endpoint %s@%s failed to locate nonce in HTTP response' %
                (self._vendorname, self._ip))
            http.close()
            return (None, None)
        nonce = m.group(1)

        # Identify firmware
        if noncesource == '/right.htm': self._firmware = 1 # Old firmware

        # Simulate POST to allow fetching rest of content
        extraheaders = {
            'Connection' : 'keep-alive',
            'Cookie' : 'auth=' + nonce,
            'Content-Type' : 'application/x-www-form-urlencoded'
        }
        postvars = {
            'encoded'   :   self._http_username + ':' +
                md5.new(':'.join((self._http_username, self._http_password, nonce))).hexdigest(),
            'nonce'     :   nonce,
            'goto'      :   'Logon',
            'URL'       :   '/'
        }
        postdata = urllib.urlencode(postvars)
        http.request('POST', noncesource, postdata, extraheaders)
        resp = http.getresponse()
        if resp.status != 200:
            logging.error('Endpoint %s@%s failed to fetch login result - got response code %s' %
                (self._vendorname, self._ip, resp.status))
            http.close()
            return (None, None)
        htmlbody = resp.read()
        return (http, nonce)
Example #13
0
    def _loginHttp_V2(self):
        try:
            # Do HTTP login and save session cookie
            postvars = {
                'username': self._http_username,
                'password': self._http_password,
                'link': 'index.htm',
                'submit': 'Login'
            }
            response = urllib2.urlopen('http://' + self._ip + '/index.htm',
                                       urllib.urlencode(postvars))
            htmlbody = response.read()
            if not 'Set-Cookie' in response.headers:
                logging.error('Endpoint %s@%s invalid username or password' %
                              (self._vendorname, self._ip))
                return False
            self._cookie_v2 = response.headers['Set-Cookie']

            # If the phone is used for the first time, it will show an EULA that
            # must be accepted in order to continue.
            m = re.search(r'<input type="radio" name="eula" value="(.+?)">',
                          htmlbody)
            if m != None:
                logging.warning('Endpoint %s@%s accepting EULA...' %
                                (self._vendorname, self._ip))
                postvars = {'eula': m.group(1), 'save': 'Submit'}
                response = urllib2.urlopen(
                    urllib2.Request('http://' + self._ip + '/index.htm',
                                    urllib.urlencode(postvars),
                                    {'Cookie': self._cookie_v2}))
                htmlbody = response.read()
            return True
        except urllib2.URLError, e:
            logging.error('Endpoint %s@%s failed to connect - %s' %
                          (self._vendorname, self._ip, str(e)))
            return False
Example #14
0
 def _setProvisionServer_V1(self):
     try:
         postvars = {
             'setting_server': 'tftp://' + self._serverip,
             'Settings': 'Save'
         }
         response = urllib2.urlopen(
             'http://' + self._ip + '/advanced_update.htm',
             urllib.urlencode(postvars))
         htmlbody = response.read()
         return True
     except urllib2.URLError, e:
         logging.error('Endpoint %s@%s failed to connect - %s' %
                       (self._vendorname, self._ip, str(e)))
         return False
Example #15
0
 def _rebootbyhttp_V2(self):
     try:
         response = urllib2.urlopen(
             urllib2.Request('http://' + self._ip + '/update.htm',
                             urllib.urlencode({'reboot': 'Reboot'}),
                             {'Cookie': self._cookie_v2}))
         htmlbody = response.read()
         if response.code == 200:
             return True
         else:
             logging.error(
                 'Endpoint %s@%s failed to reboot phone - got error code %d'
                 % (self._vendorname, self._ip, response.code))
     except urllib2.URLError, e:
         logging.error('Endpoint %s@%s failed to connect - %s' %
                       (self._vendorname, self._ip, str(e)))
         return False
Example #16
0
    def _encodeGrandstreamConfig(self, vars):
        # Encode configuration variables. The gnkey must be the last item in
        # order to prevent other variables from being followed by a null byte.
        payload = urllib.urlencode(vars) + '&gnkey=0b82'
        if (len(payload) & 1) != 0: payload = payload + '\x00'

        # Calculate block length in words, plus checksum
        length = 8 + len(payload) / 2
        binmac = self._mac.replace(':', '').lower().decode('hex')
        bindata = struct.pack('>LH6s', length, 0,
                              binmac) + '\x0d\x0a\x0d\x0a' + payload
        wordsize = len(bindata) / 2
        checksum = 0x10000 - (
            sum(struct.unpack('>' + str(wordsize) + 'H', bindata)) & 0xFFFF)
        bindata = struct.pack('>LH6s', length, checksum,
                              binmac) + '\x0d\x0a\x0d\x0a' + payload

        return bindata
Example #17
0
 def _doAuthPost(self, urlpath, postvars):
     '''Perform an HTTP POST on a particular URL using the HTTP credentials
     
     This method is frequently used to make the phone use the Elastix server
     as the TFTP source for autoprovisioning.
     ''' 
     password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
     password_manager.add_password(None, 'http://' + self._ip + '/',
         self._http_username, self._http_password)
     basic_auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
     digest_auth_handler = urllib2.HTTPDigestAuthHandler(password_manager)
     opener = urllib2.build_opener(basic_auth_handler, digest_auth_handler)
     if postvars != None:
         opener.addheaders = [('Content-Type', 'application/x-www-form-urlencoded')]
         if not isinstance(postvars, str):
             postvars = urllib.urlencode(postvars)
     try:
         opener.open('http://' + self._ip + urlpath, postvars)
     except urllib2.HTTPError, e:
         logging.error('Endpoint %s@%s failed to authenticate - %s' %
             (self._vendorname, self._ip, str(e)))
         return False
Example #18
0
    def _setupAtcomAuthentication(self):
        http = httplib.HTTPConnection(self._ip)

        nonce, noncesource = self._getNonce(http)
        if nonce == None:
            http.close()
            return (None, None)

        # Simulate POST to allow fetching rest of content
        extraheaders = {
            'Connection': 'keep-alive',
            'Cookie': 'auth=' + nonce,
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        postvars = {
            'encoded':
            self._http_username + ':' + md5.new(':'.join(
                (self._http_username, self._http_password,
                 nonce))).hexdigest(),
            'nonce':
            nonce,
            'goto':
            'Logon',
            'URL':
            '/'
        }
        postdata = urllib.urlencode(postvars)
        http.request('POST', noncesource, postdata, extraheaders)
        resp = http.getresponse()
        if resp.status != 200:
            logging.error(
                'Endpoint %s@%s failed to fetch login result - got response code %s'
                % (self._vendorname, self._ip, resp.status))
            http.close()
            return (None, None)
        htmlbody = resp.read()
        return (http, nonce)
Example #19
0
    def _sendPhoneConfiguration(self, xmlcontent):
        try:
            # Login into interface
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
            response = opener.open(
                'http://' + self._ip + '/console/j_security_check',
                urllib.urlencode({
                    'submit': 'Login',
                    'j_username': self._http_username,
                    'j_password': self._http_password
                }))
            body = response.read()
            if not '/console/start' in body:
                logging.error(
                    'Endpoint %s@%s - j_security_check failed login' %
                    (self._vendorname, self._ip))
                return False

            # Build a custom request with form data
            boundary = '------------------ENDPOINTCONFIG'
            postdata = '--' + boundary + '\r\n' +\
                'Content-Disposition: form-data; name="COMMAND"\r\n' +\
                '\r\n' +\
                'RX' + '\r\n' +\
                '--' + boundary + '\r\n' +\
                'Content-Disposition: form-data; name="RX"; filename="config.xml"\r\n' +\
                'Content-Type: text/xml\r\n' +\
                '\r\n' +\
                xmlcontent + '\r\n' +\
                '--' + boundary + '--\r\n'
            filerequest = urllib2.Request(
                'http://' + self._ip + '/console/configuration', postdata,
                {'Content-Type': 'multipart/form-data; boundary=' + boundary})
            # The phone configuration restore is known to hang for 25-30 seconds
            oldtimeout = socket.getdefaulttimeout()
            socket.setdefaulttimeout(40)
            try:
                response = opener.open(filerequest)
            finally:
                socket.setdefaulttimeout(oldtimeout)
            body = response.read()

            if not 'Configuration restore complete' in body:
                logging.error('Endpoint %s@%s - configuration post failed' %
                              (self._vendorname, self._ip))
                return False

            # Attempt to set just the provisioning server
            response = opener.open(
                'http://' + self._ip + '/console/general',
                urllib.urlencode({
                    'COMMAND': 'AP',
                    '@p.provisioningServer': self._serverip,
                    '@dhcp_option_protocol': 'TFTP'
                }))
            body = response.read()

            # Since the web interface will NOT immediately apply the network
            # changes, we need to go raw and ssh into the phone. Additionally,
            # if we are changing the network setting from DHCP to static or
            # viceversa, we expect the SSH connection to be disconnected in the
            # middle of the update. A timeout of 5 seconds should do it.
            if self._dhcp:
                command = '/root/dhcp-configure.sh'
            else:
                dns2 = 'none'
                if self._static_dns2 != None:
                    dns2 = self._static_dns2
                command = '/root/staticip-configure.sh %s %s %s %s %s' %\
                    (self._static_ip, self._static_mask, self._static_gw, self._static_dns1, dns2)
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.WarningPolicy())
            ssh.connect(self._ip,
                        username=self._ssh_username,
                        password=self._ssh_password,
                        timeout=5)
            stdin, stdout, stderr = ssh.exec_command(command)
            logging.info(
                'Endpoint %s@%s - about to set timeout of %d on stdout' % (
                    self._vendorname,
                    self._ip,
                    oldtimeout,
                ))
            stdout.channel.settimeout(5)
            try:
                s = stdout.read()
                logging.info('Endpoint %s@%s - answer follows:\n%s' % (
                    self._vendorname,
                    self._ip,
                    s,
                ))
            except socket.error, e:
                pass
            ssh.close()
            return True
Example #20
0
    def _enableStaticProvisioning_GXV(self, vars):
        try:
            # Login into interface
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
            headers = {
                'User-Agent':
                'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36',
            }
            opener.addheaders = headers.items()
            response = opener.open('http://' + self._ip + '/manager?' +
                                   urllib.urlencode({
                                       'action': 'login',
                                       'Username': self._http_username,
                                       'Secret': self._http_password,
                                       'time': (int)(time.time())
                                   }))
            body = response.read()
            if 'Error' in body:
                logging.error('Endpoint %s@%s GXV - dologin failed login' %
                              (self._vendorname, self._ip))
                return False

            # For this interface, the variables are translated as follows: The
            # source key of the form Pxxxx produces a variable var-dddd where
            # dddd is a counter. The corresponding value produces a variable
            # val-dddd with the same counter
            varcount = 0
            submitvars = {'action': 'put', 'time': (int)(time.time())}
            for pk in vars:
                varkey = 'var-' + ('%04d' % (varcount, ))
                varval = 'val-' + ('%04d' % (varcount, ))
                submitvars[varkey] = pk[1:]
                submitvars[varval] = vars[pk]
                varcount += 1
            response = opener.open('http://' + self._ip + '/manager?' +
                                   urllib.urlencode(submitvars))
            body = response.read()
            if not ('Success' in body):
                logging.error(
                    'Endpoint %s@%s GXV - dologin failed to keep session' %
                    (self._vendorname, self._ip))
                return False

            # Phonebook programming is a special case.
            submitvars = {
                'action': 'putdownphbk',
                'time': (int)(time.time()),
                'url': vars['P331'],
                'mode': 2,  # HTTP
                'clear-old': 1,
                'flag': 1,  # 1 forces download right now
                'interval': vars['P332'],
                'rm-redup': 1
            }
            # This generates problems with GXV3240
            # logging.info('Endpoint %s@%s GXV failed to send vars to interface - %s' %
            #    (self._vendorname, self._ip, 'http://' + self._ip + '/manager?' + urllib.urlencode(submitvars)))
            # response = opener.open('http://' + self._ip + '/manager?' + urllib.urlencode(submitvars))
            # body = response.read()
            # if not ('Success' in body):
            #    logging.error('Endpoint %s@%s GXV - could not reprogram phonebook' %
            #        (self._vendorname, self._ip))

            return True
        except httplib.HTTPException as e:
            logging.info(
                'Endpoint %s@%s GXV failed to send vars to interface - %s' %
                (self._vendorname, self._ip, str(e)))
            return True
        except urllib2.HTTPError, e:
            logging.error(
                'Endpoint %s@%s GXV failed to send vars to interface - %s' %
                (self._vendorname, self._ip, str(e)))
            return False
Example #21
0
    def _enableStaticProvisioning_GXV(self, vars):
        try:
            # Login into interface
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
            response = opener.open('http://' + self._ip + '/manager?' +
                                   urllib.urlencode({
                                       'action': 'login',
                                       'Username': self._http_username,
                                       'Secret': self._http_password,
                                       'time': (int)(time.time())
                                   }))
            body = response.read()
            if 'Error' in body:
                logging.error('Endpoint %s@%s GXV - dologin failed login' %
                              (self._vendorname, self._ip))
                return False

            # For this interface, the variables are translated as follows: The
            # source key of the form Pxxxx produces a variable var-dddd where
            # dddd is a counter. The corresponding value produces a variable
            # val-dddd with the same counter
            varcount = 0
            submitvars = {'action': 'put', 'time': (int)(time.time())}
            for pk in vars:
                varkey = 'var-' + ('%04d' % (varcount, ))
                varval = 'val-' + ('%04d' % (varcount, ))
                submitvars[varkey] = pk[1:]
                submitvars[varval] = vars[pk]
                varcount += 1

            response = opener.open('http://' + self._ip + '/manager?' +
                                   urllib.urlencode(submitvars))
            body = response.read()
            if not ('Success' in body):
                logging.error(
                    'Endpoint %s@%s GXV - dologin failed to keep session' %
                    (self._vendorname, self._ip))
                return False

            # Phonebook programming is a special case.
            submitvars = {
                'action': 'putdownphbk',
                'time': (int)(time.time()),
                'url': vars['P331'],
                'mode': 2,  # HTTP
                'clear-old': 1,
                'flag': 1,  # 1 forces download right now
                'interval': vars['P332'],
                'rm-redup': 1
            }
            response = opener.open('http://' + self._ip + '/manager?' +
                                   urllib.urlencode(submitvars))
            body = response.read()
            if not ('Success' in body):
                logging.error(
                    'Endpoint %s@%s GXV - could not reprogram phonebook' %
                    (self._vendorname, self._ip))

            return True
        except urllib2.HTTPError, e:
            logging.error(
                'Endpoint %s@%s GXV failed to send vars to interface - %s' %
                (self._vendorname, self._ip, str(e)))
            return False
Example #22
0
 def _setProvisionServer_V2(self):
     sConfigFile = 'snom-' + self._model + '-' + (self._mac.replace(
         ':', '').upper()) + '.xml'
     try:
         '''
         base_name=snom-at-192.168.254.254-reg-192.168.254.1&
         asset_id=&
         dhcp=true&
         ip_adr=&
         netmask=&
         gateway=&
         dns_server1=&
         dns_server2=&
         dns_server3=&
         dns_server4=&
         dns_domain=&
         vlan_id=0&
         vlan_prio=0&
         setting_server=192.168.254.2&
         settings_refresh_timer=86400&
         sip_port=0&
         retry_t1=500&
         tos_rtp=160&
         tos_sip=160&
         allow_check_sync=false&
         stun_server=&
         stun_interval=5&
         ethernet_replug=reregister&
         network=true&
         save=Save
         '''
         postvars = {
             'setting_server': 'tftp://' + self._serverip,
             'base_name': 'snom-at-' + self._ip + '-reg-' + self._serverip,
             'dhcp': 'true',
             'ip_adr': '',
             'netmask': '',
             'gateway': '',
             'dns_server1': '',
             'dns_server2': '',
             'dns_server3': '',
             'dns_server4': '',
             'allow_check_sync': 'true',  # Needed for sip notify to work
             'save': 'Save',
             'network': 'true',
             'asset_id': '',
             'vlan_id': 0,
             'vlan_prio': 0,
             'settings_refresh_timer': 86400,
             'sip_port': 0,
             'retry_t1': 500,
             'tos_rtp': 160,
             'tos_sip': 160,
             'stun_server': '',
             'stun_interval': 5,
             'ethernet_replug': 'reregister',
         }
         if not self._dhcp:
             postvars.update({
                 'dhcp': 'false',
                 'ip_adr': self._static_ip,
                 'netmask': self._static_mask,
                 'gateway': self._static_gw,
                 'dns_server1': self._static_dns1,
                 'dns_server2': self._static_dns2,
             })
         response = urllib2.urlopen(
             urllib2.Request('http://' + self._ip + '/network.htm',
                             urllib.urlencode(postvars),
                             {'Cookie': self._cookie_v2}))
         htmlbody = response.read()
         if not 'Please reboot the device' in htmlbody:
             logging.error(
                 'Endpoint %s@%s failed to save provisioning or network settings'
                 % (self._vendorname, self._ip))
             return False
         return True
     except urllib2.URLError, e:
         logging.error('Endpoint %s@%s failed to connect - %s' %
                       (self._vendorname, self._ip, str(e)))
         return False
Example #23
0
    def _enableStaticProvisioning(self):
        # The Aastra firmware is stateful, in an annoying way. Just submitting
        # a POST to the autoprovisioning URL from the factory-default setting will
        # only get a 200 OK with a message to visit sysinfo.html, and the settings
        # will NOT be applied.
        # To actually apply the settings, it is required to perform a dummy GET
        # to /sysinfo.html, discard anything returned, and only then
        # perform the POST.
        # Additionally, the TCP/IP and HTTP stack of the Aastra 6739i is buggy.
        # When performing a POST, the firmware wants the end of the headers and
        # the start of the body in the same TCP/IP packet. If they are on
        # different packets, the request hangs. Due to the way urllib2 works,
        # it introduces a flush between the two, which triggers said hang.
        # Therefore, the full POST request must be assembled and sent manually
        # as a single write.
        if not self._doAuthGet('/sysinfo.html'):
            return False

        # Set the Elastix server as the provisioning server
        postvars = {
            'protocol': 'TFTP',
            'tftp': self._serverip,
            'tftppath': '',
            'alttftp': self._serverip,
            'alttftppath': '',
            'usealttftp': '1',
            'ftpserv': '',
            'ftppath': '',
            'ftpuser': '',
            'ftppass': '',
            'httpserv': '',
            'httppath': '',
            'httpport': 80,
            'httpsserv': '',
            'httpspath': '',
            'httpsport': 80,
            'autoResyncMode': 0,
            'autoResyncTime': '00:00',
            'maxDelay': 15,
            'days': 0,
            'postList': self._serverip,
        }
        postbody = urllib.urlencode(postvars)
        urlpath = '/configurationServer.html'
        postrequest = (\
            'POST %s HTTP/1.1\r\n' +\
            'Host: %s\r\n' +\
            'Connection: close\r\n' +\
            'Accept-Encoding: identity\r\n' +\
            'Authorization: Basic %s\r\n' +\
            'Content-length: %d\r\n' +\
            'Content-type: application/x-www-form-urlencoded\r\n' +\
            '\r\n%s') % (urlpath, self._ip, base64.encodestring('%s:%s' % (self._http_username, self._http_password)).strip(), len(postbody), postbody)
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((self._ip, 80))
            sock.sendall(postrequest)

            # Rather than parse the response myself, I create an instance of
            # HTTPResponse. However, begin() is an internal method, and not
            # guaranteed to exist in future versions of the library.
            resp = httplib.HTTPResponse(sock, strict=1, method='POST')
            resp.begin()
            htmlbody = resp.read()

            if resp.status <> 200:
                logging.error(
                    'Endpoint %s@%s failed to post configuration - %s' %
                    (self._vendorname, self._ip, r))
                return False
            if not 'Provisioning complete' in htmlbody:
                logging.error(
                    'Endpoint %s@%s failed to set configuration server - not provisioned'
                    % (self._vendorname, self._ip))
                return False
        except socket.error, e:
            logging.error('Endpoint %s@%s failed to connect - %s' %
                          (self._vendorname, self._ip, str(e)))
            return False
Example #24
0
    def parse_rest(self,url,data={}):
        html_json=self.fetch(url,False)[1]
        next_page=str(int(data['current_page'])+1)
        self.requests.put((self.parse_rest,self.domain_url+self.search_other_pages%next_page+"&"+urllib.urlencode({'location':self.full_city})+"&"+data['query'],{'current_page':next_page,"query":data['query']}))
        try:
            html=json.loads(html_json)
            xs=HtmlXPathSelector(text=html['results'])
            for link in xs.select("//div[@class='listing-outer']//a[@class='target-details']/@href").extract():
                self.requests.put((self.parse_room,self.domain_url+link,{}))


        except:
            #ADD LOGGER
            self.scrape_finished=True
Example #25
0
 def _transmit(self, command, data):
     enc_data = urllib.urlencode(data)
     self.conn.request('POST', '/web/%s'%command, enc_data, self.headers)
     resp = self.conn.getresponse()
     return resp.read()
Example #26
0
    def updateLocalConfig(self):
        '''Configuration for INCOM endpoints (local):

        The following procedure was developed for the ICW-1000 wireless phone.

        All interaction must be done on unencrypted HTTP protocol on port 8080.
        The phone interface requires an administrator login on /s_login.htm . The
        POST is unusual in that it apparently needs the question mark that would
        normally separate a GET request from its parameters. However, tests show
        that a GET works just as well for login. The session is IP-based with
        a timeout. 200 OK for success, 500 for error.

        The query /xpdb.uds?mode=list&db=config lists the entire catalog of
        known configuration variables, as a JSON structure. This structure
        consists of an object with a "section" member and an "entry" member. The
        "section" member is an array of objects that describe one section each,
        with a "name" member and a "sid" member. The "sid" value for a given
        section must be picked for a later POST.

        The top-level "entry" member is an array of objects that describe one
        scalar configuration variable each. Each variable has a "sid" number,
        an "eid" number and a "name" description. The "eid" value for a given
        variable must be picked for a later POST.

        To change a set of variables, a POST to /xpdb.uds must be done with
        the following variables: ?mode=change&db=config&... Each variable to
        update must set sidN=###&eidN=###&valN=### for each N counting from
        0. Additionally, a "cnt" variable must be set at the end with the number
        of modified variables. If successful, 200 OK and a listing of updated
        variables.

        USER ACCOUNT/Displayname
        USER ACCOUNT/Phone Number
        USER ACCOUNT/User ID
        USER ACCOUNT/User Password
        USER ACCOUNT/URL Scheme

        SERVER SETTINGS/1st Proxy
        SERVER SETTINGS/Domain Realm

        To reboot the phone, it is necessary to POST to /s_reboot.htm while
        authenticated.
        '''
        # Check that there is at least one account to configure
        if len(self._accounts) <= 0:
            logging.error('Endpoint %s@%s has no accounts to configure' %
                (self._vendorname, self._ip))
            return False

        try:
            # Login into interface
            response = urllib2.urlopen('http://' + self._ip + ':8080/s_login.htm',
                urllib.urlencode({'id' : self._http_username, 'password' : self._http_password}))
            body = response.read()

            # The body is JSON but Content-Type is set to text/plain
            response = urllib2.urlopen('http://' + self._ip + ':8080/xpdb.uds?mode=list&db=config')
            body = response.read()
            jsonvars = cjson.decode(body)

            # Use the JSON map to find out values for sid and eid
            varmap = {
                'USER ACCOUNT': {
                    'Displayname'   : None,
                    'Phone Number'  : None,
                    'User ID'       : None,
                    'User Password' : None,
                    'URL Scheme'    : None,
                },
                'SERVER SETTINGS': {
                    '1st Proxy'     : None,
                    'Domain Realm'  : None,
                },
            }

            # The ICW-1000 has up to 12 network configurations, labeled NETWORK1 to
            # NETWORK12. The one that should be configured is the one that contains
            # the current IP being used to access the device.
            for i in range(1,13):
                k_sid = 'NETWORK' + str(i)
                varmap[k_sid] = {
                    'Enable DHCP'   : None,
                    'Address'       : None,
                    'Netmask'       : None,
                    'Gateway'       : None,
                    'DNS1'          : None,
                    'DNS2'          : None,
                }
            for k_sid in varmap:
                v_sid = self._sectionFromName(jsonvars, k_sid)
                if v_sid == None:
                    logging.error('Endpoint %s@%s received invalid JSON - cannot locate sid for %s' %
                        (self._vendorname, self._ip, k_sid))
                    return False
                for k_entry in varmap[k_sid]:
                    v_entry = self._entryFromName(jsonvars, v_sid, k_entry)
                    if v_entry == None:
                        logging.error('Endpoint %s@%s received invalid JSON - cannot locate eid for %s' %
                            (self._vendorname, self._ip, k_entry))
                        return False
                    varmap[k_sid][k_entry] = v_entry
            current_network = None
            for i in range(1,13):
                k_sid = 'NETWORK' + str(i)
                #logging.info('Endpoint %s@%s - %s Address %s looking for %s' %
                #    (self._vendorname, self._ip, k_sid, varmap[k_sid]['Address'], self._ip))
                if varmap[k_sid]['Address']['value'] == self._ip:
                    current_network = k_sid
                    break
            if current_network == None:
                logging.warning('Endpoint %s@%s - cannot locate network for %s, cannot update network settings' %
                    (self._vendorname, self._ip, self._ip))
                return False

            vars = self._prepareVarList()
            postvars = {'mode': 'change', 'db': 'config'}
            postvars.update(self._createPOSTVar(varmap, 0, 'SERVER SETTINGS', '1st Proxy', vars['server_ip']))
            postvars.update(self._createPOSTVar(varmap, 1, 'SERVER SETTINGS', 'Domain Realm', vars['server_ip']))
            postvars.update(self._createPOSTVar(varmap, 2, 'USER ACCOUNT', 'Displayname', vars['sip'][0].description))
            postvars.update(self._createPOSTVar(varmap, 3, 'USER ACCOUNT', 'Phone Number', vars['sip'][0].extension))
            postvars.update(self._createPOSTVar(varmap, 4, 'USER ACCOUNT', 'User ID', vars['sip'][0].account))
            postvars.update(self._createPOSTVar(varmap, 5, 'USER ACCOUNT', 'User Password', vars['sip'][0].secret))
            postvars.update(self._createPOSTVar(varmap, 6, 'USER ACCOUNT', 'URL Scheme', 'SIP'))
            postvar_count = 7
            postvars.update({'cnt': postvar_count})

            # Send updated variables
            response = urllib2.urlopen('http://' + self._ip + ':8080/xpdb.uds',
                urllib.urlencode(postvars))
            body = response.read()

            # Apparently the ICW-1000 does not support setting the phone account
            # and the network settings in a single request
            if current_network != None:
                postvars = {'mode': 'change', 'db': 'config'}
                postvars.update(self._createPOSTVar(varmap, 0, current_network, 'Enable DHCP', vars['enable_dhcp']))
                postvar_count = 1
                if not self._dhcp:
                    postvars.update(self._createPOSTVar(varmap, 1, current_network, 'Address', vars['static_ip']))
                    postvars.update(self._createPOSTVar(varmap, 2, current_network, 'Netmask', vars['static_mask']))
                    postvars.update(self._createPOSTVar(varmap, 3, current_network, 'Gateway', vars['static_gateway']))
                    postvars.update(self._createPOSTVar(varmap, 4, current_network, 'DNS1', vars['static_dns1']))
                    postvars.update(self._createPOSTVar(varmap, 5, current_network, 'DNS1', vars['static_dns2']))
                    postvar_count += 5
                postvars.update({'cnt': postvar_count})
                # Send updated variables
                response = urllib2.urlopen('http://' + self._ip + ':8080/xpdb.uds',
                    urllib.urlencode(postvars))
                body = response.read()

            # Reiniciar el teléfono
            response = urllib2.urlopen('http://' + self._ip + ':8080/s_reboot.htm', '')
            body = response.read()

            self._unregister()
            self._setConfigured()
            return True
        except cjson.DecodeError, e:
            logging.error('Endpoint %s@%s received invalid JSON - %s' %
                (self._vendorname, self._ip, str(e)))
            return False
Example #27
0
 def parse_first(self,url,data={}):
     """Fetch url for scraping and parsing the data with a right function"""
     xs=self.fetch(url)[1]
     for link in xs.select("//div[@class='listing-outer']//a[@class='target-details']/@href").extract():
         self.requests.put((self.parse_room,self.domain_url+link,{}))
     self.full_city=xs.select("//input[@name='location']/@value").extract()[0]
     query=urllib.splitquery(url)
     if len(query)>1:
         query=query[1].replace("&source=bb","")
     else:
         query=""
     self.requests.put((self.parse_rest,self.domain_url+self.search_other_pages%"2&"+urllib.urlencode({"location":self.full_city})+"&"+query,{'current_page':'2','query':query}))