Beispiel #1
0
    def sendRsp(self, trunkId, msgId, rsp):
        if trunkId in self.__runningServersTrunkMap:
            trunk = self.__runningServersTrunkMap[trunkId]
        elif trunkId in self.__runningClientsTrunkMap:
            trunk = self.__runningClientsTrunkMap[trunkId]
        else:
            raise error.SnmpfwdError('Unknown trunk ID %s' % trunkId)

        return trunk.sendRsp(msgId, rsp)
Beispiel #2
0
    def sendReq(self, trunkId, req, cbFun, cbCtx):
        if trunkId in self.__runningServersTrunkMap:
            trunk = self.__runningServersTrunkMap[trunkId]
        elif trunkId in self.__runningClientsTrunkMap:
            trunk = self.__runningClientsTrunkMap[trunkId]
        else:
            raise error.SnmpfwdError('Unknown trunk ID %s' % trunkId)

        return trunk.sendReq(req, cbFun, cbCtx)
Beispiel #3
0
        def __exit__(self, *args):
            if self._olduid is None or self._oldgid is None:
                return

            try:
                os.setegid(self._oldgid)
                os.seteuid(self._olduid)

            except Exception:
                raise error.SnmpfwdError(
                    'setegid()/seteuid() failed for %s/%s: %s' %
                    (self._oldgid, self._olduid, sys.exc_info()[1]))
Beispiel #4
0
    def getAttrValue(self, attr, *nodes, **kwargs):
        scope = nodes
        while scope:
            obj = self.traverse([self.objects], scope)
            if obj and attr in obj:
                expect = kwargs.get('expect')

                if 'vector' in kwargs:
                    if expect:
                        try:
                            return [expect(x) for x in obj[attr]]
                        except Exception:
                            raise error.SnmpfwdError(
                                '%s value casting error at scope "%s" attribute "%s"'
                                % (self, '.'.join(nodes), attr))
                    else:
                        return obj[attr]
                else:
                    if obj[attr]:
                        if expect:
                            try:
                                return expect(obj[attr][0])
                            except Exception:
                                raise error.SnmpfwdError(
                                    '%s value casting error at scope "%s" attribute "%s"'
                                    % (self, '.'.join(nodes), attr))
                        else:
                            return obj[attr][0]
                    else:
                        return ''

            scope = scope[:-1]

        if 'default' in kwargs:
            return kwargs['default']
        else:
            raise error.SnmpfwdError(
                '%s non-existing attribute "%s" at scope "%s"' %
                (self, attr, '.'.join(nodes)))
Beispiel #5
0
    def dropPrivileges(uname, gname):
        if os.getuid() != 0:
            if uname and uname != pwd.getpwnam(uname).pw_name or \
                    gname and gname != grp.getgrnam(gname).gr_name:
                raise error.SnmpfwdError(
                    'Process is running under different UID/GID')
            else:
                return
        else:
            if not uname or not gname:
                raise error.SnmpfwdError(
                    'Must drop priveleges to a non-priveleged user&group')

        try:
            runningUid = pwd.getpwnam(uname).pw_uid
            runningGid = grp.getgrnam(gname).gr_gid
        except Exception:
            raise error.SnmpfwdError(
                'getpwnam()/getgrnam() failed for %s/%s: %s' %
                (uname, gname, sys.exc_info()[1]))

        try:
            os.setgroups([])
        except Exception:
            raise error.SnmpfwdError('setgroups() failed: %s' %
                                     sys.exc_info()[1])

        try:
            os.setgid(runningGid)
            os.setuid(runningUid)
        except Exception:
            raise error.SnmpfwdError(
                'setgid()/setuid() failed for %s/%s: %s' %
                (runningGid, runningUid, sys.exc_info()[1]))

        os.umask(63)  # 0077
Beispiel #6
0
    def getAttrValue(self, attr, *nodes, **kwargs):
        scope = nodes
        while scope:
            obj = self.traverse([self.objects], scope)
            if obj and attr in obj:
                if 'vector' in kwargs:
                    return obj[attr]
                else:
                    return obj[attr] and obj[attr][0] or ''
            scope = scope[:-1]

        if 'default' in kwargs:
            return kwargs['default']
        else:
            raise error.SnmpfwdError(
                '%s non-existing attribute "%s" at scope "%s"' %
                (self, attr, '.'.join(nodes)))
