Exemple #1
0
 def __init__( self, inDevice=None ):
     """ Constructor """
     assert inDevice != None
     
     Connection.__init__( self, inDevice )
     self._conn = Ssh()
Exemple #2
0
class SshConnection( Connection ):
    """ Encapsulates an Ssh Connection to a device """
    
    def __init__( self, inDevice=None ):
        """ Constructor """
        assert inDevice != None
        
        Connection.__init__( self, inDevice )
        self._conn = Ssh()

    def open( self, inHost=None, inPort=22 ):
        """ Open the connection to the device """
        assert inHost != None
        
        self._conn.open( inHost, inPort )
        self._isOpen = 1
        self._debuglog( "Connection open" )
        if self._device.needsWakeup():
            self.wakeup()

    def wakeup( self ):
        """ Helper function to send CRLF's to the device in order to wake it up """
        self._debuglog( "Trying to wakeup the device with CRLF (twice)" )
        self._conn.write("\r\n")
        self._conn.write("\015\012")

    def close( self ):
        """ Close the connection to the device """
        
        if self._isOpen:
            self.enablePaging()
            if self._device.getCommand('logout'):
                self._conn.cmd(self._device.getCommand('logout'))
            self._conn.close()
        self._isOpen = 0

#	def whereami( self ):
#		matches = [
#			self._device.getPrompt('rommon'),
#            self._device.getPrompt('username'),
#            self._device.getPrompt('login'),
#            self._device.getPrompt('password'),
#            self._device.getPrompt('command-enabled') ]
#            self._device.getPrompt('command-notenabled') ]
#		]
#
    def login( self, inUser=None, inPass=None ):
        """ Login to the device using a username and password """

        # Whooooo's on the other end ? a little state machine is more suited to the task:
        # one's never know what state is the device in anyway

        self._conn.login(inUser,inPass)

        matches = [ self._device.getPrompt('rommon'),
                    self._device.getPrompt('username'),
                    self._device.getPrompt('login'),
                    self._device.getPrompt('password'),
                    self._device.getPrompt('command'),
                    self._device.getPrompt('initialconfig') ]
        
        self._debuglog( "Looking for a prompt. Any kind of prompt" )

        sentWakeup, sentUser, sentPass, loggedIn, result = 0,0,0,0,None

        while loggedIn != 1:
            self._debuglog( "Trying to match:\n\t" + "\n\t".join(matches) \
                + " in: " + self._lastPrompt )

            result = self._conn.expect( matches, self._timeout )
            
            if result[0] == 0:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                self._debuglog( "Found a rommon prompt: not logged-in, but we can stop trying." )
                loggedIn  = 1

            elif result[0] in [1,2]:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                if sentUser:
                    self._debuglog( "Still facing a login/username prompt. Login Failed" )
                    self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                    raise RuntimeError, LoginFailedException
                self._debuglog( "Found login/username prompt. Sending User" )
                assert inUser != None
                self._conn.write( inUser + "\n" )
                sentUser = 1
                
            elif result[0] == 3:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                if sentPass:
                    self._debuglog( "Still facing a password prompt. Login Failed" )
                    self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                    raise RuntimeError, LoginFailedException
                self._debuglog( "Found password prompt. Sending Pass" )
                assert inPass != None
                self._conn.write( inPass + "\n" )
                sentPass = 1
            
            elif result[0] == 4:
                self._debuglog( "Matched: [" + str(result[0]) + "]: " + matches[result[0]] )
                self._debuglog( "Found a cmd prompt: We are logged in" )
                loggedIn = 1

            elif result[0] == 5:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                self._debuglog( "Found an initial config prompt: Successfully ignored config" )
                self._conn.write( "no" )
                self.crlf()
                time.sleep(3)
                self.crlf()
                self.wakeup()
                loggedIn = 1
 
            elif result[0] == -1:
                self._debuglog( "Matched: [" +  str(result[0]) + "].")
                if sentWakeup:
                    self._debuglog( "Still no prompt. Quitting" )
                    self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                    raise RuntimeError, LoginFailedException
                self._debuglog( "Found no prompt. Trying to wakeup the device with CRLF." )
                self.wakeup()
                sentWakeup = 1
           
        if(self._device._class == 'ASA'):
            self._debuglog( "Warning: disablePaging at logon time is disabled for ASA: run disablePaging() once in enabled mode." )
        else:
            self.disablePaging()
    
    def cmd( self, inCmd=None, inPrompt=None, inConfirm=False ):
        """ Run a command on the device and return the output """
        assert inCmd != None

        # Handle blank commands (i.e. unimplemented in the Device subclass)
        if inCmd == "":
            return ""
        
        self._debuglog( "running command (" + inCmd + ")" )
        self._conn.write( inCmd + "\n" )
    
        if inConfirm:
            self._conn.write( "y\n" )

        if inPrompt != None:
            if type( inPrompt ) == types.ListType:
                prompts = inPrompt
            else:
                prompts = [ inPrompt ]
        else:
            prompts = [ self._device.getPrompt('command') ]

        self._debuglog("Looking for cmd prompt:")
        self._debuglog( "Trying to match:\n\t" + "\n\t".join(prompts) \
                       + "\n             in: " + self._lastPrompt )

        result = self._conn.expect( prompts, self._timeout )

        # Store the last prompt we saw
        if result[1] != None:
            self._lastPrompt = result[1].group()

        # Remove the command itself from the output
        exp = re.compile( '^%s\s*$\n' % re.escape(inCmd), re.MULTILINE )
        output = exp.sub( '', result[2], 1 )
        
        # Remove the prompt from the output and return the results
        exp = re.compile( self._device.getPrompt('command') )
        return exp.sub( '', output )

    #def cmd( self, inCmd=None, inPrompt=None, inConfirm=False ):
    #    """ Run a command on the device and return the output """
    #    assert inCmd != None
    #
    #    # Handle blank commands (i.e. unimplemented in the Device subclass)
    #    if inCmd == "":
    #        return ""
    #    
    #    self._debuglog( "running command (" + inCmd + ")" )
    #    self._conn.write( inCmd + "\n" )
    #
    #    if inConfirm:
    #        self._conn.write( "y\n" )
    #
    #    if inPrompt != None:
    #        if type( inPrompt ) == types.ListType:
    #            prompts = inPrompt
    #        else:
    #            prompts = [ inPrompt ]
    #    else:
    #        prompts = [ self._device.getPrompt('command'),self._device.getPrompt('confirm') ]
    #
    #    self._debuglog("Looking for cmd/confirm prompt:")
    #    self._debuglog( "Trying to match:\n\t" + "\n\t".join(prompts) \
    #                   + "\n             in: " + self._lastPrompt )
    #
    #    confirmed = 0
    #    result = self._conn.expect( prompts, self._timeout )
    #
    #    # If expect returned a confirmation prompt, answer yes and expect again
    #    if result[0] == 1:
    #      if confirmed == 0:
    #          self._conn.write( "y" )
    #      else:
    #          self._conn.write( "yes" )
    #          self.crlf()
    #      result = self._conn.expect( prompts, self._timeout )
    #
    #    if result[0] == 1:
    #      if confirmed == 0:
    #          self._conn.write( "y" )
    #      else:
    #          self._conn.write( "yes" )
    #          self.crlf()
    #      result = self._conn.expect( prompts, self._timeout )
    #
    #    # Store the last prompt we saw
    #    if result[1] != None:
    #        self._lastPrompt = result[1].group()
    # 
    #    # Remove the command itself from the output
    #    exp = re.compile( '^%s\s*$\n' % re.escape(inCmd), re.MULTILINE )
    #    output = exp.sub( '', result[2], 1 )
    #    
    #    # Remove the prompt from the output and return the results
    #    exp = re.compile( self._device.getPrompt('command') )
    #    return exp.sub( '', output )

    def enable( self, inPass=None ):
        """ Put the connection in 'superuser' mode """

        if inPass == None:
            inPass = ''
 
        matches = [ self._device.getPrompt('rommon'),
                    self._device.getPrompt('password'),
                    self._device.getPrompt('command-enabled'),
                    self._device.getPrompt('command-notenabled'),
                ]
        
        self._debuglog( "Looking for enable ?" )

        result = None
        sentEnable, enabled, sentEnablePass, sentWakeup, sentExtraNewline = 0,0,0,0,0
        self._conn.write( self._device.getCommand('enable') + "\n" )
        
        while enabled != 1:
            self._debuglog( "Trying to match:\n\t" + "\n\t".join(matches) )
            result = self._conn.expect( matches, self._timeout )
            
            if result[0] == 0:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                self._debuglog( "Found a rommon prompt: not enabled, but we can stop trying." )
                enabled  = 1
            
            elif result[0] == 1:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )

                if sentEnablePass:
                    if sentExtraNewline:
                        self._debuglog( "Still facing a password prompt. Enable Failed" )
                        self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                        raise RuntimeError, LoginFailedException
                    else:
                        self._debuglog( "Still facing a password prompt. Extra Newline ?" )
                        self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                        self._conn.write("\n")
                        sentExtraNewline = 1
                self._debuglog( "Found password prompt. Sending Enable Pass" )
                self._conn.write( inPass + "\n" )
                sentEnablePass = 1
            
            elif result[0] == 3:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                if sentEnablePass:
                    self._debuglog( "Still facing a not-enabled prompt. Enable Failed" )
                    self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                    raise RuntimeError, LoginFailedException
                self._debuglog( "Found a not-enabled prompt. Sending Enable" )
                self._conn.write( self._device.getCommand('enable') + "\n" )
                sentEnable = 1
            
            elif result[0] == 2:
                self._debuglog( "Matched: [" +  str(result[0]) + "]: " + matches[result[0]] )
                self._debuglog( "Found an enabled cmd prompt: We are enabled" )
                enabled  = 1
           
            elif result[0] == -1:
                self._debuglog( "Matched: [" +  str(result[0]) + "].")
                if sentWakeup:
                    self._debuglog( "Still no command or password prompt. Quitting" )
                    self._debuglog( "matched [" + str(result[0]) + "]:" + result[2] )
                    raise RuntimeError, LoginFailedException
                self._debuglog( "Found no command or password prompt. Trying to wakeup the device with CRLF." )
                self.wakeup()
                sentWakeup = 1
            
    def disable( self ):
        """ Take the connection out of 'superuser' mode """
        
        self.cmd( self._device.getCommand('disable') )

        # Make sure we disabled
        if self.isEnabled():
            raise DisableFailedException

    def isEnabled( self ):
        """ Returns true if the connection is in 'superuser' mode """
        
        self._debuglog( "Trying to match " + self._device.getPrompt( 'enabledIndicator' ) \
            + " in " + self._lastPrompt )
        exp = re.compile( self._device.getPrompt( 'enabledIndicator' ) )
        if exp.search( self._lastPrompt ) == None:
            return 0
        else:
            return 1

    def isLoggedIn( self ):
        """ Returns true if the connection is already logged in """
    
        exp = re.compile( self._device.getPrompt( 'command' ) )
        if exp.search( self._lastPrompt ) == None:
            return 0
        else:
            return 1