Example #1
0
class SNMPService(SystemServiceService):
    class Config:
        service = 'snmp'
        datastore_prefix = 'snmp_'

    @accepts(
        Dict('snmp_update',
             Str('location'),
             Str('contact',
                 validators=[Or(Email(), Match(r'^[-_a-zA-Z0-9\s]*$'))]),
             Bool('traps'),
             Bool('v3'),
             Str('community',
                 validators=[Match(r'^[-_.a-zA-Z0-9\s]*$')],
                 default='public'),
             Str('v3_username'),
             Str('v3_authtype', enum=['', 'MD5', 'SHA']),
             Str('v3_password'),
             Str('v3_privproto', enum=[None, 'AES', 'DES'], null=True),
             Str('v3_privpassphrase'),
             Int('loglevel', validators=[Range(min=0, max=7)]),
             Str('options'),
             update=True))
    async def do_update(self, data):
        old = await self.config()

        new = old.copy()
        new.update(data)

        verrors = ValidationErrors()

        if not new['v3'] and not new['community']:
            verrors.add('snmp_update.community',
                        'This field is required when SNMPv3 is disabled')

        if new['v3_authtype'] and not new['v3_password']:
            verrors.add(
                'snmp_update.v3_password',
                'This field is requires when SNMPv3 auth type is specified',
            )

        if new['v3_password'] and len(new['v3_password']) < 8:
            verrors.add('snmp_update.v3_password',
                        'Password must contain at least 8 characters')

        if new['v3_privproto'] and not new['v3_privpassphrase']:
            verrors.add(
                'snmp_update.v3_privpassphrase',
                'This field is requires when SNMPv3 private protocol is specified',
            )

        if verrors:
            raise verrors

        await self._update_service(old, new)

        return new
Example #2
0
class SNMPService(SystemServiceService):
    class Config:
        service = "snmp"
        datastore_prefix = "snmp_"

    @accepts(
        Dict(
            'snmp_update',
            Str('location'),
            Str('contact',
                validators=[Or(Email(), Match(r'^[-_a-zA-Z0-9\s]+$'))]),
            Bool('traps'),
            Bool('v3'),
            Str('community', validators=[Match(r'^[-_.a-zA-Z0-9\s]*$')]),
            Str('v3_username'),
            Str('v3_authtype', enum=['', 'MD5', 'SHA']),
            Str('v3_password'),
            Str('v3_privproto', enum=[None, 'AES', 'DES']),
            Str('v3_privpassphrase'),
            Int('loglevel', validators=[Range(min=0, max=7)]),
            Str('options'),
        ))
    async def update(self, data):
        old = await self.config()

        new = old.copy()
        new.update(data)

        verrors = ValidationErrors()

        if not data["v3"] and not data["community"]:
            verrors.add("snmp_update.community",
                        "This field is required when SNMPv3 is disabled")

        if data["v3_authtype"] and not data["v3_password"]:
            verrors.add(
                "snmp_update.v3_password",
                "This field is requires when SNMPv3 auth type is specified")

        if data["v3_password"] and len(data["v3_password"]) < 8:
            verrors.add("snmp_update.v3_password",
                        "Password must contain at least 8 characters")

        if data["v3_privproto"] and not data["v3_privpassphrase"]:
            verrors.add(
                "snmp_update.v3_privpassphrase",
                "This field is requires when SNMPv3 private protocol is specified"
            )

        if verrors:
            raise verrors

        await self._update_service(old, new)

        return new
