Beispiel #1
0
 def do_login(self):
     '''
     There's a bunch of dynamically generated obfuscated JavaScript,
     which uses DOM. For now the easiest option seems to be to run it in
     PhantomJs.
     '''
     for i in xrange(self.MAX_RETRIES):
         scrf, scrn = mkstemp('.js')
         cookf, cookn = mkstemp('.json')
         os.write(scrf, LOGIN_JS % {
             'timeout': self.TIMEOUT,
             'username': self.username,
             'password': self.password,
             'output': cookn,
             'question1': self.question1,
             'answer1': self.answer1,
             'question2': self.question2,
             'answer2': self.answer2,
             'question3': self.question3,
             'answer3': self.answer3})
         os.close(scrf)
         os.close(cookf)
         check_output(["phantomjs", scrn], stderr=STDOUT)
         with open(cookn) as cookf:
             cookies = json.loads(cookf.read())
         os.remove(scrn)
         os.remove(cookn)
         self.session.cookies.clear()
         for c in cookies:
           for k in ['expiry', 'expires', 'httponly']:
             c.pop(k, None)
           c['value'] = unquote(c['value'])
           self.session.cookies.set(**c)
         self.summary.go()
         if self.page.logged:
             break
     else:
         raise BrowserIncorrectPassword
Beispiel #2
0
 def extra(self):
     APPEND = r'jQuery\( "form" \).each\(function\(\) {' \
                 r'if\(isValidUrl\(jQuery\(this\).attr\("action"\)\)\){' \
                     r'jQuery\(this\).append\(([^)]+)\);}}\);'
     script = self.doc.xpath(
         '//script[contains(text(),"XXX_Extra")]/text()')[0]
     script = re.sub(APPEND, lambda m: 'return %s;' % m.group(1), script)
     script = re.sub(r'jQuery\(document\)[^\n]+\n', '', script)
     for x in re.findall('function ([^(]+)\(', script):
         script += '\nvar x = %s(); if (x) print(x);' % x
     scriptFd, scriptName = mkstemp('.js')
     os.write(scriptFd, script)
     os.close(scriptFd)
     html = check_output(["d8", scriptName], stderr=STDOUT)
     os.remove(scriptName)
     return re.findall(r'name=([^ ]+) value=([^>]+)>', html)