Beispiel #7
0
    def load(self, filename):
        try:
            self.lines = open(filename).readlines()
        except OSError:
            raise error.SnmpfwdError('cant open config file %s: %s' %
                                     (filename, sys.exc_info()[1]))

        self.tokens = []

        while self.lines:
            line = self.lines.pop(0)

            if line and line[0] == '#':
                continue

            tokens = re.findall(r'(?:[^\s,"]|"(?:\\.|[^"])*")+', line)
            for i in range(len(tokens)):
                if tokens[i] and tokens[i][0] == '"' and tokens[i][-1] == '"':
                    tokens[i] = tokens[i][1:-1]

            if not tokens or not tokens[0] or tokens[0][0] == '#':
                continue

            for token in tokens:
                # Figure out the grammar type of the token
                if token and token[-1] == SYMBOL_OPTION:
                    # It's an option
                    symbol = SYMBOL_OPTION

                    # Cut the trailing char from token
                    token = token[:-1]
                elif token == '{':
                    symbol = SYMBOL_SECTION_BEGIN
                elif token == '}':
                    symbol = SYMBOL_SECTION_END
                else:
                    symbol = SYMBOL_WORD

                # Attach read tokens to list of tokens
                self.tokens.append((token, symbol))

        self.index = 0
        self.length = len(self.tokens)

        return self
Beispiel #8
0
    def __init__(self, localEndpoint, secret, dataCbFun, ctlCbFun):
        self.__localEndpoint = localEndpoint
        self.__secret = secret
        self.__dataCbFun = dataCbFun
        self.__ctlCbFun = ctlCbFun
        asyncore.dispatcher.__init__(self)

        try:
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65535)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65535)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.bind(localEndpoint)
            self.listen(10)
        except socket.error:
            raise error.SnmpfwdError('%s socket error: %s' %
                                     (self, sys.exc_info()[1]))
            log.msg('%s: listening...' % self)
Beispiel #9
0
    def __init__(self, sock, localEndpoint, remoteEndpoint, secret, dataCbFun,
                 ctlCbFun):
        self.__localEndpoint = localEndpoint
        self.__remoteEndpoint = remoteEndpoint
        self.__secret = secret
        self.__dataCbFun = dataCbFun
        self.__ctlCbFun = ctlCbFun
        self.__pendingReqs = {}
        self.__pendingCounter = 0
        self.__input = null
        self.socket = None  # asyncore strangeness
        asyncore.dispatcher_with_send.__init__(self, sock)

        try:
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65535)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65535)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        except socket.error:
            raise error.SnmpfwdError('%s socket error: %s' %
                                     (self, sys.exc_info()[1]))
        else:
            log.msg('%s: serving new connection...' % (self, ))
Beispiel #10
0
    def __init__(self, localEndpoint, remoteEndpoint, secret, dataCbFun):
        self.__localEndpoint = localEndpoint
        self.__remoteEndpoint = remoteEndpoint
        self.__secret = secret
        self.__dataCbFun = dataCbFun
        self.__pendingReqs = {}
        self.__pendingCounter = 0
        self.__input = null
        self.__announcementData = null
        asyncore.dispatcher_with_send.__init__(self)

        try:
            self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65535)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65535)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            self.bind(localEndpoint)
            self.connect(remoteEndpoint)
        except socket.error:
            raise error.SnmpfwdError('%s socket error: %s' %
                                     (self, sys.exc_info()[1]))
        log.msg('initiated trunk client connection from %s to %s...' %
                (localEndpoint, remoteEndpoint))