Example #3
0
class FTPService(SystemServiceService):

    class Config:
        service = "ftp"
        datastore_prefix = "ftp_"
        datastore_extend = "ftp.ftp_extend"
        cli_namespace = "service.ftp"

    @private
    async def ftp_extend(self, data):
        if data['ssltls_certificate']:
            data['ssltls_certificate'] = data['ssltls_certificate']['id']
        return data

    @accepts(Dict(
        'ftp_update',
        Int('port', validators=[Range(min=1, max=65535)]),
        Int('clients', validators=[Range(min=1, max=10000)]),
        Int('ipconnections', validators=[Range(min=0, max=1000)]),
        Int('loginattempt', validators=[Range(min=0, max=1000)]),
        Int('timeout', validators=[Range(min=0, max=10000)]),
        Bool('rootlogin'),
        Bool('onlyanonymous'),
        Dir('anonpath', null=True),
        Bool('onlylocal'),
        Str('banner', max_length=None),
        Str('filemask', validators=[Match(r"^[0-7]{3}$")]),
        Str('dirmask', validators=[Match(r"^[0-7]{3}$")]),
        Bool('fxp'),
        Bool('resume'),
        Bool('defaultroot'),
        Bool('ident'),
        Bool('reversedns'),
        Str('masqaddress'),
        Int('passiveportsmin', validators=[Or(Exact(0), Range(min=1024, max=65535))]),
        Int('passiveportsmax', validators=[Or(Exact(0), Range(min=1024, max=65535))]),
        Int('localuserbw', validators=[Range(min=0)]),
        Int('localuserdlbw', validators=[Range(min=0)]),
        Int('anonuserbw', validators=[Range(min=0)]),
        Int('anonuserdlbw', validators=[Range(min=0)]),
        Bool('tls'),
        Str('tls_policy', enum=["on", "off", "data", "!data", "auth", "ctrl",
                                "ctrl+data", "ctrl+!data", "auth+data", "auth+!data"]),
        Bool('tls_opt_allow_client_renegotiations'),
        Bool('tls_opt_allow_dot_login'),
        Bool('tls_opt_allow_per_user'),
        Bool('tls_opt_common_name_required'),
        Bool('tls_opt_enable_diags'),
        Bool('tls_opt_export_cert_data'),
        Bool('tls_opt_no_cert_request'),
        Bool('tls_opt_no_empty_fragments'),
        Bool('tls_opt_no_session_reuse_required'),
        Bool('tls_opt_stdenvvars'),
        Bool('tls_opt_dns_name_required'),
        Bool('tls_opt_ip_address_required'),
        Int('ssltls_certificate', null=True),
        Str('options', max_length=None),
        update=True
    ))
    async def do_update(self, data):
        """
        Update ftp service configuration.

        `clients` is an integer value which sets the maximum number of simultaneous clients allowed. It defaults to 32.

        `ipconnections` is an integer value which shows the maximum number of connections per IP address. It defaults
        to 0 which equals to unlimited.

        `timeout` is the maximum client idle time in seconds before client is disconnected.

        `rootlogin` is a boolean value which when configured to true enables login as root. This is generally
        discouraged because of the security risks.

        `onlyanonymous` allows anonymous FTP logins with access to the directory specified by `anonpath`.

        `banner` is a message displayed to local login users after they successfully authenticate. It is not displayed
        to anonymous login users.

        `filemask` sets the default permissions for newly created files which by default are 077.

        `dirmask` sets the default permissions for newly created directories which by default are 077.

        `resume` if set allows FTP clients to resume interrupted transfers.

        `fxp` if set to true indicates that File eXchange Protocol is enabled. Generally it is discouraged as it
        makes the server vulnerable to FTP bounce attacks.

        `defaultroot` when set ensures that for local users, home directory access is only granted if the user
        is a member of group wheel.

        `ident` is a boolean value which when set to true indicates that IDENT authentication is required. If identd
        is not running on the client, this can result in timeouts.

        `masqaddress` is the public IP address or hostname which is set if FTP clients cannot connect through a
        NAT device.

        `localuserbw` is a positive integer value which indicates maximum upload bandwidth in KB/s for local user.
        Default of zero indicates unlimited upload bandwidth ( from the FTP server configuration ).

        `localuserdlbw` is a positive integer value which indicates maximum download bandwidth in KB/s for local user.
        Default of zero indicates unlimited download bandwidth ( from the FTP server configuration ).

        `anonuserbw` is a positive integer value which indicates maximum upload bandwidth in KB/s for anonymous user.
        Default of zero indicates unlimited upload bandwidth ( from the FTP server configuration ).

        `anonuserdlbw` is a positive integer value which indicates maximum download bandwidth in KB/s for anonymous
        user. Default of zero indicates unlimited download bandwidth ( from the FTP server configuration ).

        `tls` is a boolean value which when set indicates that encrypted connections are enabled. This requires a
        certificate to be configured first with the certificate service and the id of certificate is passed on in
        `ssltls_certificate`.

        `tls_policy` defines whether the control channel, data channel, both channels, or neither channel of an FTP
        session must occur over SSL/TLS.

        `tls_opt_enable_diags` is a boolean value when set, logs verbosely. This is helpful when troubleshooting a
        connection.

        `options` is a string used to add proftpd(8) parameters not covered by ftp service.
        """
        old = await self.config()

        new = old.copy()
        new.update(data)

        verrors = ValidationErrors()

        if not ((new["passiveportsmin"] == 0) == (new["passiveportsmax"] == 0)):
            verrors.add("passiveportsmin", "passiveportsmin and passiveportsmax should be both zero or non-zero")
        if not ((new["passiveportsmin"] == 0 and new["passiveportsmax"] == 0) or
                (new["passiveportsmax"] > new["passiveportsmin"])):
            verrors.add("ftp_update.passiveportsmax", "When specified, should be greater than passiveportsmin")

        if new["onlyanonymous"]:
            if not new["anonpath"]:
                verrors.add("ftp_update.anonpath", "This field is required for anonymous login")
            else:
                await check_path_resides_within_volume(verrors, self.middleware, "ftp_update.anonpath", new["anonpath"])

        if new["tls"]:
            if not new["ssltls_certificate"]:
                verrors.add(
                    "ftp_update.ssltls_certificate",
                    "Please provide a valid certificate id when TLS is enabled"
                )
            else:
                verrors.extend((await self.middleware.call(
                    "certificate.cert_services_validation", new["ssltls_certificate"],
                    "ftp_update.ssltls_certificate", False
                )))

        if new["masqaddress"]:
            await resolve_hostname(self.middleware, verrors, "ftp_update.masqaddress", new["masqaddress"])

        if verrors:
            raise verrors

        await self._update_service(old, new)

        if not old['tls'] and new['tls']:
            await self.middleware.call('service.start', 'ssl')

        return new