Beispiel #3
0
 def extra(self):
     APPEND = r'jQuery\( "form" \).each\(function\(\) {' \
                 r'if\(isValidUrl\(jQuery\(this\).attr\("action"\)\)\){' \
                     r'jQuery\(this\).append\(([^)]+)\);}}\);'
     script = self.doc.xpath(
         '//script[contains(text(),"XXX_Extra")]/text()')[0]
     script = re.sub(APPEND, lambda m: 'return %s;' % m.group(1), script)
     script = re.sub(r'jQuery\(document\)[^\n]+\n', '', script)
     for x in re.findall('function ([^(]+)\(', script):
         script += '\nvar x = %s(); if (x) print(x);' % x
     scriptFd, scriptName = mkstemp('.js')
     os.write(scriptFd, script)
     os.close(scriptFd)
     html = check_output(["d8", scriptName], stderr=STDOUT)
     os.remove(scriptName)
     return re.findall(r'name=([^ ]+) value=([^>]+)>', html)
    def ask(self,
            question,
            default=None,
            masked=None,
            regexp=None,
            choices=None,
            tiny=None):
        """
        Ask a question to user.

        @param question  text displayed (str)
        @param default  optional default value (str)
        @param masked  if True, do not show typed text (bool)
        @param regexp  text must match this regexp (str)
        @param choices  choices to do (list)
        @param tiny  ask for the (small) value of the choice (bool)
        @return  entered text by user (str)
        """

        if isinstance(question, Value):
            v = copy(question)
            if default is not None:
                v.default = to_unicode(default) if isinstance(default,
                                                              str) else default
            if masked is not None:
                v.masked = masked
            if regexp is not None:
                v.regexp = regexp
            if choices is not None:
                v.choices = choices
            if tiny is not None:
                v.tiny = tiny
        else:
            if isinstance(default, bool):
                klass = ValueBool
            elif isinstance(default, float):
                klass = ValueFloat
            elif isinstance(default, (int, long)):
                klass = ValueInt
            else:
                klass = Value

            v = klass(label=question,
                      default=default,
                      masked=masked,
                      regexp=regexp,
                      choices=choices,
                      tiny=tiny)

        question = v.label
        if v.id:
            question = u'[%s] %s' % (v.id, question)

        if isinstance(v, ValueBackendPassword):
            print(question.encode(self.encoding) + ':')
            question = v.label
            choices = OrderedDict()
            choices['c'] = 'Run an external tool during backend load'
            if not v.noprompt:
                choices['p'] = 'Prompt value when needed (do not store it)'
            choices['s'] = 'Store value in config'

            if v.is_command(v.default):
                d = 'c'
            elif v.default == '' and not v.noprompt:
                d = 'p'
            else:
                d = 's'

            r = self.ask('*** How do you want to store it?',
                         choices=choices,
                         tiny=True,
                         default=d)
            if r == 'p':
                return ''
            if r == 'c':
                print(
                    'Enter the shell command that will print the required value on the standard output'
                )
                if v.is_command(v.default):
                    print(': %s' % v.default[1:-1])
                else:
                    d = None
                while True:
                    cmd = self.ask('')
                    try:
                        check_output(cmd, shell=True)
                    except subprocess.CalledProcessError as e:
                        print('%s' % e)
                    else:
                        return '`%s`' % cmd

        aliases = {}
        if isinstance(v, ValueBool):
            question = u'%s (%s/%s)' % (question, 'Y' if v.default else 'y',
                                        'n' if v.default else 'N')
        elif v.choices:
            if v.tiny is None:
                v.tiny = True
                for key in v.choices.iterkeys():
                    if len(key) > 5 or ' ' in key:
                        v.tiny = False
                        break

            if v.tiny:
                question = u'%s (%s)' % (question, '/'.join(
                    (s.upper() if s == v.default else s)
                    for s in v.choices.iterkeys()))
                for s in v.choices.iterkeys():
                    if s == v.default:
                        aliases[s.upper()] = s
                for key, value in v.choices.iteritems():
                    print('     %s%s%s: %s' % (self.BOLD, key, self.NC, value))
            else:
                for n, (key, value) in enumerate(v.choices.iteritems()):
                    print('     %s%2d)%s %s' % (self.BOLD, n + 1, self.NC,
                                                value.encode(self.encoding)))
                    aliases[str(n + 1)] = key
                question = u'%s (choose in list)' % question
        if v.masked:
            question = u'%s (hidden input)' % question

        if not isinstance(
                v, ValueBool) and not v.tiny and v.default not in (None, ''):
            question = u'%s [%s]' % (question,
                                     '*******' if v.masked else v.default)

        question += ': '

        while True:
            if v.masked:
                if sys.platform == 'win32':
                    line = getpass.getpass(str(question))
                else:
                    line = getpass.getpass(question.encode(self.encoding))
            else:
                self.stdout.write(question.encode(self.encoding))
                self.stdout.flush()
                line = self.stdin.readline()
                if len(line) == 0:
                    raise EOFError()
                else:
                    line = line.rstrip('\r\n')

            if not line and v.default is not None:
                line = v.default
            if isinstance(line, str):
                line = line.decode('utf-8')

            if line in aliases:
                line = aliases[line]

            try:
                v.set(line)
            except ValueError as e:
                print(u'Error: %s' % e, file=self.stderr)
            else:
                break

        v.noprompt = True
        return v.get()
