コード例 #1
0
    def sendMsgToStorage(cmd):
        '''Forwarder of messages to storage'''
        log.debug("In sendMsgToStorage - cmd: {0}".format(cmd))
        try:
            if not util.connLock.acquire(True, 5):
                raise IKException(
                    ErrorCode.operationFailed,
                    "Failed to acquire the lock for connecting to storage.")

            log.debug("Sending...")
            connHere.send(cmd)
            log.debug("Sent. Receiving...")
            if connHere.poll(15):
                ret = connHere.recv()
                log.debug("In sendMsgToStorage - ret: {0}".format(ret))
            else:
                ret = composeResponse(
                    "0", "Socket timed out or no data to receive.")
                log.debug("Nothing to receive")

            util.connLock.release()
        except Exception as e:
            ret = composeResponse("0", str(e))
            log.error(
                "In sendMsgToStorage exception received: {0}".format(ret))

        return ret
コード例 #2
0
ファイル: serv.py プロジェクト: al-berger/regd
	def accept(self, sock, mask):
		try:
			connection, client_address = sock.accept()
		except Exception as e:
			log.error( "Exception occured: ", e )
			return

		mp.Process( target = self.handle_connection, name = "RegdConnectionHandler",
							args = ( connection, client_address, util.connLock ) ).start()
コード例 #3
0
ファイル: serv.py プロジェクト: al-berger/regd
	def loop( self, sock ):
		self.cont = True
		self.exitcode = 0

		while app.glCont:
			events = self.sel.select( 30 )
			for key, mask in events:
				callback = key.data
				callback(key.fileobj, mask)
			
			if 0 : # not os.path.exists( self.sockfile ):
				log.error( "Socket file {0} is gone. Exiting.".format( self.sockfile ) )
				#exit( 1 )
				return
			else:
				continue
コード例 #4
0
def startRegistry(servername,
                  sockfile=None,
                  host=None,
                  port=None,
                  acc=defs.PL_PRIVATE,
                  datafile=None,
                  binsecfile=None):
    srv = connStor = None

    def shutdown():
        log.info("Registry is shutting down...")
        cmds.CmdSwitcher.switchCmd({"cmd": fs.FS_STOP})
        log.info("Shutdown complete.")

    def signal_handler(signal, frame):
        #shutdown()
        # Returning normally, so that the signal notification be forwarded to
        # the wakeup socket.
        return

    sigHandler.push(signal.SIGINT, signal_handler)
    sigHandler.push(signal.SIGTERM, signal_handler)
    sigHandler.push(signal.SIGHUP, signal_handler)
    sigHandler.push(signal.SIGABRT, signal_handler)
    sigHandler.push(signal.SIGALRM, signal_handler)

    try:
        # Storage
        log.debug("Creating storage")
        connStor, sigStor = fs.startStorage(acc, datafile, binsecfile)
        # Server
        log.debug("Creating server instance")
        srv = serv.RegdServer(servername, sockfile, host, port, acc)
        # Info
        log.debug("Creating info")
        info.Info()
        log.debug("Starting server")
        srv.start_loop(sigStor)
    except Exception as e:
        log.error("Failed to start server: {0}".format(e))
    else:
        #glSignal.acquire()
        # Wait till notification on df.SERVER_STOP
        #glSignal.wait()
        shutdown()
        log.info("Exiting.")
コード例 #5
0
    def start_loop(conn, sigConn, acc, datafile, binsectfile):
        '''Create FS instance and start loop'''
        util.setLog("DEBUG")
        fs = FS(conn, acc, datafile, binsectfile)
        log.info("Starting listening for messages...")
        try:
            fs.listenForMessages(fs.serialize)
        except Exception as e:
            log.error("Exception received: {0}".format(e))
            #fs.conn.shutdown(SHUT_RDWR)
        conn.close()
        sigConn.send("Exception in storage".encode())
        sigConn.shutdown(SHUT_RDWR)
        sigConn.close()

        log.info("Ended listening for messages. Quitting...")
        return 0