Example #4
0
class FTPService(SystemServiceService):
    class Config:
        service = "ftp"
        datastore_prefix = "ftp_"
        datastore_extend = "ftp.ftp_extend"

    @private
    async def ftp_extend(self, data):
        if data['ssltls_certificate']:
            data['ssltls_certificate'] = data['ssltls_certificate']['id']
        return data

    @accepts(
        Dict('ftp_update',
             Int('port', validators=[Range(min=1, max=65535)]),
             Int('clients', validators=[Range(min=1, max=10000)]),
             Int('ipconnections', validators=[Range(min=0, max=1000)]),
             Int('loginattempt', validators=[Range(min=0, max=1000)]),
             Int('timeout', validators=[Range(min=0, max=10000)]),
             Bool('rootlogin'),
             Bool('onlyanonymous'),
             Dir('anonpath', null=True),
             Bool('onlylocal'),
             Str('banner'),
             Str('filemask', validators=[Match(r"^[0-7]{3}$")]),
             Str('dirmask', validators=[Match(r"^[0-7]{3}$")]),
             Bool('fxp'),
             Bool('resume'),
             Bool('defaultroot'),
             Bool('ident'),
             Bool('reversedns'),
             Str('masqaddress'),
             Int('passiveportsmin',
                 validators=[Or(Exact(0), Range(min=1024, max=65535))]),
             Int('passiveportsmax',
                 validators=[Or(Exact(0), Range(min=1024, max=65535))]),
             Int('localuserbw', validators=[Range(min=0)]),
             Int('localuserdlbw', validators=[Range(min=0)]),
             Int('anonuserbw', validators=[Range(min=0)]),
             Int('anonuserdlbw', validators=[Range(min=0)]),
             Bool('tls'),
             Str('tls_policy',
                 enum=[
                     "on", "off", "data", "!data", "auth", "ctrl", "ctrl+data",
                     "ctrl+!data", "auth+data", "auth+!data"
                 ]),
             Bool('tls_opt_allow_client_renegotiations'),
             Bool('tls_opt_allow_dot_login'),
             Bool('tls_opt_allow_per_user'),
             Bool('tls_opt_common_name_required'),
             Bool('tls_opt_enable_diags'),
             Bool('tls_opt_export_cert_data'),
             Bool('tls_opt_no_cert_request'),
             Bool('tls_opt_no_empty_fragments'),
             Bool('tls_opt_no_session_reuse_required'),
             Bool('tls_opt_stdenvvars'),
             Bool('tls_opt_dns_name_required'),
             Bool('tls_opt_ip_address_required'),
             Int('ssltls_certificate', null=True),
             Str('options'),
             update=True))
    async def do_update(self, data):
        old = await self.config()

        new = old.copy()
        new.update(data)

        verrors = ValidationErrors()

        if not ((new["passiveportsmin"] == 0) == (new["passiveportsmax"]
                                                  == 0)):
            verrors.add(
                "passiveportsmin",
                "passiveportsmin and passiveportsmax should be both zero or non-zero"
            )
        if not ((new["passiveportsmin"] == 0 and new["passiveportsmax"] == 0)
                or (new["passiveportsmax"] > new["passiveportsmin"])):
            verrors.add(
                "ftp_update.passiveportsmax",
                "When specified, should be greater than passiveportsmin")

        if new["onlyanonymous"] and not new["anonpath"]:
            verrors.add("ftp_update.anonpath",
                        "This field is required for anonymous login")

        if new["anonpath"]:
            await check_path_resides_within_volume(verrors, self.middleware,
                                                   "ftp_update.anonpath",
                                                   new["anonpath"])

        if new["tls"]:
            if not new["ssltls_certificate"]:
                verrors.add(
                    "ftp_update.ssltls_certificate",
                    "Please provide a valid certificate id when TLS is enabled"
                )
            else:
                verrors.extend((await self.middleware.call(
                    "certificate.cert_services_validation",
                    new["ssltls_certificate"], "ftp_update.ssltls_certificate",
                    False)))

        if new["masqaddress"]:
            await resolve_hostname(self.middleware, verrors,
                                   "ftp_update.masqaddress",
                                   new["masqaddress"])

        if verrors:
            raise verrors

        await self._update_service(old, new)

        if not old['tls'] and new['tls']:
            await self.middleware.call('service.start', 'ssl')

        return new