Beispiel #11
0
    def loadPlugin(self, pluginId, pluginModuleName, pluginOptions):
        if pluginId in self.__plugins:
            raise error.SnmpfwdError('duplicate plugin ID %s' % pluginId)

        for pluginModulesDir in self.__path:
            log.info('scanning "%s" directory for plugin modules...' %
                     pluginModulesDir)
            if not os.path.exists(pluginModulesDir):
                log.error('directory "%s" does not exist' % pluginModulesDir)
                continue

            modPath = os.path.join(pluginModulesDir, pluginModuleName + '.py')
            if not os.path.exists(modPath):
                log.error('Variation module "%s" not found' % modPath)
                continue

            ctx = {
                'modulePath': modPath,
                'moduleContext': {},
                'moduleOptions': pluginOptions
            }

            modData = open(modPath).read()

            try:
                exec(compile(modData, modPath, 'exec'), ctx)

            except Exception:
                raise error.SnmpfwdError(
                    'plugin module "%s" execution failure: %s' %
                    (modPath, sys.exc_info()[1]))

            else:
                pluginModule = ctx
                try:
                    if self.__progId not in pluginModule['hostProgs']:
                        log.error(
                            'ignoring plugin module "%s" (unmatched program ID)'
                            % modPath)
                        continue

                    if self.__apiVer not in pluginModule['apiVersions']:
                        log.error(
                            'ignoring plugin module "%s" (incompatible API version)'
                            % modPath)
                        continue
                except KeyError:
                    log.error(
                        'ignoring plugin module "%s" (missing versioning info)'
                        % modPath)
                    continue

                self.__plugins[pluginId] = pluginModule

                log.info('plugin module "%s" loaded' % modPath)
                break

        else:
            raise error.SnmpfwdError(
                'plugin module "%s" not found in search path(s): %s' %
                (pluginModuleName, ', '.join(self.__path)))
Beispiel #12
0
    def load_section(self):
        obj = {'_name': '', '_children': []}

        state = 'FSM_START'

        while 1:
            # Initial state
            if state == 'FSM_START':
                try:
                    token, symbol = self.scanner.get_token()

                except error.EofError:
                    state = 'FSM_STOP'
                    continue

                self.scanner.unget_token()

                # See if it's object closure sign
                if symbol == SYMBOL_SECTION_END:
                    state = 'FSM_SECTION_END'

                # See if it's symbol sign
                elif symbol == SYMBOL_OPTION:
                    state = 'FSM_OPTION_NAME'

                # Default is to start from parsing up new section
                else:
                    state = 'FSM_SECTION_NAME'

            # If object name expected
            elif state == 'FSM_SECTION_NAME':
                self.scanner.get_token()

                self.scanner.unget_token()

                # Move to next FSM state
                state = 'FSM_SECTION_BEGIN'

            # If object body delimiter expected
            elif state == 'FSM_SECTION_BEGIN':
                self.scanner.get_token()

                # Get section begin
                token, symbol = self.scanner.get_token()

                # Now unget these tokens to be used at the
                # next FSM state
                self.scanner.unget_token()
                self.scanner.unget_token()

                # Make sure it's object's body start sign
                if symbol != SYMBOL_SECTION_BEGIN:
                    raise error.SnmpfwdError(
                        '%s missing object beginning sign: %s' % (self, token))

                state = 'FSM_CHILD_BEGIN'

            # If inclusive object expected
            elif state == 'FSM_CHILD_BEGIN':
                name, symbol = self.scanner.get_token()

                self.scanner.get_token()

                child_object = self.load_section()

                child_object['_name'] = name

                # Attach child object to the list of enclosed objects
                obj['_children'].append(child_object)

                state = 'FSM_CHILD_END'

            # If object body closure delimiter expected
            elif state == 'FSM_CHILD_END':
                # Get next token
                token, symbol = self.scanner.get_token()

                # Make sure it's object's body end sign
                if symbol != SYMBOL_SECTION_END:
                    raise error.SnmpfwdError(
                        '%s missing object closure sign: %s' % (self, token))

                # Move to the beginning of FSM
                state = 'FSM_START'

            # If object body closure delimiter expected
            elif state == 'FSM_SECTION_END':
                # Get next token
                token, symbol = self.scanner.get_token()

                # Now unget token to be used at upper level FSM instance
                self.scanner.unget_token()

                # Make sure it's object's body end sign
                if symbol != SYMBOL_SECTION_END:
                    raise error.SnmpfwdError(
                        '%s missing object closure sign: %s' % (self, token))

                # Move to next FSM state
                state = 'FSM_STOP'

            # If attribute name expected
            elif state == 'FSM_OPTION_NAME':
                # Get next token
                token, symbol = self.scanner.get_token()

                # See if this attribute does not yet exist
                if token in obj:
                    raise error.SnmpfwdError(
                        '%s multiple option occurrence: %s' % (self, token))

                # Accept token as attribute name
                obj[token] = []

                # Now unget token to be used at the next FSM state
                self.scanner.unget_token()

                # Move to next FSM state
                state = 'FSM_OPTION_VALUE'

            # If option value expected
            elif state == 'FSM_OPTION_VALUE':
                option, symbol = self.scanner.get_token()

                # Read up one or more option values
                while 1:
                    try:
                        token, symbol = self.scanner.get_token()

                    except error.EofError:
                        state = 'FSM_STOP'
                        break

                    # If it's not a plain word
                    if symbol != SYMBOL_WORD:
                        self.scanner.unget_token()

                        # See if it's object begin symbol
                        if symbol == SYMBOL_SECTION_BEGIN:
                            # Unget section begin sign
                            self.scanner.unget_token()

                            # Remove previously added last value of
                            # the list as it turned to be section name
                            del obj[option][-1]

                        # Move to the beginning of FSM
                        state = 'FSM_START'

                        break

                    # Accept token as attribute value
                    if token.lower()[:2] == '0x':
                        token = str(OctetString(hexValue=token[2:]))

                    obj[option].append(token)

            # If FSM is gonna stop
            elif state == 'FSM_STOP':
                # Return object loaded
                return obj

            # If this FSM state is not known
            else:
                raise error.SnmpfwdError('%s unknown FSM state: %s' %
                                         (self, state))