コード例 #6
0
	def listenForMessages(self, func):
		while self.cont:
			if self.conn.poll(30):
				try:
					cmd = self.conn.recv()
					try:
						resp = self.processCmd( cmd )
					except IKException as e:
						resp = util.composeResponse( "0", "In listenForMessages - exception received: {0}. Continue listening...".format( e ) )
						log.error( resp  )
					self.conn.send( resp )
				except Exception as e:
					fh = io.StringIO()
					traceback.print_exc( file=fh )
					log.error( "In listenForMessages - fatal exception received: {0}. Quit listening...".format( fh.getvalue() ) )
					raise
			else:
				func()
コード例 #7
0
ファイル: serv.py プロジェクト: al-berger/regd
	def handle_connection( self, *args ):
		'''Exceptions-catcher wrapper'''
		connection = args[0]
		client_address = args[1]
		storage_lock = args[2]
		try:
			self._handle_connection( connection, client_address, storage_lock )
		except IKException as e:
			log.error( ( "Exception while handling connection."
						"Client: %s ; Exception: %s" ) % ( client_address, e ) )

		except Exception as e:
			log.error( "Exception in connection handler: %s" % ( e ) )
			self.sigsock_w.send("stop".encode())

		finally:
			connection.shutdown( socket.SHUT_RDWR )
			connection.close()
コード例 #8
0
    def read_sec_file(self, filename=None, cmd=None, addMode=df.noOverwrite):
        '''Read secure tokens from a file with a user command'''
        if not filename:
            filename = self.encFile

        if not os.path.exists(filename):
            log.error("Cannot find encrypted data file. Exiting.")
            raise IKException(ErrorCode.operationFailed, "File not found.")

        try:
            if not cmd:
                cmd = self.secTokCmd.replace("FILENAME",
                                             "{0}").format(filename)
            ftxt = "Calling read private file command..."
            ftxt = subprocess.check_output(cmd,
                                           shell=True,
                                           stderr=subprocess.DEVNULL)
        except subprocess.CalledProcessError as e:
            log.error(e.output.decode() + "; " + ftxt)
            raise IKException(ErrorCode.operationFailed, e.output)

        fh = io.BytesIO(ftxt)
        fh.name = "BytesIO:" + filename
        self.fs.readFromFile(fh=fh, dest="/ses", addMode=addMode)
コード例 #9
0
ファイル: serv.py プロジェクト: al-berger/regd
	def _handle_connection( self, connection, client_address, storage_lock ):
		'''Connection handler'''
		if not self.host:
			creds = connection.getsockopt( socket.SOL_SOCKET, socket.SO_PEERCRED,
									struct.calcsize( "3i" ) )
			pid, uid, gid = struct.unpack( "3i", creds )
			log.debug( "new connection: pid: {0}; uid: {1}; gid: {2}".format( pid, uid, gid ) )
		else:
			log.debug( "new connection: client address: %s" % ( str( client_address ) ) )

		connection.settimeout( 5 )

		data = bytearray()
		util.recvPack( connection, data )
		bytesReceived = len( data )

		log.debug( "data: %s" % ( data[:1000] ) )
		data = data[10:]  # .decode( 'utf-8' )

		bresp = bytearray()
		cmd = None
		perm = False
		# dcmd - command dictionary. Contains three fields:
		# cmd - command name, received from client
		# params - command parameters, received from client
		# res - internal command processing result, set by the command processor or
		# command handler. This result has the server semantics, rather than the
		# command semantics: if it's 0 - this means a general program error, e.g.
		# non-existing command name. It's meant to be handled by the server before
		# sending response to the client.
		
		try:
			dcmd = util.parsePacket( data )
			# 'internal' switch is only used within regd server
			if "internal" in dcmd:
				raise Exception("Unrecognized syntax.")
			cmd = dcmd["cmd"]
			log.debug( "command received: {0}".format( cmd ) )
		except Exception as e:
			bresp = composeResponse( "0", "Exception while parsing the command: " + str( e ) )
		else:
			# Check permission and persistency
			
			if self.host:
				# IP-based server
				if not self.trustedIps:
					perm = True
				else :
					try:
						clientIp = ipaddress.IPv4Address( client_address[0] )
					except ValueError:
						log.error( "Client IP address format is not recognized." )
					else:
						for i in self.trustedIps:
							if clientIp in i:
								perm = True
								log.debug( "Client IP is trusted." )
								break
						if not perm:
							log.error( "Client IP is NOT trusted : '%s : %s" %
									( client_address[0], client_address[1] ) )
			else:
				# File socket server
				if self.useruid == uid:
					perm = True
				elif uid in self.trustedUserids:
					perm = True
				elif cmd not in defs.secure_cmds:
					if self.acc == defs.PL_PUBLIC:
						perm = True
					elif self.acc == defs.PL_PUBLIC_READ:
						if cmd in defs.pubread_cmds:
							perm = True
			log.debug( "perm: {0}".format( perm ) )
			if not perm:
				bresp = composeResponse( "0", str( IKException( ErrorCode.permissionDenied, cmd ) ) )
			#elif not self.datafile and defs.PERS in cmd:
			#	bresp = composeResponse( "0", str( IKException( ErrorCode.operationFailed, None, "Persistent tokens are not enabled." ) ) )
		
		if not len( bresp ):
			util.connLock = storage_lock
			bresp = CmdSwitcher.handleCmd( dcmd )

		try:
			bytesSent = util.sendPack( connection, bresp )
		except OSError as er:
			log.error( "Socket error {0}: {1}\nClient address: {2}\n".format( 
							er.errno, er.strerror, client_address ) )
		else: 
			if type( bytesSent ) is int:
				info.setShared( "bytesReceived", bytesReceived, defs.SUM )
				info.setShared( "bytesSent", bytesSent, defs.SUM )

		if cmd == defs.STOP_SERVER and perm:
			self.sigsock_w.send("stop".encode())

		return