Example #5
0
class SNMPService(SystemServiceService):

    class Config:
        service = 'snmp'
        datastore_prefix = 'snmp_'
        cli_namespace = 'service.snmp'

    ENTRY = Dict(
        'snmp_entry',
        Str('location', required=True),
        Str('contact', required=True, validators=[Or(Email(), Match(r'^[-_a-zA-Z0-9\s]*$'))]),
        Bool('traps', required=True),
        Bool('v3', required=True),
        Str('community', validators=[Match(r'^[-_.a-zA-Z0-9\s]*$')], default='public', required=True),
        Str('v3_username', max_length=20, required=True),
        Str('v3_authtype', enum=['', 'MD5', 'SHA'], required=True),
        Str('v3_password', required=True),
        Str('v3_privproto', enum=[None, 'AES', 'DES'], null=True, required=True),
        Str('v3_privpassphrase', required=True, null=True),
        Int('loglevel', validators=[Range(min=0, max=7)], required=True),
        Str('options', max_length=None, required=True),
        Bool('zilstat', required=True),
        Bool('iftop', required=True),
        Int('id', required=True),
    )

    async def do_update(self, data):
        """
        Update SNMP Service Configuration.

        `v3` when set enables SNMP version 3.

        `v3_username`, `v3_authtype`, `v3_password`, `v3_privproto` and `v3_privpassphrase` are only used when `v3`
        is enabled.
        """
        old = await self.config()

        new = old.copy()
        new.update(data)

        verrors = ValidationErrors()

        if not new['v3'] and not new['community']:
            verrors.add('snmp_update.community', 'This field is required when SNMPv3 is disabled')

        if new['v3_authtype'] and not new['v3_password']:
            verrors.add(
                'snmp_update.v3_password',
                'This field is requires when SNMPv3 auth type is specified',
            )

        if new['v3_password'] and len(new['v3_password']) < 8:
            verrors.add('snmp_update.v3_password', 'Password must contain at least 8 characters')

        if new['v3_privproto'] and not new['v3_privpassphrase']:
            verrors.add(
                'snmp_update.v3_privpassphrase',
                'This field is requires when SNMPv3 private protocol is specified',
            )

        if verrors:
            raise verrors

        await self._update_service(old, new)

        return await self.config()