def sendData(self, tpl=None, dataRaw=None): """ Send ssh data @param tpl: ssh template data (default=None) @type tpl: templatelayer/none @param dataRaw: ssh data (default=None) @type dataRaw: string/none @return: an event matching with the template or None otherwise @rtype: templatemessage """ if self.sshTranport is None: return if not self.sshTranport.is_authenticated(): self.debug( 'not authenticated' ) return if not self.connected: self.debug( "not connected" ) return # log event if self.logEventSent: if dataRaw is not None: ssh_tpl = templates.data_sent(data=dataRaw) else: ssh_tpl = tpl tpl_final = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=ssh_tpl ) else: tpl_final = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.data_sent() ) data = dataRaw if dataRaw is None: data = tpl.get('data') self.debug( data ) if data is None: return if self.logEventSent: tpl_final.addRaw(raw=data) self.logSentEvent( shortEvt = "data", tplEvt = tpl_final ) if self.cfg['agent-support']: remote_cfg = { 'cmd': 'send-data', 'data': data } self.sendNotifyToAgent(data=remote_cfg) else: try: self.sshChannel.send(data) except Exception as e: self.error("unable to send data through ssh: %s" % str(e) ) return tpl_final
def sendData(self, data, to=None): """ Send data over the udp protocol @param data: data to send over udp @type data: string @param to: address of destination (ip,port) @type to: tuple/none @return: udp layer encapsulate in ip, return False on error @rtype: templatemessage """ try: #self.debug( "data to sent (bytes %s) to %s" % (len(data), to) ) if not self.islistening: self.debug( "not listening" ) return False # prepare destination address addr = (self.cfg['dst-ip'], self.cfg['dst-port']) if to is not None: addr = to self.cfg['dst-ip'] = addr[0] self.cfg['dst-port'] = addr[1] # add the separator to the end of the data, if the feature is enabled pdu = self.addSeparator( data=data ) # log event pdu_size = len(pdu) if self.logEventSent: tpl = self.encapsule( ip_event=AdapterIP.sent(), udp_event=templates.sent(data=pdu, data_length=str(pdu_size)) ) else: tpl = self.encapsule( ip_event=AdapterIP.sent(), udp_event=templates.sent( data_length=str(pdu_size) ) ) if self.logEventSent: tpl.addRaw(raw=pdu) self.logSentEvent( shortEvt = "data", tplEvt = tpl ) if self.cfg['agent-support']: data = { 'cmd': 'send-data', 'pdu': pdu, 'addr': addr} self.sendNotifyToAgent(data=data) else: # send the packet self.socket.sendto(pdu, addr) self.debug( "data sent (bytes %s)" % len(pdu) ) return tpl except Exception as e: self.error('Unable to send data: %s' % str(e)) return False
def stopListening(self): """ Stop listening """ self.__mutex__.acquire() if self.islistening: self.debug( 'stopping to listen' ) # log event self.islistening = False tpl = self.encapsule( ip_event=AdapterIP.sent(), udp_event=templates.stopping() ) self.logSentEvent( shortEvt = "stopping", tplEvt = tpl ) if self.cfg['agent-support']: self.cleanSocket() # cleanup remote agent #self.resetAgent() remote_cfg = {'cmd': 'disconnect'} self.sendNotifyToAgent(data=remote_cfg) else: # clean socket self.cleanSocket() # dispatch self.onStopListening() self.__mutex__.release()
def openSession(self): """ Open a ssh session """ if self.sshTranport is None: return if not self.sshTranport.is_authenticated(): self.debug( 'not authenticated' ) return # log event if self.sftpSupport: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.open_channel() ) self.logSentEvent( shortEvt = "open sftp channel", tplEvt = tpl ) else: if self.logEventSent: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.open_channel() ) self.logSentEvent( shortEvt = "open channel", tplEvt = tpl ) if self.cfg['agent-support']: remote_cfg = { 'cmd': 'open-session', 'sftp-support': self.sftpSupport, 'terminal-type': self.cfg['terminal-type'], 'terminal-width': self.cfg['terminal-width'] , 'terminal-height': self.cfg['terminal-height']} self.sendNotifyToAgent(data=remote_cfg) else: try: if self.sftpSupport: self.sshChannel = self.sshTranport.open_sftp_client() else: self.sshChannel = self.sshTranport.open_session() self.sshChannel.get_pty(term=self.cfg['terminal-type'], width=self.cfg['terminal-width'] , height =self.cfg['terminal-height'] ) self.sshChannel.invoke_shell() self.sshChannel.settimeout(0.0) except Exception as e: #self.debug( e ) if self.sftpSupport: self.__onSftpFailed(err="%s" % e ) else: self.onChannelOpeningFailed(err="%s" % e) # channel opened else: if self.sftpSupport: self.__onSftpOpened() else: self.onChannelOpened()
def __onSftpOpened(self): """ to reimplement """ self.sftpOpened = True # log event tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.open_channel_ok() ) self.logRecvEvent( shortEvt = "sftp channel opened", tplEvt = tpl ) self.onSftpOpened()
def onAuthenticationOk(self): """ On authentication ok """ # log event if self.logEventReceived: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.authentication_ok() ) self.logRecvEvent( shortEvt = "authenticated", tplEvt = tpl ) # open session self.openSession()
def authentication(self): """ authentication ssh with login and password """ if self.sshTranport is None: self.debug( 'negotiation todo before' ) return # log event if self.logEventSent: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.authentication() ) self.logSentEvent( shortEvt = "authentication", tplEvt = tpl ) if self.cfg['agent-support']: remote_cfg = { 'cmd': 'authentication', 'login': self.cfg['login'], 'password': self.cfg['password'] } if self.cfg['private-key'] is not None: remote_cfg['private-key'] = self.cfg['private-key'] else: remote_cfg['private-key'] = '' self.sendNotifyToAgent(data=remote_cfg) else: try: if self.cfg['private-key'] is not None or self.cfg['private-key-path'] is not None : key = self.sshTranport.get_remote_server_key() if self.cfg['private-key-path'] is not None: f = open(self.cfg['private-key-path'], 'r') self.cfg['private-key'] = f.read() f.close() # read first line of the private key to detect the type key_head=self.cfg['private-key'].splitlines()[0] if 'DSA' in key_head: keytype=paramiko.DSSKey elif 'RSA' in key_head: keytype=paramiko.RSAKey else: raise Exception("Invalid key type: %s" % key_head) # construct the key keyfile = io.StringIO( unicode(self.cfg['private-key']) ) pkey=keytype.from_private_key(keyfile) # try to make the authen self.sshTranport.auth_publickey(self.cfg['login'], pkey) else: self.sshTranport.auth_password(self.cfg['login'], self.cfg['password']) except Exception as e: #self.debug( e ) self.onAuthenticationFailed(err="%s" % e ) # authen ok else: self.onAuthenticationOk()
def onNegotiationOk(self): """ On negotiation ok """ # log event if self.logEventReceived: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.negotiation_ok() ) self.logRecvEvent( shortEvt = "negotiated", tplEvt = tpl ) # auth with password self.authentication()
def stopSending(self): """ Stop sending rtp. """ self.debug('stop sending rtp') if self.sendingThread: if self.sendingThread.isSending(): self.sendingThread.unsetSending() self.sendingThread.stop() lower = self.udp.encapsule(ip_event=AdapterIP.sent(), udp_event=AdapterUDP.sent()) self.onStopSending(lower=lower)
def onChannelOpened(self): """ On channel opened """ self.channelOpened = True # log event if self.logEventReceived: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.open_channel_ok() ) self.logRecvEvent( shortEvt = "channel opened", tplEvt = tpl ) # begin to run self.setRunning()
def onChannelOpeningFailed(self, err=""): """ On channel opening failed """ # log event if self.logEventReceived: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.authentication_failed(err=err) ) self.logRecvEvent( shortEvt = "open channel failed", tplEvt = tpl ) # close transport if self.sshTranport is not None: self.sshTranport.close() self.sshTranport = None self.sshChannel = None
def startListening(self): """ Start listening """ if self.islistening: self.debug('already listening') return # Start the tcp connection self.debug('starting to listen') # log event tpl = self.encapsule(ip_event=AdapterIP.sent(), udp_event=templates.starting()) self.logSentEvent(shortEvt="starting", tplEvt=tpl) self.__mutex__.acquire() try: # set the socket version if self.cfg['sock-family'] == AdapterIP.IPv4: sockType = TestAdapterLib.INIT_DGRAM_SOCKET elif self.cfg['sock-family'] == AdapterIP.IPv6: sockType = TestAdapterLib.INIT6_DGRAM_SOCKET else: raise Exception('socket family unknown: %s' % str(self.cfg['socket-family'])) # Create the socket self.socket = TestAdapterLib.getSocket(sockType=sockType) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.debug('bind socket on %s:%s' % (self.cfg['bind-ip'], self.cfg['bind-port'])) self.socket.bind((self.cfg['bind-ip'], self.cfg['bind-port'])) # listening successful self.__setSource() # dispatch self.lastActivity = time.time() self.islistening = True self.onStartListening() # start thread self.setRunning() except socket.error as e: self.onStartListeningFailed(e) except Exception as e: self.error("start listen error: %s" % str(e)) self.stopListening() self.__mutex__.release()
def __onSftpFailed(self, err=""): """ to reimplement """ # log event tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.authentication_failed(err=err) ) self.logRecvEvent( shortEvt = "open sftp channel failed", tplEvt = tpl ) # close transport if self.sshTranport is not None: self.sshTranport.close() self.sshTranport = None self.sshChannel = None self.onSftpFailed()
def onAuthenticationFailed(self, err=""): """ On authentication failed """ # log event if self.logEventReceived: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.authentication_failed(err=err) ) self.logRecvEvent( shortEvt = "authentication failed", tplEvt = tpl ) # close transport if self.sshTranport is not None: self.sshTranport.close() self.sshTranport = None self.connected = False self.handleConnectionFailed(err=err)
def negotiation(self): """ Start ssh negotiation """ if not self.connected: self.debug( 'tcp not connected' ) return # log event if self.logEventSent: tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.negotiation() ) self.logSentEvent( shortEvt = "negotiation", tplEvt = tpl ) if self.cfg['agent-support']: remote_cfg = { 'cmd': 'negotiation'} self.sendNotifyToAgent(data=remote_cfg) else: t = threading.Thread(target=self.__negotiation) t.start()
def stopListening(self): """ Stop listening """ self.__mutex__.acquire() if self.islistening: self.debug('stopping to listen') # log event self.islistening = False tpl = self.encapsule(ip_event=AdapterIP.sent(), udp_event=templates.stopping()) self.logSentEvent(shortEvt="stopping", tplEvt=tpl) # clean socket self.cleanSocket() # dispatch self.onStopListening() self.__mutex__.release()
def disconnect(self): """ Close the TCP connection """ self.__mutex__.acquire() if self.connected: self.debug( 'disconnection started' ) # log event tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.disconnection() ) if self.logEventSent: self.logSentEvent( shortEvt = "disconnection", tplEvt = tpl ) if self.cfg['agent-support']: self.unsetRunning() remote_cfg = {'cmd': 'disconnect'} self.sendNotifyToAgent(data=remote_cfg) self.debug( 'reset sent to agent' ) else: self.cleanSocket() self.onDisconnection() return tpl self.__mutex__.release()
def startListening(self): """ Start listening """ if self.islistening: self.debug( 'already listening' ) return # Optional: resolve destination hostname if self.cfg['dst-host'] != '': self.cfg['dst-ip'] = self.dns.resolveHost(host=self.cfg['dst-host']) if not len(self.cfg['dst-ip']): return # Start the tcp connection self.debug( 'starting to listen' ) # log event tpl = self.encapsule( ip_event=AdapterIP.sent(), udp_event=templates.starting() ) self.logSentEvent( shortEvt = "starting", tplEvt = tpl ) if self.cfg['agent-support']: remote_cfg = { 'cmd': 'connect', 'sock-type': 'udp', 'bind-ip': self.cfg['bind-ip'], 'bind-port': self.cfg['bind-port'], 'sock-family': self.cfg['sock-family'], 'dst-ip': self.cfg['dst-ip'], 'dst-port':self.cfg['dst-port'], } self.sendNotifyToAgent(data=remote_cfg) # start thread self.lastActivity = time.time() self.setRunning() else: self.__mutex__.acquire() try: # set the socket version if self.cfg['sock-family'] == AdapterIP.IPv4: sockType = TestAdapterLib.INIT_DGRAM_SOCKET elif self.cfg['sock-family'] == AdapterIP.IPv6: sockType = TestAdapterLib.INIT6_DGRAM_SOCKET else: raise Exception('socket family unknown: %s' % str(self.cfg['socket-family']) ) # Create the socket self.socket = TestAdapterLib.getSocket(sockType=sockType) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.debug( 'bind socket on %s:%s' % (self.cfg['bind-ip'], self.cfg['bind-port']) ) self.socket.bind( (self.cfg['bind-ip'], self.cfg['bind-port']) ) # listening successful self.__setSource() # dispatch self.lastActivity = time.time() self.islistening = True self.onStartListening() # start thread self.setRunning() except socket.error as e: self.onStartListeningFailed(e) except Exception as e: self.error( "start listen error: %s" % str(e) ) self.stopListening() self.__mutex__.release()
def connect(self): """ Start the TCP connection """ if self.connected: self.debug( 'already connected' ) return # Optional: resolve hostname if self.cfg['dst-host'] != '': self.cfg['dst-ip'] = self.dns.resolveHost(host=self.cfg['dst-host']) if not len(self.cfg['dst-ip']): return # Start the tcp connection self.debug( 'connection started' ) # log event tpl = self.encapsule( ip_event=AdapterIP.sent(), ssh_event=templates.connection() ) if self.logEventSent: self.logSentEvent( shortEvt = "connection", tplEvt = tpl ) if self.cfg['agent-support']: remote_cfg = { 'cmd': 'connect', 'bind-ip': self.cfg['bind-ip'], 'bind-port': self.cfg['bind-port'], 'sock-timeout': self.cfg['sock-timeout'], 'tcp-keepalive': self.cfg['tcp-keepalive'], 'tcp-keepalive-interval': self.cfg['tcp-keepalive-interval'] , 'sock-family': self.cfg['sock-family'], 'dst-ip': self.cfg['dst-ip'], 'dst-port':self.cfg['dst-port'], 'shared': self.isShared() } self.sendNotifyToAgent(data=remote_cfg) else: try: # set the socket version if self.cfg['sock-family'] == AdapterIP.IPv4: sockType = TestAdapterLib.INIT_STREAM_SOCKET elif self.cfg['sock-family'] == AdapterIP.IPv6: sockType = TestAdapterLib.INIT6_STREAM_SOCKET else: raise Exception('socket family unknown: %s' % str(self.cfg['sock-family']) ) # Create the socket self.socket = TestAdapterLib.getSocket(sockType=sockType) self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) if self.cfg['tcp-keepalive']: # active tcp keep alive self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # seconds before sending keepalive probes self.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, self.cfg['tcp-keepalive-interval'] ) # interval in seconds between keepalive probes self.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, self.cfg['tcp-keepalive-interval']) # failed keepalive probes before declaring the other end dead self.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 5) self.socket.settimeout( self.cfg['sock-timeout'] ) self.debug( 'bind socket on %s:%s' % (self.cfg['bind-ip'], self.cfg['bind-port']) ) self.socket.bind( (self.cfg['bind-ip'], self.cfg['bind-port']) ) # Connect the socket self.socket.connect( (self.cfg['dst-ip'], self.cfg['dst-port']) ) # Connection successful self.__setSource() self.connected = True self.onConnection() # start thread self.setRunning() except socket.timeout as e: self.onConnectionTimeout(e) except socket.error as e: (errno, errstr) = e if errno == 111: self.onConnectionRefused() else: self.onConnectionFailed(errno=errno, errstr=errstr) except Exception as e: self.error( "connect error: %s" % str(e) ) self.disconnectTcp() return tpl
def sendData(self, clientId, data): """ Send data over the udp protocol @param clientId: client id number @type clientId: integer/string @param data: data to send over udp @type data: string @return: udp layer encapsulate in ip @rtype: templatemessage """ try: #self.debug( "data to sent (bytes %s) to %s" % (len(data), to) ) if not self.islistening: self.debug("not listening") return # find the client destAddr = None for clientAddress, client in self.clients.items(): if client['id'] == int(clientId): destAddr = clientAddress break if destAddr is None: self.error("client id %s does not exist!" % clientId) return # add the separator to the end of the data, if the feature is enabled if self.cfg['sep-disabled']: pdu = data else: pdu = data + self.cfg['sep-out'] # log event pdu_size = len(pdu) if self.logEventSent: tpl = self.encapsule(ip_event=AdapterIP.sent(), udp_event=templates.sent( data=pdu, data_length=str(pdu_size), id=clientId)) else: tpl = self.encapsule(ip_event=AdapterIP.sent(), udp_event=templates.sent( data_length=str(pdu_size), id=clientId)) if self.logEventSent: tpl.addRaw(raw=pdu) self.logSentEvent(shortEvt="client #%s data" % clientId, tplEvt=tpl) # send the packet self.socket.sendto(pdu, destAddr) self.debug("data sent (bytes %s) for client %s" % (len(pdu), str(destAddr))) return tpl except Exception as e: self.error('Unable to send data: %s to client %s' % (str(e), clientId))