コード例 #10
0
ファイル: serv.py プロジェクト: al-berger/regd
	def start_loop( self, sigStor ):
		'''Start loop.'''

		# Check for the previous instance

		if not self.host and os.path.exists( self.sockfile ):
			log.info( "Socket file for a server with name already exists. Checking for the server process." )
			'''Socket file may remain after an unclean exit. Check if another server is running.'''
			try:
				# If the server is restarted, give the previous instance time to exit cleanly.
				time.sleep( 2 )
				if self.servername and self.servername != "regd":
					s = "ps -ef | grep '{0}(/cli.py)? start .*{1} {2}' | grep -v grep".format( 
												app.APPNAME,
												app.clp( defs.SERVER_NAME ),
												self.servername )
				else:
					s = "ps -ef | grep -E '{0}(/cli.py)? start' | grep -v '{1}' | grep -v grep".format( 
												app.APPNAME,
												app.clc( defs.SERVER_NAME ) )


				res = subprocess.check_output( s, shell = True ).decode( 'utf-8' )

			except subprocess.CalledProcessError as e:
				if e.returncode != 1:
					log.error( "Check for already running server instance failed: {0} ".format( e.output ) )
					return -1
				else:
					res = ""

			if len( res ):
				# TODO
				if res.count( "\n" ) > 2:
					'''Server is already running.'''
					log.warning( "Server is already running:\n{0}".format( res ) )
					return 1
			log.info( "Server process is not found. Unlinking the existing socket file." )
			try:
				os.unlink( self.sockfile )
			except OSError:
				if os.path.exists( self.sockfile ):
					raise

		self.useruid = os.getuid()
		if self.host:
			log.info( "Starting regd server. useruid: {0} ; host: {1} ; port: {2}.".format( 
															self.useruid, self.host, self.port ) )
		else:
			log.info( "Starting regd server. useruid: {0} ; sockfile: {1} ; servername: {2}.".format( 
												self.useruid, self.sockfile, self.servername ) )
		self.info["time_started"] = str( datetime.datetime.now() ).rpartition( "." )[0]
		
		# Set up sockets
		try:
			if self.host:
				self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
				self.sock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
				self.sock.bind( ( self.host, int( self.port ) ) )
				with open( self.sockfile, "w" ) as f:
					f.write( '' )

			else:
				self.sock = socket.socket( socket.AF_UNIX, socket.SOCK_STREAM )
				self.sock.bind( self.sockfile )
				os.chmod( self.sockfile, mode = 0o777 )

		except OSError as e:
			log.error( "Cannot create or bind socket: %s" % ( e ) )
			return -1

		self.sock.listen( 1 )
		self.sock.settimeout( 30 )
		self.sel = selectors.DefaultSelector()
		self.sigsock_r, self.sigsock_w = socket.socketpair()
		self.sigsock_r.setblocking( False )
		self.sigsock_w.setblocking( False )
		os.set_inheritable( self.sigsock_w.fileno(), True )
		self.sock.setblocking( False )
		signal.set_wakeup_fd( self.sigsock_w.fileno() )
		self.sel.register( self.sock, selectors.EVENT_READ, self.accept )
		self.sel.register( self.sigsock_r, selectors.EVENT_READ, self.stop )
		self.sel.register( sigStor, selectors.EVENT_READ, self.stop )
		self.loop( self.sock, )
