def handle(self, command): """ Handle authentication: If the connection is not yet authenticated, start PAM authentication and handle challenge-response through AUTHENTICATION packets. Returns None on success, Response_AUTHENTICATION on further negotiation and Response_ERROR on failure.""" if self.state == PamAuthenticator.AUTH_OK: return None if self.state == PamAuthenticator.AUTH_FAIL: return self.res self.challenge_pending.clear() if self.state == PamAuthenticator.AUTH_INIT: self.state = PamAuthenticator.AUTH_RUNNING self.thread.start() else: # self.state == PamAuthenticator.AUTH_RUNNING: if not isinstance(command, protocol.Request_AUTHENTICATION): logger.warn('Authentication protocol violated: %s' % (command,)) # terminate thread self.state = PamAuthenticator.AUTH_FAIL self.response = None self.response_pending.set() self.thread.join() self.res = protocol.Response_ERROR() self.res.translatable_text = _('Authentication protocol violated') return self.res self.response = command.response self.response_pending.set() self.challenge_pending.wait(PamAuthenticator.TIMEOUT) if self.res is None: self.thread.join() return self.res
def handle_command(self, command): """Handle command packet.""" logger.info('[%d] Request "%s" received' % (self.client_id, command.command,)) try: cmd = commands[command.command] except KeyError, e: logger.warning('[%d] Unknown command "%s": %s.' % (self.client_id, command.command,str(e))) res = protocol.Response_ERROR() res.translatable_text = '[%(id)d] Unknown command "%(command)s".' res.values = { 'id': self.client_id, 'command': command.command, }
def handle_command(self, command): """Handle command packet.""" logger.info('[%d] Request "%s" received' % ( self.client_id, command.command, )) try: cmd = commands[command.command] except KeyError as e: logger.warning('[%d] Unknown command "%s": %s.' % (self.client_id, command.command, str(e))) res = protocol.Response_ERROR() res.translatable_text = '[%(id)d] Unknown command "%(command)s".' res.values = { 'id': self.client_id, 'command': command.command, } else: try: res = cmd(self, command) if res is None: res = protocol.Response_OK() except CommandError as e: logger.warning('[%d] Error doing command "%s": %s' % (self.client_id, command.command, e)) res = protocol.Response_ERROR() res.translatable_text, res.values = e.args except Exception as e: logger.error('[%d] Exception: %s' % (self.client_id, traceback.format_exc())) res = protocol.Response_ERROR() res.translatable_text = _('Exception: %(exception)s') res.values = { 'exception': str(e), } return res
def run(self): """Thread doing PAM authentication.""" try: try: auth = PAM.pam() auth.start(PamAuthenticator.PAM_SERVICE) auth.set_item(PAM.PAM_RHOST, self.client_address) auth.set_item(PAM.PAM_CONV, self.pam_conv) auth.setUserData(self) auth.authenticate() auth.acct_mgmt() del auth # signal success logger.info('Authentication succeeded') self.state = PamAuthenticator.AUTH_OK self.res = None except Exception, e: logger.error('Authentication failed: %s' % e) self.state = PamAuthenticator.AUTH_FAIL self.res = protocol.Response_ERROR() self.res.translatable_text = _('Authentication failed') finally: self.challenge_pending.set()
def handle(self): """Handle protocol.""" try: self.eos = False buffer = '' while not self.eos: try: data = self.request.recv(1024) except socket.error as (err, errmsg): if err == errno.EINTR: continue else: raise logger.debug('[%d] Data recveived: %d' % (self.client_id, len(data))) if data == '': self.eos = True else: buffer += data try: packet = protocol.Packet.parse(buffer) if packet is None: continue # waiting except protocol.PacketError as e: # (translatable_text, dict): logger.warning("[%d] Invalid packet received: %s" % (self.client_id, e)) if logger.isEnabledFor(logging.DEBUG): logger.debug("[%d] Dump: %r" % (self.client_id, data)) break logger.debug('[%d] Received packet.' % (self.client_id, )) (length, command) = packet buffer = buffer[length:] if isinstance(command, protocol.Request): res = self.handle_command(command) else: logger.warning('[%d] Packet is no UVMM Request. Ignored.' % (self.client_id, )) res = protocol.Response_ERROR() res.translatable_text = _( 'Packet is no UVMM Request: %(type)s') res.values = { 'type': type(command), } logger.debug('[%d] Sending response.' % (self.client_id, )) packet = res.pack() self.wfile.write(packet) self.wfile.flush() logger.debug('[%d] Done.' % (self.client_id, )) except EOFError: pass except socket.error as (err, errmsg): if err != errno.ECONNRESET: logger.error('[%d] Exception: %s' % (self.client_id, traceback.format_exc())) raise else: logger.warn('[%d] NetException: %s' % (self.client_id, traceback.format_exc()))
continue # waiting except protocol.PacketError, e: # (translatable_text, dict): logger.warning("[%d] Invalid packet received: %s" % (self.client_id, e)) if logger.isEnabledFor(logging.DEBUG): logger.debug("[%d] Dump: %r" % (self.client_id, data)) break logger.debug('[%d] Received packet.' % (self.client_id,)) (length, command) = packet buffer = buffer[length:] if isinstance(command, protocol.Request): res = self.handle_command(command) else: logger.warning('[%d] Packet is no UVMM Request. Ignored.' % (self.client_id,)) res = protocol.Response_ERROR() res.translatable_text = _('Packet is no UVMM Request: %(type)s') res.values = { 'type': type(command), } logger.debug('[%d] Sending response.' % (self.client_id,)) packet = res.pack() self.wfile.write(packet) self.wfile.flush() logger.debug('[%d] Done.' % (self.client_id,)) except EOFError: pass except socket.error, (err, errmsg): if err != errno.ECONNRESET: logger.error('[%d] Exception: %s' % (self.client_id, traceback.format_exc()))