Beispiel #5
0
    def ask(self, question, default=None, masked=None, regexp=None, choices=None, tiny=None):
        """
        Ask a question to user.

        @param question  text displayed (str)
        @param default  optional default value (str)
        @param masked  if True, do not show typed text (bool)
        @param regexp  text must match this regexp (str)
        @param choices  choices to do (list)
        @param tiny  ask for the (small) value of the choice (bool)
        @return  entered text by user (str)
        """

        if isinstance(question, Value):
            v = copy(question)
            if default is not None:
                v.default = to_unicode(default) if isinstance(default, str) else default
            if masked is not None:
                v.masked = masked
            if regexp is not None:
                v.regexp = regexp
            if choices is not None:
                v.choices = choices
            if tiny is not None:
                v.tiny = tiny
        else:
            if isinstance(default, bool):
                klass = ValueBool
            elif isinstance(default, float):
                klass = ValueFloat
            elif isinstance(default, (int,long)):
                klass = ValueInt
            else:
                klass = Value

            v = klass(label=question, default=default, masked=masked, regexp=regexp, choices=choices, tiny=tiny)

        question = v.label
        if v.id:
            question = u'[%s] %s' % (v.id, question)

        if isinstance(v, ValueBackendPassword):
            print(question.encode(self.encoding) + ':')
            question = v.label
            choices = OrderedDict()
            choices['c'] = 'Run an external tool during backend load'
            if not v.noprompt:
                choices['p'] = 'Prompt value when needed (do not store it)'
            choices['s'] = 'Store value in config'

            if v.is_command(v.default):
                d = 'c'
            elif v.default == '' and not v.noprompt:
                d = 'p'
            else:
                d = 's'

            r = self.ask('*** How do you want to store it?', choices=choices, tiny=True, default=d)
            if r == 'p':
                return ''
            if r == 'c':
                print('Enter the shell command that will print the required value on the standard output')
                if v.is_command(v.default):
                    print(': %s' % v.default[1:-1])
                else:
                    d = None
                while True:
                    cmd = self.ask('')
                    try:
                        check_output(cmd, shell=True)
                    except subprocess.CalledProcessError as e:
                        print('%s' % e)
                    else:
                        return '`%s`' % cmd

        aliases = {}
        if isinstance(v, ValueBool):
            question = u'%s (%s/%s)' % (question, 'Y' if v.default else 'y', 'n' if v.default else 'N')
        elif v.choices:
            if v.tiny is None:
                v.tiny = True
                for key in v.choices.iterkeys():
                    if len(key) > 5 or ' ' in key:
                        v.tiny = False
                        break

            if v.tiny:
                question = u'%s (%s)' % (question, '/'.join((s.upper() if s == v.default else s)
                                                            for s in v.choices.iterkeys()))
                for s in v.choices.iterkeys():
                    if s == v.default:
                        aliases[s.upper()] = s
                for key, value in v.choices.iteritems():
                    print('     %s%s%s: %s' % (self.BOLD, key, self.NC, value))
            else:
                for n, (key, value) in enumerate(v.choices.iteritems()):
                    print('     %s%2d)%s %s' % (self.BOLD, n + 1, self.NC,
                                                value.encode(self.encoding)))
                    aliases[str(n + 1)] = key
                question = u'%s (choose in list)' % question
        if v.masked:
            question = u'%s (hidden input)' % question

        if not isinstance(v, ValueBool) and not v.tiny and v.default not in (None, ''):
            question = u'%s [%s]' % (question, '*******' if v.masked else v.default)

        question += ': '

        while True:
            if v.masked:
                if sys.platform == 'win32':
                    line = getpass.getpass(str(question))
                else:
                    line = getpass.getpass(question.encode(self.encoding))
            else:
                self.stdout.write(question.encode(self.encoding))
                self.stdout.flush()
                line = self.stdin.readline()
                if len(line) == 0:
                    raise EOFError()
                else:
                    line = line.rstrip('\r\n')

            if not line and v.default is not None:
                line = v.default
            if isinstance(line, str):
                line = line.decode('utf-8')

            if line in aliases:
                line = aliases[line]

            try:
                v.set(line)
            except ValueError as e:
                print(u'Error: %s' % e, file=self.stderr)
            else:
                break

        v.noprompt = True
        return v.get()