コード例 #11
0
    def __init__(self, conn, acc, datafile, binsecfile=None):
        super(FS, self).__init__(conn)

        self.acc = acc
        self.datafile = datafile
        self.binsecfile = binsecfile
        self.info = {}
        self.cont = True

        self.fs = getstor(rootStor=None, mode=0o555)

        self.tokens = getstor(rootStor=None, mode=0o777)
        self.bintokens = getstor(rootStor=None, mode=0o777)
        self.systokens = getstor(rootStor=None, mode=0o600)

        self.fs[''] = getstor(rootStor=None, mode=0o555)
        self.fs[''][SESNAME] = self.tokens
        self.fs[''][SYSNAME] = self.systokens
        self.fs[''][BINNAME] = self.bintokens

        if self.binsecfile:
            self.fs.setItemAttr(BINPATH, ("{0}={1}".format(
                stor.SItem.persPathAttrName, self.binsecfile), ))

        self.tokens.rootStor = self.tokens
        self.bintokens.rootStor = self.bintokens
        self.systokens.rootStor = self.systokens

        self.useruid = None

        # Default encrypted file name
        self.encFile = app.homedir + "/.sec/safestor.gpg"
        # Flag showing whether the default enc. file has been read
        self.defencread = False
        # Command line command for reading encrypted file
        self.secTokCmd = df.READ_ENCFILE_CMD

        if self.datafile:
            # Persistent tokens
            self.perstokens = getstor(rootStor=None, mode=0o777)
            self.fs[''][PERSNAME] = self.perstokens
            self.fs.setItemAttr(PERSPATH, ("{0}={1}".format(
                stor.SItem.persPathAttrName, self.datafile), ))
            self.perstokens.rootStor = self.perstokens

            try:
                fhd = {'cur': None}
                stor.treeLoad = True
                self.fs[''][PERSNAME].serialize(fhd, read=True)
                stor.treeLoad = False
                for v in fhd.values():
                    if v: v.close()
                # read_locked( self.data_fd, self.perstokens, defs.overwrite )
                # self.data_fd.close()
            except IKException as e:
                log.error("Cannot read the data file: %s" % (str(e)))
                raise IKException(ErrorCode.operationFailed)
        else:
            print(
                "Server's data file is not specified. Persistent tokens are not enabled."
            )

        if self.binsecfile:
            try:
                fhd = {'cur': None}
                stor.treeLoad = True
                self.fs[''][BINNAME].serialize(fhd, read=True)
                stor.treeLoad = False
                for v in fhd.values():
                    if v: v.close()
            except IKException as e:
                log.error("Cannot read the bin_section file: %s" % (str(e)))
                raise IKException(ErrorCode.operationFailed)

        d = {}
        app.read_conf(d)

        if "encfile" in d:
            self.encFile = d["encfile"]
        if "encfile_read_cmd" in d:
            self.secTokCmd = d["encfile_read_cmd"]

        # Storing shared info
        self.fs[''][SYSNAME]["dataFile"] = self.datafile