Beispiel #13
0
 def unget_token(self):
     if not self.index:
         raise error.SnmpfwdError('%s nothing to unget' % self)
     self.index -= 1
Beispiel #14
0
 def addClient(self, trunkId, localEndpoint, remoteEndpoint, secret):
     if trunkId in self.__clients or trunkId in self.__runningServersTrunkMap:
         raise error.SnmpfwdError('Trunk %s already registered' % trunkId)
     self.__clients[
         trunkId] = localEndpoint, remoteEndpoint, secret, self.__proxyDataCbFun
Beispiel #15
0
 def parse(self):
     try:
         return self.load_section()
     except error.EofError:
         raise error.SnmpfwdError(
             '%s premature EOF while reading config file' % self)
Beispiel #16
0
 def daemonize(pidfile):
     raise error.SnmpfwdError('Windows is not inhabited with daemons!')
Beispiel #17
0
    def daemonize(pidfile):
        try:
            pid = os.fork()
            if pid > 0:
                # exit first parent
                os._exit(0)
        except OSError:
            raise error.SnmpfwdError('ERROR: fork #1 failed: %s' %
                                     sys.exc_info()[1])

        # decouple from parent environment
        try:
            os.chdir('/')
            os.setsid()
        except OSError:
            pass
        os.umask(0)

        # do second fork
        try:
            pid = os.fork()
            if pid > 0:
                # exit from second parent
                os._exit(0)
        except OSError:
            raise error.SnmpfwdError('ERROR: fork #2 failed: %s' %
                                     sys.exc_info()[1])

        def signal_cb(s, f):
            raise KeyboardInterrupt

        for s in signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT:
            signal.signal(s, signal_cb)

        # write pidfile
        def atexit_cb():
            try:
                if pidfile:
                    os.remove(pidfile)
            except OSError:
                pass

        atexit.register(atexit_cb)

        try:
            if pidfile:
                fd, nm = tempfile.mkstemp(dir=os.path.dirname(pidfile))
                os.write(fd, ('%d\n' % os.getpid()).encode('utf-8'))
                os.close(fd)
                os.rename(nm, pidfile)
        except Exception:
            raise error.SnmpfwdError('Failed to create PID file %s: %s' %
                                     (pidfile, sys.exc_info()[1]))

        # redirect standard file descriptors
        sys.stdout.flush()
        sys.stderr.flush()
        si = open(os.devnull, 'r')
        so = open(os.devnull, 'a+')
        se = open(os.devnull, 'a+')

        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())