mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
WIP: Moved DMARC plugin back to core repo
This commit is contained in:
@@ -101,7 +101,7 @@ jobs:
|
||||
run: |
|
||||
python ./tests.py
|
||||
cd test_project
|
||||
python3 manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog modoboa.parameters
|
||||
python3 manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog modoboa.parameters modoboa.dmarc
|
||||
env:
|
||||
# use localhost for the host here because we are running the job on the VM.
|
||||
# If we were running the job on in a container this would be postgres
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
run: |
|
||||
python ./tests.py
|
||||
cd test_project
|
||||
coverage run manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog modoboa.parameters
|
||||
coverage run manage.py test modoboa.core modoboa.lib modoboa.admin modoboa.limits modoboa.transport modoboa.relaydomains modoboa.dnstools modoboa.ldapsync modoboa.policyd modoboa.maillog modoboa.parameters modoboa.dmarc
|
||||
coverage combine
|
||||
env:
|
||||
# use localhost for the host here because we are running the job on the VM.
|
||||
|
||||
+37
-4
@@ -66,7 +66,7 @@ New admin interface won't update by itself. Run the following commands to update
|
||||
> rm -rf frontend
|
||||
> cp -R <virtuenv_path>/lib/pythonX.X/site-packages/modoboa/frontend_dist/ frontend/
|
||||
> cp ./config.json frontend/config.json
|
||||
|
||||
|
||||
Extensions
|
||||
**********
|
||||
|
||||
@@ -108,7 +108,40 @@ Rebuild Virtual Environment
|
||||
Specific instructions
|
||||
*********************
|
||||
|
||||
2.0.4
|
||||
2.1.0
|
||||
=====
|
||||
|
||||
The ``modoboa-dmarc`` plugin has been merged into the core.
|
||||
|
||||
Add ``'modoboa.dmarc'`` to ``MODOBOA_APPS``:
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
MODOBOA_APPS = (
|
||||
'modoboa',
|
||||
'modoboa.core',
|
||||
'modoboa.lib',
|
||||
'modoboa.admin',
|
||||
'modoboa.transport',
|
||||
'modoboa.relaydomains',
|
||||
'modoboa.limits',
|
||||
'modoboa.parameters',
|
||||
'modoboa.dnstools',
|
||||
'modoboa.policyd',
|
||||
'modoboa.maillog',
|
||||
'modoboa.dmarc',
|
||||
)
|
||||
|
||||
And remove any reference to ``modoboa_dmarc`` in this same variable.
|
||||
|
||||
FIXME: INSTALLATION django-rename-app
|
||||
|
||||
.. sourcecode:: bash
|
||||
|
||||
python manage.py rename_app modoboa_dmarc dmarc
|
||||
|
||||
|
||||
2.0.4t
|
||||
=====
|
||||
|
||||
The following modifications must be applied to the :file:`settings.py` file:
|
||||
@@ -159,7 +192,7 @@ The following modifications must be applied to the :file:`settings.py` file:
|
||||
},
|
||||
|
||||
|
||||
* You now have the possibility to customize the url of the new-admin interface.
|
||||
* You now have the possibility to customize the url of the new-admin interface.
|
||||
To do so please head up to :ref:`the custom configuration chapter <customization>` (advanced user).
|
||||
|
||||
* Add ``DEFAULT_THROTTLE_RATES`` to ``REST_FRAMEWORK``:
|
||||
@@ -187,7 +220,7 @@ The following modifications must be applied to the :file:`settings.py` file:
|
||||
|
||||
* You can edit the ``DEFAULT_THROTTLE_RATES`` to whatever value suits you.
|
||||
- `user` is for every endpoint, it is per user or per ip if not logged.
|
||||
- `ddos` is per api endpoint and per user or per ip if not logged.
|
||||
- `ddos` is per api endpoint and per user or per ip if not logged.
|
||||
- `ddos_lesser` is for per api endpoint and per user or per ip if not logged. This is for api endpoint that are lighter.
|
||||
- `login` the number of time an ip can attempt to log. The counter will reset on login success.
|
||||
- `password_` is for the recovery, it is divided per step in the recovery process.
|
||||
|
||||
@@ -13,6 +13,12 @@ export default {
|
||||
getDomainDNSDetail (domainId) {
|
||||
return repository.get(`/${domainResource}/${domainId}/dns_detail/`)
|
||||
},
|
||||
getDomainDmarcAligment (domainId, period) {
|
||||
return repository.get(
|
||||
`${domainResource}/${domainId}/dmarc/alignment_stats/`,
|
||||
{ params: { period } }
|
||||
)
|
||||
},
|
||||
getDomainAliases (domain) {
|
||||
let url = `/${domainAliasResource}/`
|
||||
if (domain !== undefined) {
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-card>
|
||||
<v-toolbar dense elevation="0" class="mr-2">
|
||||
<v-toolbar-title><translate>Aligment</translate></v-toolbar-title>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
icon
|
||||
x-small
|
||||
@click="previousWeek"
|
||||
>
|
||||
<v-icon>mdi-arrow-left</v-icon>
|
||||
</v-btn>
|
||||
<span class="mx-2">{{ weekStart.toLocaleString() }} - {{ weekEnd.toLocaleString() }}</span>
|
||||
<v-btn
|
||||
icon
|
||||
x-small
|
||||
@click="nextWeek"
|
||||
>
|
||||
<v-icon>mdi-arrow-right</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="5">
|
||||
<apexchart
|
||||
v-if="series"
|
||||
type="pie"
|
||||
height="350"
|
||||
:options="options"
|
||||
:series="series"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="7">
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="box in boxes"
|
||||
:key="box.key"
|
||||
cols="6"
|
||||
>
|
||||
<v-sheet
|
||||
outlined
|
||||
:color="box.color"
|
||||
rounded
|
||||
>
|
||||
<v-card
|
||||
outlined
|
||||
class="pa-10 text-center"
|
||||
>
|
||||
<span :class="'text-h4 ' + getTextColors(box.color)">{{ stats[box.key] }}</span><br>
|
||||
<span class="text-subtitle-1">{{ box.label }}</span>
|
||||
</v-card>
|
||||
</v-sheet>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-expansion-panels
|
||||
v-model="panel"
|
||||
class="mt-2"
|
||||
>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-header>
|
||||
<translate>Detail</translate>
|
||||
</v-expansion-panel-header>
|
||||
<v-expansion-panel-content>
|
||||
<dmarc-source-table
|
||||
:title="'Trusted sources'|translate"
|
||||
color="green"
|
||||
:total="stats.aligned"
|
||||
:sources="alignments.aligned"
|
||||
/>
|
||||
<dmarc-source-table
|
||||
:title="'Partially trusted sources / Forwarders'|translate"
|
||||
color="orange"
|
||||
:total="stats.trusted"
|
||||
:sources="alignments.trusted"
|
||||
class="mt-4"
|
||||
/>
|
||||
<dmarc-source-table
|
||||
:title="'Forwarders with ARC'|translate"
|
||||
color="blue"
|
||||
:total="stats.forwarded"
|
||||
:sources="alignments.forwarded"
|
||||
class="mt-4"
|
||||
/>
|
||||
<dmarc-source-table
|
||||
:title="'Unknown sources / Threats'|translate"
|
||||
color="red"
|
||||
:total="stats.failed"
|
||||
:sources="alignments.failed"
|
||||
class="mt-4"
|
||||
/>
|
||||
</v-expansion-panel-content>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import colors from 'vuetify/lib/util/colors'
|
||||
import DmarcSourceTable from './DmarcSourceTable'
|
||||
import domainsApi from '@/api/domains'
|
||||
import { DateTime } from 'luxon'
|
||||
import VueApexCharts from 'vue-apexcharts'
|
||||
|
||||
const order = ['aligned', 'trusted', 'forwarded', 'failed']
|
||||
|
||||
export default {
|
||||
components: {
|
||||
apexchart: VueApexCharts,
|
||||
DmarcSourceTable
|
||||
},
|
||||
props: {
|
||||
domain: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
options: {
|
||||
colors: [colors.green.lighten2, colors.orange.lighten2, colors.blue.lighten2, colors.red.lighten2],
|
||||
labels: [
|
||||
this.$gettext('Fully aligned'),
|
||||
this.$gettext('Partially aligned'),
|
||||
this.$gettext('Forwarded'),
|
||||
this.$gettext('Failed')
|
||||
],
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
},
|
||||
alignments: {},
|
||||
boxes: [
|
||||
{ key: 'total', label: this.$gettext('Total'), color: 'primary lighten-2' },
|
||||
{ key: 'aligned', label: this.$gettext('Fully aligned'), color: 'green lighten-2' },
|
||||
{ key: 'trusted', label: this.$gettext('Partially aligned'), color: 'orange lighten-2' },
|
||||
{ key: 'forwarded', label: this.$gettext('Forwarded'), color: 'blue lighten-2' },
|
||||
{ key: 'failed', label: this.$gettext('Failed'), color: 'red lighten-2' }
|
||||
],
|
||||
currentWeek: 0,
|
||||
currentYear: 0,
|
||||
loading: false,
|
||||
panel: null,
|
||||
series: [],
|
||||
stats: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
weekStart () {
|
||||
const dt = DateTime.fromObject({
|
||||
weekYear: this.currentYear,
|
||||
weekNumber: this.currentWeek
|
||||
})
|
||||
return dt.startOf('week')
|
||||
},
|
||||
weekEnd () {
|
||||
const dt = DateTime.fromObject({
|
||||
weekYear: this.currentYear,
|
||||
weekNumber: this.currentWeek
|
||||
})
|
||||
return dt.endOf('week')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTextColors (value) {
|
||||
let result = ''
|
||||
for (const color of value.split(' ')) {
|
||||
if (result !== '') {
|
||||
result += ' '
|
||||
}
|
||||
if (color.startsWith('lighten')) {
|
||||
result += 'text--' + color
|
||||
} else {
|
||||
result += color + '--text'
|
||||
}
|
||||
}
|
||||
return result
|
||||
},
|
||||
nextWeek () {
|
||||
if (this.currentWeek === 52) {
|
||||
this.currentYear += 1
|
||||
this.currentWeek = 1
|
||||
} else {
|
||||
this.currentWeek += 1
|
||||
}
|
||||
},
|
||||
previousWeek () {
|
||||
if (this.currentWeek === 1) {
|
||||
this.currentYear -= 1
|
||||
this.currentWeek = 52
|
||||
} else {
|
||||
this.currentWeek -= 1
|
||||
}
|
||||
},
|
||||
fetchAligmentStats () {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
const period = `${this.currentYear}-${this.currentWeek}`
|
||||
this.loading = true
|
||||
domainsApi.getDomainDmarcAligment(this.domain.pk, period).then(resp => {
|
||||
this.stats = { total: 0 }
|
||||
this.alignments = resp.data
|
||||
this.series = []
|
||||
for (const key of order) {
|
||||
let total = 0
|
||||
for (const name in resp.data[key]) {
|
||||
for (const ip in resp.data[key][name]) {
|
||||
total += resp.data[key][name][ip].total
|
||||
}
|
||||
}
|
||||
this.stats.total += total
|
||||
this.stats[key] = total
|
||||
this.series.push(total)
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const now = DateTime.now()
|
||||
this.currentYear = now.year
|
||||
this.currentWeek = now.weekNumber
|
||||
},
|
||||
mounted () {
|
||||
this.fetchAligmentStats()
|
||||
},
|
||||
watch: {
|
||||
currentWeek () {
|
||||
this.fetchAligmentStats()
|
||||
},
|
||||
currentYear () {
|
||||
this.fetchAligmentStats()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="text-h6">{{ title }} <span :class="`${color}--text text--lighten-2`">{{ total }}</span></div>
|
||||
<v-simple-table>
|
||||
<tbody>
|
||||
<template v-for="(source, name) in sources">
|
||||
<tr :key="name">
|
||||
<th width="40%">{{ name }}</th>
|
||||
<th><translate>Total</translate></th>
|
||||
<th>SPF</th>
|
||||
<th>DKIM</th>
|
||||
</tr>
|
||||
<tr v-for="(counters, ip) in source" :key="ip">
|
||||
<td>{{ ip }}</td>
|
||||
<td>{{ counters.total }}</td>
|
||||
<td>
|
||||
<v-avatar
|
||||
color="green lighten-2"
|
||||
size="24"
|
||||
>
|
||||
<span class="white--text">{{ counters.spf.success }}</span>
|
||||
</v-avatar>
|
||||
<v-avatar
|
||||
color="red lighten-2 ml-1"
|
||||
size="24"
|
||||
>
|
||||
<span class="white--text">{{ counters.spf.failure }}</span>
|
||||
</v-avatar>
|
||||
</td>
|
||||
<td>
|
||||
<v-avatar
|
||||
color="green lighten-2"
|
||||
size="24"
|
||||
>
|
||||
<span class="white--text">{{ counters.dkim.success }}</span>
|
||||
</v-avatar>
|
||||
<v-avatar
|
||||
color="red lighten-2 ml-1"
|
||||
size="24"
|
||||
>
|
||||
<span class="white--text">{{ counters.dkim.failure }}</span>
|
||||
</v-avatar>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</v-simple-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: String,
|
||||
color: String,
|
||||
total: Number,
|
||||
sources: Object
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -6,49 +6,77 @@
|
||||
<v-icon>mdi-circle-edit-outline</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-layout>
|
||||
<v-row>
|
||||
<v-col cols="6">
|
||||
<domain-summary :domain="domain" />
|
||||
<div class="mt-4" />
|
||||
<administrator-list
|
||||
|
||||
<v-tabs
|
||||
v-model="tab"
|
||||
>
|
||||
<v-tab>
|
||||
<translate>General</translate>
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
<translate>Statistics</translate>
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
<translate>DMARC</translate>
|
||||
</v-tab>
|
||||
<v-tabs-items
|
||||
v-model="tab"
|
||||
>
|
||||
<v-tab-item>
|
||||
<v-layout class="pa-2">
|
||||
<v-row>
|
||||
<v-col cols="6">
|
||||
<domain-summary :domain="domain" />
|
||||
<div class="mt-4" />
|
||||
<administrator-list
|
||||
:domain="domain"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="6">
|
||||
<dns-detail v-model="domain" />
|
||||
<div class="mt-4" />
|
||||
<resources
|
||||
v-if="limitsConfig.params && limitsConfig.params.enable_domain_limits && domain.resources && domain.resources.length"
|
||||
:resources="domain.resources"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-layout>
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<v-layout class="pa-2">
|
||||
<v-row class="mt-2">
|
||||
<v-col cols="12">
|
||||
<time-serie-chart
|
||||
v-if="domain.name"
|
||||
:domain="domain"
|
||||
graphic-set="mailtraffic"
|
||||
graphic-name="averagetraffic"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<time-serie-chart
|
||||
v-if="domain.name"
|
||||
:domain="domain"
|
||||
graphic-set="mailtraffic"
|
||||
graphic-name="averagetrafficsize"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-layout>
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<dmarc-aligment-chart
|
||||
:domain="domain"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="6">
|
||||
<dns-detail v-model="domain" />
|
||||
<div class="mt-4" />
|
||||
<resources
|
||||
v-if="limitsConfig.params && limitsConfig.params.enable_domain_limits && domain.resources && domain.resources.length"
|
||||
:resources="domain.resources"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-layout>
|
||||
<v-layout>
|
||||
<v-row class="mt-2">
|
||||
<v-col cols="12">
|
||||
<time-serie-chart
|
||||
v-if="domain.name"
|
||||
:domain="domain"
|
||||
graphic-set="mailtraffic"
|
||||
graphic-name="averagetraffic"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<time-serie-chart
|
||||
v-if="domain.name"
|
||||
:domain="domain"
|
||||
graphic-set="mailtraffic"
|
||||
graphic-name="averagetrafficsize"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-layout>
|
||||
<v-dialog v-model="showEditForm"
|
||||
persistent
|
||||
max-width="800px"
|
||||
>
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-tabs>
|
||||
<v-dialog
|
||||
v-model="showEditForm"
|
||||
persistent
|
||||
max-width="800px"
|
||||
>
|
||||
<domain-form :domain="domain" @close="showEditForm = false" />
|
||||
</v-dialog>
|
||||
</div>
|
||||
@@ -57,6 +85,7 @@
|
||||
<script>
|
||||
import domains from '@/api/domains'
|
||||
import AdministratorList from '@/components/domains/AdministratorList'
|
||||
import DmarcAligmentChart from '@/components/dmarc/DmarcAligmentChart'
|
||||
import DNSDetail from '@/components/domains/DNSDetail'
|
||||
import DomainForm from '@/components/domains/DomainForm'
|
||||
import DomainSummary from '@/components/domains/DomainSummary'
|
||||
@@ -68,6 +97,7 @@ export default {
|
||||
components: {
|
||||
AdministratorList,
|
||||
'dns-detail': DNSDetail,
|
||||
DmarcAligmentChart,
|
||||
DomainForm,
|
||||
DomainSummary,
|
||||
Resources,
|
||||
@@ -78,7 +108,8 @@ export default {
|
||||
domain: { pk: this.$route.params.id },
|
||||
limitsConfig: {},
|
||||
showEditForm: false,
|
||||
showAdminList: false
|
||||
showAdminList: false,
|
||||
tab: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -98,4 +129,7 @@ export default {
|
||||
.v-toolbar {
|
||||
background-color: #f7f8fa !important;
|
||||
}
|
||||
.v-tabs-items {
|
||||
background-color: #f7f8fa !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -87,6 +87,7 @@ MODOBOA_APPS = (
|
||||
'modoboa.dnstools',
|
||||
'modoboa.policyd',
|
||||
'modoboa.maillog',
|
||||
'modoboa.dmarc',
|
||||
# Modoboa extensions here.
|
||||
{% for extension in extensions %} '{{ extension }}',
|
||||
{% endfor %}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
"""DMARC related tools for Modoboa."""
|
||||
|
||||
default_app_config = "modoboa.dmarc.apps.DmarcConfig"
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -0,0 +1,32 @@
|
||||
"""App related serializers."""
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class TestResultSerializer(serializers.Serializer):
|
||||
|
||||
success = serializers.IntegerField()
|
||||
failure = serializers.IntegerField()
|
||||
|
||||
|
||||
class SourceSerializer(serializers.Serializer):
|
||||
|
||||
total = serializers.IntegerField()
|
||||
spf = TestResultSerializer()
|
||||
dkim = TestResultSerializer()
|
||||
|
||||
|
||||
class DMARCAligmentSerializer(serializers.Serializer):
|
||||
|
||||
aligned = serializers.DictField(
|
||||
child=serializers.DictField(child=SourceSerializer())
|
||||
)
|
||||
trusted = serializers.DictField(
|
||||
child=serializers.DictField(child=SourceSerializer())
|
||||
)
|
||||
forwarded = serializers.DictField(
|
||||
child=serializers.DictField(child=SourceSerializer())
|
||||
)
|
||||
failed = serializers.DictField(
|
||||
child=serializers.DictField(child=SourceSerializer())
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""API v2 tests."""
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from modoboa.lib.tests import ModoAPITestCase
|
||||
|
||||
from modoboa.admin import factories as admin_factories
|
||||
from modoboa.dmarc.tests import mixins
|
||||
|
||||
|
||||
class DmarcViewSetTestCase(mixins.CallCommandMixin, ModoAPITestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super().setUpTestData()
|
||||
cls.domain = admin_factories.DomainFactory(name="ngyn.org")
|
||||
|
||||
def test_alignment_stats(self):
|
||||
"""Test alignment stats endpoint."""
|
||||
self.import_reports()
|
||||
url = reverse("v2:dmarc-alignment-stats", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=2015-26")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()["failed"]), 1)
|
||||
|
||||
def test_wrong_range(self):
|
||||
url = reverse("v2:dmarc-alignment-stats", args=[self.domain.pk])
|
||||
response = self.client.get(f"{url}?period=toto-titi")
|
||||
self.assertEqual(response.status_code, 400)
|
||||
@@ -0,0 +1,10 @@
|
||||
"""App related API urls."""
|
||||
|
||||
from rest_framework import routers
|
||||
|
||||
from . import viewsets
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r"domains", viewsets.DMARCViewSet, basename="dmarc")
|
||||
|
||||
urlpatterns = router.urls
|
||||
@@ -0,0 +1,36 @@
|
||||
"""App. related viewsets."""
|
||||
|
||||
from rest_framework import permissions, response, viewsets
|
||||
from rest_framework.decorators import action
|
||||
|
||||
from modoboa.admin import models as admin_models
|
||||
from modoboa.lib.throttle import GetThrottleViewsetMixin
|
||||
|
||||
from ... import lib
|
||||
from . import serializers
|
||||
|
||||
|
||||
class DMARCViewSet(GetThrottleViewsetMixin, viewsets.GenericViewSet):
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated, )
|
||||
|
||||
def get_queryset(self):
|
||||
"""Filter queryset based on current user."""
|
||||
return admin_models.Domain.objects.get_for_admin(self.request.user)
|
||||
|
||||
@action(
|
||||
methods=["get"],
|
||||
detail=True,
|
||||
serializer_class=serializers.DMARCAligmentSerializer,
|
||||
url_path="dmarc/alignment_stats"
|
||||
)
|
||||
def alignment_stats(self, request, **kwargs):
|
||||
domain = self.get_object()
|
||||
try:
|
||||
stats = lib.get_aligment_stats(
|
||||
domain, self.request.query_params.get("period")
|
||||
)
|
||||
except ValueError:
|
||||
return response.Response("Invalid range received", status=400)
|
||||
serializer = self.get_serializer(stats)
|
||||
return response.Response(serializer.data)
|
||||
@@ -0,0 +1,16 @@
|
||||
"""AppConfig for dmarc."""
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
from modoboa.dmarc.forms import load_settings
|
||||
|
||||
|
||||
class DmarcConfig(AppConfig):
|
||||
"""App configuration."""
|
||||
|
||||
name = "modoboa.dmarc"
|
||||
verbose_name = "Modoboa DMARC tools"
|
||||
|
||||
def ready(self):
|
||||
load_settings()
|
||||
from . import handlers
|
||||
@@ -0,0 +1,10 @@
|
||||
"""DMARC constants."""
|
||||
|
||||
ALLOWED_REASON_TYPES = (
|
||||
"forwarded",
|
||||
"sampled_out",
|
||||
"trusted_forwarder",
|
||||
"mailing_list",
|
||||
"local_policy",
|
||||
"other"
|
||||
)
|
||||
@@ -0,0 +1,51 @@
|
||||
"""Custom forms."""
|
||||
|
||||
from django import forms
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from modoboa.lib import form_utils
|
||||
from modoboa.parameters import forms as param_forms
|
||||
|
||||
|
||||
class ReportOptionsForm(forms.Form):
|
||||
"""Report display options."""
|
||||
|
||||
current_year = forms.IntegerField(widget=forms.widgets.HiddenInput)
|
||||
current_week = forms.IntegerField()
|
||||
query = forms.ChoiceField(
|
||||
choices=[("previous", "Previous"), ("next", "Next")])
|
||||
resolve_hostnames = forms.BooleanField(
|
||||
initial=False, required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Constructor."""
|
||||
super(ReportOptionsForm, self).__init__(*args, **kwargs)
|
||||
if not args:
|
||||
year, week, day = timezone.now().isocalendar()
|
||||
self.fields["current_year"].initial = year
|
||||
self.fields["current_week"].initial = week
|
||||
|
||||
|
||||
class ParametersForm(param_forms.AdminParametersForm):
|
||||
"""Extension settings."""
|
||||
|
||||
app = "dmarc"
|
||||
|
||||
qsettings_sep = form_utils.SeparatorField(label=_("DNS settings"))
|
||||
|
||||
enable_rlookups = form_utils.YesNoField(
|
||||
label=_("Enable reverse lookups"),
|
||||
initial=False,
|
||||
help_text=_(
|
||||
"Enable reverse DNS lookups (reports will be longer to display)"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def load_settings():
|
||||
"""Load app settings."""
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
param_tools.registry.add(
|
||||
"global", ParametersForm, _("DMARC"))
|
||||
@@ -0,0 +1,22 @@
|
||||
"""Django signal handlers for modoboa_dmarc."""
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.dispatch import receiver
|
||||
|
||||
from modoboa.admin import signals as admin_signals
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
@receiver(admin_signals.extra_domain_actions)
|
||||
def dmarc_domain_actions(sender, user, domain, **kwargs):
|
||||
"""Return a link to access domain report."""
|
||||
if not models.Record.objects.filter(header_from=domain).exists():
|
||||
return []
|
||||
return [{
|
||||
"name": "dmarc_report",
|
||||
"url": reverse("dmarc:domain_report", args=[domain.pk]),
|
||||
"title": _("Show DMARC report for {}").format(domain.name),
|
||||
"img": "fa fa-pie-chart"
|
||||
}]
|
||||
@@ -0,0 +1,309 @@
|
||||
"""Internal library."""
|
||||
|
||||
import concurrent.futures
|
||||
import datetime
|
||||
import email
|
||||
import fileinput
|
||||
import getpass
|
||||
import imaplib
|
||||
import zipfile
|
||||
import gzip
|
||||
import sys
|
||||
import tldextract
|
||||
|
||||
from defusedxml.ElementTree import fromstring
|
||||
from dns import resolver, reversename
|
||||
import magic
|
||||
import pytz.exceptions
|
||||
import six
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from modoboa.admin import models as admin_models
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
from . import constants
|
||||
from . import models
|
||||
|
||||
ZIP_CONTENT_TYPES = [
|
||||
"application/x-zip-compressed",
|
||||
"application/x-zip",
|
||||
"application/zip",
|
||||
"application/gzip",
|
||||
"application/octet-stream",
|
||||
"text/xml",
|
||||
]
|
||||
|
||||
FILE_TYPES = [
|
||||
"text/plain",
|
||||
"text/xml",
|
||||
]
|
||||
|
||||
|
||||
def import_record(xml_node, report):
|
||||
"""Import a record."""
|
||||
record = models.Record(report=report)
|
||||
row = xml_node.find("row")
|
||||
record.source_ip = row.find("source_ip").text
|
||||
record.count = int(row.find("count").text)
|
||||
|
||||
policy_evaluated = row.find("policy_evaluated")
|
||||
record.disposition = policy_evaluated.find("disposition").text
|
||||
record.dkim_result = policy_evaluated.find("dkim").text
|
||||
record.spf_result = policy_evaluated.find("spf").text
|
||||
reason = policy_evaluated.find("reason")
|
||||
if reason:
|
||||
record.reason_type = smart_text(reason.find("type").text)[:14]
|
||||
if record.reason_type not in constants.ALLOWED_REASON_TYPES:
|
||||
record.reason_type = "other"
|
||||
comment = reason.find("comment").text or ""
|
||||
record.reason_comment = comment
|
||||
|
||||
identifiers = xml_node.find("identifiers")
|
||||
header_from = identifiers.find("header_from").text.split(".")
|
||||
domain = None
|
||||
while len(header_from) >= 2:
|
||||
domain = admin_models.Domain.objects.filter(
|
||||
name=".".join(header_from)).first()
|
||||
if domain is not None:
|
||||
record.header_from = domain
|
||||
break
|
||||
header_from = header_from[1:]
|
||||
if domain is None:
|
||||
print("Invalid record found (domain not local)")
|
||||
return None
|
||||
|
||||
record.save()
|
||||
auth_results = xml_node.find("auth_results")
|
||||
for rtype in ["spf", "dkim"]:
|
||||
rnode = auth_results.find(rtype)
|
||||
if not rnode:
|
||||
continue
|
||||
models.Result.objects.create(
|
||||
record=record, type=rtype, domain=rnode.find("domain").text,
|
||||
result=rnode.find("result").text)
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def import_report(content):
|
||||
"""Import an aggregated report."""
|
||||
root = fromstring(content, forbid_dtd=True)
|
||||
metadata = root.find("report_metadata")
|
||||
print(
|
||||
"Importing report {} received from {}".format(
|
||||
metadata.find("report_id").text,
|
||||
metadata.find("org_name").text)
|
||||
)
|
||||
reporter, created = models.Reporter.objects.get_or_create(
|
||||
email=metadata.find("email").text,
|
||||
defaults={"org_name": metadata.find("org_name").text}
|
||||
)
|
||||
qs = models.Report.objects.filter(
|
||||
reporter=reporter, report_id=metadata.find("report_id").text)
|
||||
if qs.exists():
|
||||
print("Report already imported.")
|
||||
return
|
||||
report = models.Report(reporter=reporter)
|
||||
|
||||
report.report_id = metadata.find("report_id").text
|
||||
date_range = metadata.find("date_range")
|
||||
report.start_date = timezone.make_aware(
|
||||
datetime.datetime.fromtimestamp(int(date_range.find("begin").text))
|
||||
)
|
||||
report.end_date = timezone.make_aware(
|
||||
datetime.datetime.fromtimestamp(int(date_range.find("end").text))
|
||||
)
|
||||
|
||||
policy_published = root.find("policy_published")
|
||||
for attr in ["domain", "adkim", "aspf", "p", "sp", "pct"]:
|
||||
node = policy_published.find(attr)
|
||||
if node is None or not node.text:
|
||||
if attr == "sp":
|
||||
node = fromstring('<sp>unstated</sp>', forbid_dtd=True)
|
||||
else:
|
||||
print(f"Report skipped because of malformed data (empty {attr})")
|
||||
return
|
||||
value = setattr(report, "policy_{}".format(attr), node.text)
|
||||
try:
|
||||
report.save()
|
||||
except (pytz.exceptions.AmbiguousTimeError):
|
||||
print("Report skipped because of invalid date.")
|
||||
return
|
||||
for record in root.findall("record"):
|
||||
import_record(record, report)
|
||||
|
||||
|
||||
def import_archive(archive, content_type=None):
|
||||
"""Import reports contained inside (file pointer)
|
||||
- a zip archive,
|
||||
- a gzip file,
|
||||
- a xml file.
|
||||
"""
|
||||
if content_type == "text/xml":
|
||||
import_report(archive.read())
|
||||
elif content_type in ["application/gzip", "application/octet-stream"]:
|
||||
with gzip.GzipFile(mode="r", fileobj=archive) as zfile:
|
||||
import_report(zfile.read())
|
||||
else:
|
||||
with zipfile.ZipFile(archive, "r") as zfile:
|
||||
for fname in zfile.namelist():
|
||||
import_report(zfile.read(fname))
|
||||
|
||||
|
||||
def import_report_from_email(content):
|
||||
"""Import a report from an email."""
|
||||
if isinstance(content, six.string_types):
|
||||
msg = email.message_from_string(content)
|
||||
elif isinstance(content, six.binary_type):
|
||||
msg = email.message_from_bytes(content)
|
||||
else:
|
||||
msg = email.message_from_file(content)
|
||||
err = False
|
||||
for part in msg.walk():
|
||||
if part.get_content_type() not in ZIP_CONTENT_TYPES:
|
||||
continue
|
||||
try:
|
||||
fpo = six.BytesIO(part.get_payload(decode=True))
|
||||
# Try to get the actual file type of the buffer
|
||||
# required to make sure we are dealing with an XML file
|
||||
file_type = magic.Magic(uncompress=True, mime=True).from_buffer(fpo.read(2048))
|
||||
fpo.seek(0)
|
||||
if file_type in FILE_TYPES:
|
||||
import_archive(fpo, content_type=part.get_content_type())
|
||||
except (OSError, IOError):
|
||||
print('Error: the attachment does not match the mimetype')
|
||||
err = True
|
||||
else:
|
||||
fpo.close()
|
||||
if err:
|
||||
# Return EX_DATAERR code <data format error> available
|
||||
# at sysexits.h file
|
||||
# (see http://www.postfix.org/pipe.8.html)
|
||||
sys.exit(65)
|
||||
|
||||
|
||||
def import_report_from_stdin():
|
||||
"""Parse a report from stdin."""
|
||||
content = six.StringIO()
|
||||
for line in fileinput.input([]):
|
||||
content.write(line)
|
||||
content.seek(0)
|
||||
|
||||
if not content:
|
||||
return
|
||||
import_report_from_email(content)
|
||||
|
||||
|
||||
def import_from_imap(options):
|
||||
"""Import reports from an IMAP mailbox."""
|
||||
obj = imaplib.IMAP4_SSL if options["ssl"] else imaplib.IMAP4
|
||||
conn = obj(options["host"])
|
||||
username = input("Username: ")
|
||||
password = getpass.getpass(prompt="Password: ")
|
||||
conn.login(username, password)
|
||||
conn.select(options["mailbox"])
|
||||
type, msg_ids = conn.search(None, "ALL")
|
||||
for msg_id in msg_ids[0].split():
|
||||
typ, content = conn.fetch(msg_id, "(RFC822)")
|
||||
for response_part in content:
|
||||
if isinstance(response_part, tuple):
|
||||
import_report_from_email(response_part[1])
|
||||
conn.close()
|
||||
|
||||
|
||||
def week_range(year, weeknumber):
|
||||
"""Return start and end dates of a given week."""
|
||||
tz = timezone.get_current_timezone()
|
||||
fmt = "%Y-%W-%w"
|
||||
start_week = datetime.datetime.strptime(
|
||||
"{}-{}-{}".format(year, weeknumber, 1), fmt)
|
||||
end_week = datetime.datetime.strptime(
|
||||
"{}-{}-{}".format(year, weeknumber, 0), fmt)
|
||||
return tz.localize(start_week), tz.localize(end_week)
|
||||
|
||||
|
||||
def insert_record(target: dict, record, name: str) -> None:
|
||||
"""Add a record."""
|
||||
if name not in target:
|
||||
target[name] = {}
|
||||
|
||||
if record.source_ip not in target[name]:
|
||||
target[name][record.source_ip] = {
|
||||
"total": 0,
|
||||
"spf": {"success": 0, "failure": 0},
|
||||
"dkim": {"success": 0, "failure": 0}
|
||||
}
|
||||
target[name][record.source_ip]["total"] += record.count
|
||||
for typ in ["spf", "dkim"]:
|
||||
result = getattr(record, "{}_result".format(typ))
|
||||
key = "success" if result == "pass" else "failure"
|
||||
target[name][record.source_ip][typ][key] += record.count
|
||||
|
||||
|
||||
def get_aligment_stats(domain, period=None) -> dict:
|
||||
"""Retrieve aligment statistics for given domain."""
|
||||
if not period:
|
||||
year, week, day = timezone.now().isocalendar()
|
||||
week -= 1
|
||||
period = f"{year}-{week}"
|
||||
else:
|
||||
year, week = period.split("-")
|
||||
if not year or not week:
|
||||
period = f"{year}-{week}"
|
||||
|
||||
daterange = week_range(year, week)
|
||||
qargs = (
|
||||
(Q(report__start_date__gte=daterange[0],
|
||||
report__start_date__lte=daterange[1]) |
|
||||
Q(report__end_date__gte=daterange[0],
|
||||
report__end_date__lte=daterange[1])) &
|
||||
Q(header_from=domain)
|
||||
)
|
||||
all_records = models.Record.objects.select_related().filter(qargs)
|
||||
stats = {
|
||||
"aligned": {},
|
||||
"trusted": {},
|
||||
"forwarded": {},
|
||||
"failed": {}
|
||||
}
|
||||
|
||||
dns_names = {}
|
||||
if param_tools.get_global_parameter("enable_rlookups"):
|
||||
dns_resolver = resolver.Resolver()
|
||||
dns_resolver.timeout = 1.0
|
||||
dns_resolver.lifetime = 1.0
|
||||
|
||||
def get_domain_name_from_ip(ip):
|
||||
addr = reversename.from_address(ip)
|
||||
try:
|
||||
resp = dns_resolver.query(addr, "PTR")
|
||||
ext = tldextract.extract(str(resp[0].target))
|
||||
if not ext.suffix: # invalid PTR record
|
||||
raise resolver.NXDOMAIN()
|
||||
return (ip, '.'.join((ext.domain, ext.suffix)).lower())
|
||||
except (resolver.NXDOMAIN, resolver.YXDOMAIN,
|
||||
resolver.NoAnswer, resolver.NoNameservers,
|
||||
resolver.Timeout):
|
||||
return (None, None)
|
||||
|
||||
ips = (r.source_ip for r in all_records)
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=16) as pool:
|
||||
dns_names = {i: n for (i, n) in
|
||||
list(pool.map(get_domain_name_from_ip, ips))}
|
||||
|
||||
for record in all_records:
|
||||
name = dns_names.get(record.source_ip, _("Not resolved"))
|
||||
if record.dkim_result == "pass" and record.spf_result == "pass":
|
||||
insert_record(stats["aligned"], record, name)
|
||||
elif record.dkim_result == "pass" or record.spf_result == "pass":
|
||||
insert_record(stats["trusted"], record, name)
|
||||
elif record.reason_type == "local_policy" and record.reason_comment.startswith("arc=pass"):
|
||||
insert_record(stats["forwarded"], record, name)
|
||||
else:
|
||||
insert_record(stats["failed"], record, name)
|
||||
|
||||
return stats
|
||||
@@ -0,0 +1,138 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Irriep Nala Novram <allannkorh@yahoo.fr>, 2019
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2020-05-06 12:07+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Breton (http://www.transifex.com/tonio/modoboa/language/br/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: br\n"
|
||||
"Plural-Forms: nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr "Arventennoù DNS"
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr "Enaouiñ an enklaskoù eilpennet"
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr "Enaouiñ an enklaskoù DNS eilpennet (danevelloù a vo hiroc'h da vezañ diskouezet)"
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Diskouez an danevell DMARC evit {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Hini ebet"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Dispell"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Nac'hañ"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neptu"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Tremen"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Sac'hadenn"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Fazi padennek"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Fazi peurbadus"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Politikerezh"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Sac'hadenn wan"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "Ostilhoù DMARC"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Un dastumad ostilhoù da aesaat enframmañ DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Hollad"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Linennet penn-da-benn"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Linennet dre an hanter"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "C'hwitet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "Danevell DMARC evit"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "tretet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "linennet penn-da-benn"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "linennet dre an hanter"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "c'hwitet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Diskouez ar munudoù"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Mammennoù fizius"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Mammennoù dizanv/Gourdrouzioù"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,139 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Jan Laufik, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Czech (Czech Republic) (http://www.transifex.com/tonio/"
|
||||
"modoboa/language/cs_CZ/)\n"
|
||||
"Language: cs_CZ\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Zobrazit DMARC zprávu pro {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Nic"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Karanténa"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Odmítnout"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutrální"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Úspěch"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Selhání"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Dočasná chyba"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Permanentní chyba"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Politika"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Selhání bez odmítnutí"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "DMARC nástroje"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Sada nástrojů pro zjednodušení integrace DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Celkem"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Plně v souladu"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Částečně v souladu"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Selhalo"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "DMARC zpráva pro"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "zpracované"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "plně v souladu"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "částečně v souladu"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "selhalo"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Zobrazit podrobnosti"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Důvěryhodné zdroje"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Neznáme zdroje / Hrozby"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,139 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# controlc.de, 2015
|
||||
# Tobias Strobel, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: German (http://www.transifex.com/tonio/modoboa/language/de/)\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "DMARC-Bericht für {} anzeigen"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Nichts"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Quarantäne"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Ablehnung"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutral"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Genehmigen"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Abbruch"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Temporärer Fehler"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Permanenter Fehler"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Richtlinie"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Schwacher Fehler"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "DMARC-Tools"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Ein Set von Tools um die DMARC-Integration zu vereinfachen"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Total"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Voll zugeordnet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Teilweise zugeordnet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Fehlgeschlagen"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "DMARC-Bericht für"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "durchgeführt"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "voll zugeordnet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "teilweise zugeordnet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "fehlgeschlagen"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Anzeigedetails"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Vertraute Quellen"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Unbekannte Quellen / Bedrohungen"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,140 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Giannis Kapetanakis <bilias@edu.physics.uoc.gr>, 2016
|
||||
# Kostas Moumouris <moumouriskostas@gmail.com>, 2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-10-12 09:55+0000\n"
|
||||
"Last-Translator: Kostas Moumouris <moumouriskostas@gmail.com>\n"
|
||||
"Language-Team: Greek (Greece) (http://www.transifex.com/tonio/modoboa/"
|
||||
"language/el_GR/)\n"
|
||||
"Language: el_GR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr "Ρυθμίσεις DNS"
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr "Ενεργοποίηση ανάστροφης αναζήτησης reverse lookups"
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr "Ενεργοποίηση reverse DNS lookups (η αναφορές θα καθυστερούν)"
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Εμφάνιση της έκθεσης DMARC του {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Κανένα"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Καραντίνα"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Απόρριψη"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Ουδέτερο"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Εγκρίθηκε"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Απορρίφθηκε"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "προσωρινό σφάλμα"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Μόνιμο σφάλμα"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Πολιτική"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Πρόβλημα Soft"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "Εργαλεία DMARC"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Ένα σετ εργαλείων για την απλοποίηση της ενσωμάτωσης του DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Σύνολο"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Πλήρως ευθυγραμμισμένο"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Μερικός ευθυγραμισμένα"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Απέτυχε"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "Έκθεση DMARC του"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "Επεξεργάστηκε"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "πλήρως ευθυγραμμισμένο"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "Μερικώς ευθυγραμμισμένο"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "απέτυχε"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Προβολή λεπτομερειών"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Αξιόπιστες πηγές"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Άγνωστες πηγές / Απειλές"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,137 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr ""
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr ""
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr ""
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr ""
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,138 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Antoine Nguyen <tonio@ngyn.org>, 2017,2020
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2020-05-06 12:07+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: French (http://www.transifex.com/tonio/modoboa/language/fr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: fr\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr "Paramètres DNS"
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr "Activer les recherches inversées"
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr "Activer les recherches DNS inversées (les rapports seront plus longs à afficher)"
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Afficher le rapport DMARC pour {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Quarantaine"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Rejeter"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutre"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Succès"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Echec"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Erreur temporaire"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Erreur permanente"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Politique"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Erreur soft"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "Outils DMARC"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Un jeu d'outils pour faciliter l'intégration de DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Total"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Alignement complet"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Alignement partiel"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "En échec"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "Rapport DMARC pour"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "traité(s)"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "complètement aligné(s)"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "partiellement aligné(s)"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "en échec"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Afficher les détails"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Sources de confiance"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Sources inconnues / Menaces"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr "Non résolu"
|
||||
@@ -0,0 +1,139 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Rocco <mors10@hotmail.com>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Italian (http://www.transifex.com/tonio/modoboa/language/"
|
||||
"it/)\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Mostra DMARC report per {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Nessuno"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Quarantina"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Rifiuta"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutrale"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Passa"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Fallito"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Errore temporaneo"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Errore permanente"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Policy"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Piccolo problema"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "Strumenti DMARC"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Una serie di strumenti per facilitare l'integrazione DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Totale"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Completamente allineato"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Parzialmente allineato"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Fallito"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "Rapporto DMARC per"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "Processati"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "Completamente allineato"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "Allineato parzialmente"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "Fallito"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Mostra dettagli"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Fonti attendibili"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Fonti sconosciute / Minaccie"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,139 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# cwatanab <chihiro.watanabe@live.jp>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Japanese (Japan) (http://www.transifex.com/tonio/modoboa/"
|
||||
"language/ja_JP/)\n"
|
||||
"Language: ja_JP\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "{} の DMARC レポートを表示"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "None"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Quarantine"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Reject"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutral"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Pass"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Fail"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Temporary error"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Permanent error"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Policy"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Soft failure"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "DMARC ツール"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "DMARC 統合のためのツールセット"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Total"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Fully aligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Partially aligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Failed"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "DMARC レポート"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "processed"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "fully aligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "partially aligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "failed"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "詳細を表示"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Trusted sources"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Unknown sources / Threats"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,141 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Harrie v.d. Vegt <hvdvegt@gmail.com>, 2016
|
||||
# Tuxis Internet Engineering V.O.F. <info@tuxis.nl>, 2016
|
||||
# Tuxis Internet Engineering V.O.F. <info@tuxis.nl>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/tonio/modoboa/"
|
||||
"language/nl_NL/)\n"
|
||||
"Language: nl_NL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Toon DMARC rapportage voor {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Geen"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Quarantaine"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Afkeuren"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutraal"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Gelukt"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Mislukt"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Tijdelijke fout"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Permanente fout"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Beleid"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Toegestane fout"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "DMARC gereedschappen"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Een aantal eenvoudige programmas DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Totaal"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Volledig alligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Gedeeltelijk alligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Mislukt"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "DMARC rapportage voor"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "verwerkt"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "volledig alligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "gedeeltelijk alligned"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "mislukt"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Toon details"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Vertrouwde bronnen"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Onbekende bronnen / bedreigingen"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,139 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Paulino Michelazzo <paulino@michelazzo.com.br>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/tonio/modoboa/"
|
||||
"language/pt_BR/)\n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Mostrar relatório DMARC para {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Quarentena"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Rejeitado"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Neutro"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Passou"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Falha"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Erro temporário"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Erro permanente"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Política"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Falha leve"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "Ferramentas DMARC"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "Um conjunto de ferramentas para fácil integração do DMARC"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Total"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Completamente alinhado"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Parcialmente alinhado"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Falha"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "Relatório DMARC para"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "processado"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "completamente alinhado"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "parcialmente alinhado"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "falho"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Mostrar detalhes"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Fontes confiáveis"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Fontes desconhecidas / Ameaças"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,139 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Olle Gustafsson <olle@dalnix.se>, 2016
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Modoboa\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-05-06 14:05+0200\n"
|
||||
"PO-Revision-Date: 2017-03-03 08:18+0000\n"
|
||||
"Last-Translator: Antoine Nguyen <tonio@ngyn.org>\n"
|
||||
"Language-Team: Swedish (http://www.transifex.com/tonio/modoboa/language/"
|
||||
"sv/)\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: forms.py:35
|
||||
msgid "DNS settings"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:38
|
||||
msgid "Enable reverse lookups"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:41
|
||||
msgid "Enable reverse DNS lookups (reports will be longer to display)"
|
||||
msgstr ""
|
||||
|
||||
#: handlers.py:20
|
||||
msgid "Show DMARC report for {}"
|
||||
msgstr "Visa DMARC rapport för {}"
|
||||
|
||||
#: models.py:10 models.py:16
|
||||
msgid "None"
|
||||
msgstr "Inga"
|
||||
|
||||
#: models.py:11
|
||||
msgid "Quarantine"
|
||||
msgstr "Karantän"
|
||||
|
||||
#: models.py:12
|
||||
msgid "Reject"
|
||||
msgstr "Avvisa"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Neutral"
|
||||
msgstr "Netural"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Pass"
|
||||
msgstr "Passera"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Fail"
|
||||
msgstr "Avslå"
|
||||
|
||||
#: models.py:20
|
||||
msgid "Temporary error"
|
||||
msgstr "Tillfälligt fel"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Permanent error"
|
||||
msgstr "Permanent fel"
|
||||
|
||||
#: models.py:25
|
||||
msgid "Policy"
|
||||
msgstr "Policy"
|
||||
|
||||
#: models.py:29
|
||||
msgid "Soft failure"
|
||||
msgstr "Mjukt misslyckande"
|
||||
|
||||
#: modo_extension.py:16
|
||||
msgid "DMARC tools"
|
||||
msgstr "DMARC verktyg"
|
||||
|
||||
#: modo_extension.py:19
|
||||
msgid "A set of tools to ease DMARC integration"
|
||||
msgstr "En uppsättning verktyg för att underlätta DMARC integration"
|
||||
|
||||
#: templates/modoboa_dmarc/_result_detail.html:6
|
||||
msgid "Total"
|
||||
msgstr "Totalt"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:21
|
||||
#: templates/modoboa_dmarc/domain_report.html:26
|
||||
msgid "Fully aligned"
|
||||
msgstr "Helt i linje"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:22
|
||||
#: templates/modoboa_dmarc/domain_report.html:27
|
||||
msgid "Partially aligned"
|
||||
msgstr "Delvis i linje"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:23
|
||||
#: templates/modoboa_dmarc/domain_report.html:28
|
||||
msgid "Failed"
|
||||
msgstr "Misslyckades"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:50
|
||||
msgid "DMARC report for"
|
||||
msgstr "DMARC rapport för"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:74
|
||||
msgid "processed"
|
||||
msgstr "bearbetats"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:83
|
||||
msgid "fully aligned"
|
||||
msgstr "helt i linje"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:92
|
||||
msgid "partially aligned"
|
||||
msgstr "delvis i linje"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:101
|
||||
msgid "failed"
|
||||
msgstr "misslyckades"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:111
|
||||
msgid "Display details"
|
||||
msgstr "Visa detaljer"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:115
|
||||
msgid "Trusted sources"
|
||||
msgstr "Betrodda källor"
|
||||
|
||||
#: templates/modoboa_dmarc/domain_report.html:123
|
||||
msgid "Unknown sources / Threats"
|
||||
msgstr "Okända källor / Hot"
|
||||
|
||||
#: templatetags/dmarc_tags.py:59 views.py:120
|
||||
msgid "Not resolved"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,40 @@
|
||||
"""Import a DMARC aggregated report."""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from ... import lib
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Command definition."""
|
||||
|
||||
help = "Import DMARC aggregated reports."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
"""Add extra arguments to parser."""
|
||||
parser.add_argument(
|
||||
"--pipe", action="store_true", default=False,
|
||||
help="Import a report from an email given on stdin")
|
||||
parser.add_argument(
|
||||
"--imap", action="store_true", default=False,
|
||||
help="Import a report from an IMAP mailbox")
|
||||
parser.add_argument(
|
||||
"--host", default="localhost",
|
||||
help="IMAP host")
|
||||
parser.add_argument(
|
||||
"--ssl", action="store_true", default=False,
|
||||
help="Connect using SSL"),
|
||||
parser.add_argument(
|
||||
"--mailbox", default="INBOX",
|
||||
help="IMAP mailbox to import reports from")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""Entry point."""
|
||||
if options.get("pipe"):
|
||||
lib.import_report_from_stdin()
|
||||
elif options.get("imap"):
|
||||
lib.import_from_imap(options)
|
||||
else:
|
||||
print("Nothing to do.")
|
||||
@@ -0,0 +1,90 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('admin', '0002_migrate_from_modoboa_admin'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Record',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('source_ip', models.GenericIPAddressField()),
|
||||
('count', models.IntegerField()),
|
||||
('disposition', models.CharField(max_length=10, choices=[(b'none', 'None'), (b'quarantine', 'Quarantine'), (b'reject', 'Reject')])),
|
||||
('dkim_result', models.CharField(max_length=9, choices=[(b'none', 'None'), (b'neutral', 'Neutral'), (b'pass', 'Pass'), (b'fail', 'Fail'), (b'temperror', 'Temporary error'), (b'permerror', 'Permanent error'), (b'policy', 'Policy')])),
|
||||
('spf_result', models.CharField(max_length=9, choices=[(b'none', 'None'), (b'neutral', 'Neutral'), (b'pass', 'Pass'), (b'fail', 'Fail'), (b'temperror', 'Temporary error'), (b'permerror', 'Permanent error'), (b'softfail', 'Soft failure')])),
|
||||
('reason_type', models.CharField(max_length=15, blank=True)),
|
||||
('reason_comment', models.CharField(max_length=100, blank=True)),
|
||||
('header_from', models.ForeignKey(to='admin.Domain', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Report',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('report_id', models.CharField(max_length=100)),
|
||||
('start_date', models.DateTimeField()),
|
||||
('end_date', models.DateTimeField()),
|
||||
('policy_domain', models.CharField(max_length=100)),
|
||||
('policy_adkim', models.CharField(max_length=1)),
|
||||
('policy_aspf', models.CharField(max_length=1)),
|
||||
('policy_p', models.CharField(max_length=10)),
|
||||
('policy_sp', models.CharField(max_length=10)),
|
||||
('policy_pct', models.SmallIntegerField()),
|
||||
],
|
||||
options={
|
||||
'permissions': (('view_report', 'Can view report'),),
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Reporter',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('org_name', models.CharField(max_length=100)),
|
||||
('email', models.EmailField(unique=True, max_length=254)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Result',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('type', models.CharField(max_length=4, choices=[(b'dkim', b'DKIM'), (b'spf', b'SPF')])),
|
||||
('domain', models.CharField(max_length=100)),
|
||||
('result', models.CharField(max_length=9)),
|
||||
('record', models.ForeignKey(to='dmarc.Record', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='report',
|
||||
name='reporter',
|
||||
field=models.ForeignKey(to='dmarc.Reporter', on_delete=models.CASCADE),
|
||||
preserve_default=True,
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='report',
|
||||
unique_together=set([('reporter', 'report_id')]),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='record',
|
||||
name='report',
|
||||
field=models.ForeignKey(to='dmarc.Report', on_delete=models.CASCADE),
|
||||
preserve_default=True,
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.8 on 2018-01-24 23:11
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dmarc', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='record',
|
||||
name='disposition',
|
||||
field=models.CharField(choices=[('none', 'None'), ('quarantine', 'Quarantine'), ('reject', 'Reject')], max_length=10),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='record',
|
||||
name='dkim_result',
|
||||
field=models.CharField(choices=[('none', 'None'), ('neutral', 'Neutral'), ('pass', 'Pass'), ('fail', 'Fail'), ('temperror', 'Temporary error'), ('permerror', 'Permanent error'), ('policy', 'Policy')], max_length=9),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='record',
|
||||
name='spf_result',
|
||||
field=models.CharField(choices=[('none', 'None'), ('neutral', 'Neutral'), ('pass', 'Pass'), ('fail', 'Fail'), ('temperror', 'Temporary error'), ('permerror', 'Permanent error'), ('softfail', 'Soft failure')], max_length=9),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='result',
|
||||
name='type',
|
||||
field=models.CharField(choices=[('dkim', 'DKIM'), ('spf', 'SPF')], max_length=4),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 2.2.9 on 2020-02-27 08:36
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dmarc', '0002_auto_20180124_2311'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='report',
|
||||
options={},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 3.2.12 on 2022-09-26 07:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dmarc', '0003_auto_20200227_0936'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='record',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='report',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='reporter',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='result',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,104 @@
|
||||
"""DMARC models."""
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from modoboa.admin import models as admin_models
|
||||
|
||||
|
||||
POLICY_DISPOSITIONS = [
|
||||
("none", _("None")),
|
||||
("quarantine", _("Quarantine")),
|
||||
("reject", _("Reject"))
|
||||
]
|
||||
|
||||
COMMON_RESULTS = [
|
||||
("none", _("None")),
|
||||
("neutral", _("Neutral")),
|
||||
("pass", _("Pass")),
|
||||
("fail", _("Fail")),
|
||||
("temperror", _("Temporary error")),
|
||||
("permerror", _("Permanent error"))
|
||||
]
|
||||
|
||||
DKIM_RESULTS = COMMON_RESULTS + [
|
||||
("policy", _("Policy"))
|
||||
]
|
||||
|
||||
SPF_RESULTS = COMMON_RESULTS + [
|
||||
("softfail", _("Soft failure"))
|
||||
]
|
||||
|
||||
RECORD_TYPES = [
|
||||
("dkim", "DKIM"),
|
||||
("spf", "SPF"),
|
||||
]
|
||||
|
||||
|
||||
class Reporter(models.Model):
|
||||
|
||||
"""Report issuers."""
|
||||
|
||||
org_name = models.CharField(max_length=100)
|
||||
email = models.EmailField(unique=True)
|
||||
|
||||
def __str__(self):
|
||||
"""Return name and email."""
|
||||
return "{} <{}>".format(self.org_name, self.email)
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
|
||||
"""Aggregated reports."""
|
||||
|
||||
report_id = models.CharField(max_length=100)
|
||||
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
|
||||
start_date = models.DateTimeField()
|
||||
end_date = models.DateTimeField()
|
||||
|
||||
# Published policy
|
||||
policy_domain = models.CharField(max_length=100)
|
||||
policy_adkim = models.CharField(max_length=1)
|
||||
policy_aspf = models.CharField(max_length=1)
|
||||
policy_p = models.CharField(max_length=10)
|
||||
policy_sp = models.CharField(max_length=10)
|
||||
policy_pct = models.SmallIntegerField()
|
||||
|
||||
class Meta:
|
||||
unique_together = ("reporter", "report_id")
|
||||
|
||||
def __str__(self):
|
||||
"""Display provider and dates."""
|
||||
return "{}: {} -> {}".format(
|
||||
self.reporter, self.start_date, self.end_date)
|
||||
|
||||
|
||||
class Record(models.Model):
|
||||
|
||||
"""Report records."""
|
||||
|
||||
report = models.ForeignKey(Report, on_delete=models.CASCADE)
|
||||
source_ip = models.GenericIPAddressField()
|
||||
count = models.IntegerField()
|
||||
|
||||
# Policy evaluated
|
||||
disposition = models.CharField(
|
||||
max_length=10, choices=POLICY_DISPOSITIONS)
|
||||
dkim_result = models.CharField(
|
||||
max_length=9, choices=DKIM_RESULTS)
|
||||
spf_result = models.CharField(
|
||||
max_length=9, choices=SPF_RESULTS)
|
||||
header_from = models.ForeignKey(admin_models.Domain,
|
||||
on_delete=models.CASCADE)
|
||||
reason_type = models.CharField(max_length=15, blank=True)
|
||||
reason_comment = models.CharField(max_length=100, blank=True)
|
||||
|
||||
|
||||
class Result(models.Model):
|
||||
|
||||
"""Record results."""
|
||||
|
||||
record = models.ForeignKey(Record, on_delete=models.CASCADE)
|
||||
type = models.CharField(max_length=4, choices=RECORD_TYPES)
|
||||
domain = models.CharField(max_length=100)
|
||||
result = models.CharField(max_length=9)
|
||||
@@ -0,0 +1,27 @@
|
||||
{% load i18n %}
|
||||
|
||||
<tr>
|
||||
<th>{{ domain }}</th>
|
||||
{% if forloop.first %}
|
||||
<th class="text-center">{% trans "Total" %}</th>
|
||||
<th class="text-center">SPF</th>
|
||||
<th class="text-center">DKIM</th>
|
||||
{% else %}
|
||||
<th colspan="3"></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
||||
{% for ip_address, results in stats.items %}
|
||||
<tr>
|
||||
<td class="col-sm-6">{{ ip_address }}</td>
|
||||
<td class="col-sm-2 text-center">{{ results.total }}</td>
|
||||
<td class="col-sm-2 text-center">
|
||||
{% if not only_failed %}<span class="label label-success">{{ results.spf.pass }}</span>{% endif %}
|
||||
<span class="label label-danger">{{ results.spf.fail }}</span>
|
||||
</td>
|
||||
<td class="col-sm-2 text-center">
|
||||
{% if not only_failed %}<span class="label label-success">{{ results.dkim.pass }}</span>{% endif %}
|
||||
<span class="label label-danger">{{ results.dkim.fail }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,159 @@
|
||||
{% extends "admin/domains.html" %}
|
||||
|
||||
{% load i18n l10n %}
|
||||
{% load static %}
|
||||
{% load admin_tags %}
|
||||
{% load dmarc_tags %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ STATIC_URL }}c3/c3.min.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}d3/d3.min.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}c3/c3.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var pie_chart = c3.generate({
|
||||
bindto: '#global_distribution',
|
||||
data: {
|
||||
columns: [
|
||||
['{% trans "Fully aligned" %}', {{ pie_data.faligned|unlocalize }}],
|
||||
['{% trans "Partially aligned" %}', {{ pie_data.paligned|unlocalize }}],
|
||||
['{% trans "Forwarded" %}', {{ pie_data.forwarded|unlocalize }}],
|
||||
['{% trans "Failed" %}', {{ pie_data.failed|unlocalize }}]
|
||||
],
|
||||
colors: {
|
||||
'{% trans "Fully aligned" %}': 'limegreen',
|
||||
'{% trans "Partially aligned" %}': 'gold',
|
||||
'{% trans "Forwarded" %}': 'lightskyblue',
|
||||
'{% trans "Failed" %}': 'lightcoral',
|
||||
},
|
||||
type : 'pie'
|
||||
}
|
||||
});
|
||||
$("#show-report-detail").click(function(evt) {
|
||||
$("#report-details").show();
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block leftcol %}
|
||||
<ul class="nav nav-sidebar">
|
||||
{% domains_menu "dmarc" user False %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block apparea %}
|
||||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
<h1><small>{% trans "DMARC report for" %} {{ domain }}</small></h1>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body text-center">
|
||||
<a href="{% url 'dmarc:domain_report' domain.pk %}?period={% previous_period period %}" name="prevweek"><span class="fa fa-chevron-left"></span></a>
|
||||
{{ daterange.0|date }} - {{ daterange.1|date }}
|
||||
<a href="{% url 'dmarc:domain_report' domain.pk %}?period={% next_period period %}" name="nextweek"><span class="fa fa-chevron-right"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-5">
|
||||
<div id="global_distribution"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-7">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-primary text-center">
|
||||
<div class="panel-body">
|
||||
<h1 class="text-primary">{{ stats.total }}</h1>
|
||||
<h4>{% trans "processed" %}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-success text-center">
|
||||
<div class="panel-body">
|
||||
<h1 class="text-success" >{{ stats.aligned }}</h1>
|
||||
<h4>{% trans "fully aligned" %}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-warning text-center">
|
||||
<div class="panel-body">
|
||||
<h1 class="text-warning" >{{ stats.trusted }}</h1>
|
||||
<h4>{% trans "partially aligned" %}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-info text-center">
|
||||
<div class="panel-body">
|
||||
<h1 class="text-info" >{{ stats.forwarded }}</h1>
|
||||
<h4>{% trans "forwarded" %}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-danger text-center">
|
||||
<div class="panel-body">
|
||||
<h1 class="text-danger">{{ stats.failed }}</h1>
|
||||
<h4>{% trans "failed" %}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<button id="show-report-detail" class="btn btn-primary">
|
||||
{% trans "Display details" %}</button>
|
||||
</div>
|
||||
|
||||
<div id="report-details" style="display: none">
|
||||
<h1><small>{% trans "Trusted sources" %} <span class="text-success">{{ stats.aligned }}</span></small></h1>
|
||||
|
||||
<table class="table">
|
||||
{% for domain, stats in aligned|domain_sorted_items %}
|
||||
{% include "dmarc/_result_detail.html" with domain=domain stats=stats %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h1><small>{% trans "Partially trusted sources / Forwarders" %} <span class="text-warning">{{ stats.trusted }}</span></small></h1>
|
||||
|
||||
<table class="table">
|
||||
{% for domain, stats in trusted|domain_sorted_items %}
|
||||
{% include "dmarc/_result_detail.html" with domain=domain stats=stats %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h1><small>{% trans "Forwarders with ARC" %} <span class="text-info">{{ stats.forwarded }}</span></small></h1>
|
||||
|
||||
<table class="table">
|
||||
{% for domain, stats in forwarded|domain_sorted_items %}
|
||||
{% include "dmarc/_result_detail.html" with domain=domain stats=stats %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h1><small>{% trans "Unknown sources / Threats" %} <span class="text-danger">{{ stats.failed }}</span></small></h1>
|
||||
|
||||
<table class="table">
|
||||
{% for domain, stats in threats|domain_sorted_items %}
|
||||
{% include "dmarc/_result_detail.html" with domain=domain stats=stats only_failed=True %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,65 @@
|
||||
"""Custom template tags."""
|
||||
|
||||
import datetime
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def next_period(period):
|
||||
"""Return next period."""
|
||||
current = period.split("-")
|
||||
if int(current[1]) == 52:
|
||||
week0 = datetime.datetime.strptime("{}-0-1".format(int(current[0]) + 1 ), "%Y-%W-%w")
|
||||
week1 = datetime.datetime.strptime("{}-1-1".format(int(current[0]) + 1 ), "%Y-%W-%w")
|
||||
week52 = datetime.datetime.strptime("{}-52-1".format(current[0]), "%Y-%W-%w")
|
||||
if week0 == week52 or week0 == week1 :
|
||||
parts = (int(current[0]) + 1, 1 )
|
||||
else:
|
||||
parts = (int(current[0]) + 1, 0 )
|
||||
else:
|
||||
parts = (current[0], int(current[1]) + 1 )
|
||||
return mark_safe("{}-{}".format(parts[0], parts[1]))
|
||||
|
||||
@register.simple_tag
|
||||
def previous_period(period):
|
||||
"""Return previous period."""
|
||||
current = period.split("-")
|
||||
if int(current[1]) == 1:
|
||||
week0 = datetime.datetime.strptime("{}-0-1".format(current[0]), "%Y-%W-%w")
|
||||
week1 = datetime.datetime.strptime("{}-1-1".format(current[0]), "%Y-%W-%w")
|
||||
if week0 == week1:
|
||||
parts = (int(current[0]) - 1, 52 )
|
||||
else:
|
||||
parts = (current[0], 0 )
|
||||
elif int(current[1]) == 0:
|
||||
week0 = datetime.datetime.strptime("{}-0-1".format(current[0]), "%Y-%W-%w")
|
||||
week52 = datetime.datetime.strptime("{}-52-1".format(int(current[0]) - 1 ), "%Y-%W-%w")
|
||||
if week0 == week52:
|
||||
parts = (int(current[0]) - 1, 51 )
|
||||
else:
|
||||
parts = (int(current[0]) - 1, 52 )
|
||||
else:
|
||||
parts = (current[0], int(current[1]) - 1 )
|
||||
return mark_safe("{}-{}".format(parts[0], parts[1]))
|
||||
|
||||
|
||||
@register.filter
|
||||
def domain_sorted_items(domain_dict):
|
||||
"""Return a list of tuples ordered alphabetically by domain names."""
|
||||
if isinstance(domain_dict, dict):
|
||||
sorted_domain_dict = OrderedDict(
|
||||
sorted(domain_dict.items(), key=lambda t: t[0]))
|
||||
unresolved_label = _("Not resolved")
|
||||
unresolved = sorted_domain_dict.pop(unresolved_label, None)
|
||||
if unresolved:
|
||||
sorted_domain_dict[unresolved_label] = unresolved
|
||||
return sorted_domain_dict.items()
|
||||
|
||||
raise ValueError("domain_dict is not a dict")
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
Return-Path: <abuse@163.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id IKPdD1ULmlXgLQAABvoInA
|
||||
for <tonio@ngyn.org>; Mon, 06 Jul 2015 07:00:05 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id 2645EE035B
|
||||
for <postmaster@ngyn.org>; Mon, 6 Jul 2015 07:00:05 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <postmaster@ngyn.org>;
|
||||
Mon, 6 Jul 2015 07:00:03 +0200 (CEST)
|
||||
Received: from m12-181.163.com (m12-181.163.com [220.181.12.181])
|
||||
by mail.koalabs.org (Postfix) with ESMTP
|
||||
for <postmaster@ngyn.org>; Mon, 6 Jul 2015 06:59:54 +0200 (CEST)
|
||||
Received: from 163.com (unknown [192.168.201.141])
|
||||
by mfast1 (Coremail) with SMTP id tcCowEAJixEvC5pVHJvvLg--.53754S2;
|
||||
Mon, 06 Jul 2015 12:59:27 +0800 (CST)
|
||||
Content-Type: multipart/mixed; boundary="===============2544031943362770105=="
|
||||
MIME-Version: 1.0
|
||||
From: <abuse@163.com>
|
||||
Date: Mon, 06 Jul 2015 12:59:25 +0800
|
||||
Subject: Report Domain: ngyn.org Submitter: 163.com Report-ID:
|
||||
aggr_report_ngyn.org_20150705_163.com
|
||||
To: postmaster@ngyn.org
|
||||
X-CM-TRANSID:tcCowEAJixEvC5pVHJvvLg--.53754S2
|
||||
Message-Id:<559A0B30.EBEE1F.29746@m12-181.163.com>
|
||||
X-Coremail-Antispam: 1UD129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73
|
||||
VFW2AGmfu7bjvjm3AaLaJ3UjIYCTnIWjp_UUUnI7CY07I20VC2zVCF04k26cxKx2IYs7xG
|
||||
6rWj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wAa7VASzI0EjI02j7AqF2
|
||||
xKxVCjxxvEa2IrM2AIxVAIcxkEcVAq07x20xvEncxIr21le4C267I2x7xF54xIwI1l5I8C
|
||||
rVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4IE7xkEbVWUJVW8Jw
|
||||
ACjcxG0xvEwIxGrwAKzVAC0xCFj2AI6cx7M4kE6xkIj40Ew7xC0wCjxxvEa2IrMxkIecxE
|
||||
wVCm-wCY0x0Ix7I2Y4AK64vIr41l42xK82IYc2Ij64vIr41l42xK82IY6x8ErcxFaVAv8V
|
||||
WrMxCjnVAqn7xvrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18
|
||||
MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jr0_JrylIxkGc2Ij64vIr4
|
||||
1l6VACY4xI67k04243AbIYCTnIWIevJa73UjIFyTuYvjTRClkVDUUUU
|
||||
X-Originating-IP: [192.168.201.141]
|
||||
X-CM-SenderInfo: 5dex2vi6rwjhhfrp/
|
||||
|
||||
--===============2544031943362770105==
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
This is a DMARC aggregate report for domain ngyn.org on 20150705. For more information please mail to abuse@163.com.
|
||||
--===============2544031943362770105==
|
||||
MIME-Version: 1.0
|
||||
Content-Type: application/gzip;
|
||||
name="163.com!ngyn.org!1436054400!1436140799.zip"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment;
|
||||
filename="163.com!ngyn.org!1436054400!1436140799.zip"
|
||||
|
||||
UEsDBBQAAAAIAGxn5kZGEGLBdAEAAJQDAAAqAAAAMTYzLmNvbSFuZ3luLm9yZyExNDM2MDU0NDAw
|
||||
ITE0MzYxNDA3OTkueG1sbVNbbsMgEPzvKXICg5M4USSEehOEzdpBsQEBbpXbF4eHadovzOzs7Owu
|
||||
JiOA6PnwoB+HA7FgtPVsAc8F93zDAqrtxBRfgLaXUzPohaCCRAIsXM6U96uDz8KJYCQkXSkonybL
|
||||
0lVNT9VsUkfcdviKO1aS94QoENwAs1xNqWSAepikou35dMHd+YwxQRHJcVDiFW3P+Hq7BT8qi6Hf
|
||||
aqVa3TYxepbDk5m1n6W7QzGiQ1uKZutBKwIxysVDLtQRFD8S6Mz4wrYzQoYqrYAgk+4uAy4jZvC0
|
||||
C4RwvCz+ZyeMddA2O7P6u/Tu9GoHYNLQtu2aIz42l3CcguAeydxBr8rTlqD4keFUEL74vIZxiRzY
|
||||
ZiCd0U56qVWyXSMVb5vBGF5BIJRxpH7HFCgzqZp8qxn2k1sjUoDycpRgXUm7Axdg2Wj1Qtdm30yN
|
||||
J6E/6YSv/h7eo1tnvytWpvaV19L10tMD3xTSNNKltLXvHb2X28hxhwSVP/EHUEsBAhQDFAAAAAgA
|
||||
bGfmRkYQYsF0AQAAlAMAACoAAAAAAAAAAAAAAKSBAAAAADE2My5jb20hbmd5bi5vcmchMTQzNjA1
|
||||
NDQwMCExNDM2MTQwNzk5LnhtbFBLBQYAAAAAAQABAFgAAAC8AQAAAAA=
|
||||
--===============2544031943362770105==--
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
"""Test mixins."""
|
||||
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
|
||||
from django.core.management import call_command
|
||||
|
||||
|
||||
class CallCommandMixin(object):
|
||||
"""A mixin to provide command execution shortcuts."""
|
||||
|
||||
def setUp(self):
|
||||
"""Replace stdin"""
|
||||
super(CallCommandMixin, self).setUp()
|
||||
self.stdin = sys.stdin
|
||||
|
||||
def tearDown(self):
|
||||
sys.stdin = self.stdin
|
||||
|
||||
def import_report(self, path):
|
||||
"""Import test report from file."""
|
||||
with open(path) as fp:
|
||||
buf = io.StringIO(fp.read())
|
||||
sys.stdin = buf
|
||||
out = io.StringIO()
|
||||
call_command("import_aggregated_report", "--pipe", stdout=out)
|
||||
return out.getvalue()
|
||||
|
||||
def import_reports(self, folder="reports"):
|
||||
"""Import reports from folder."""
|
||||
path = os.path.join(os.path.dirname(__file__), folder)
|
||||
for f in os.listdir(path):
|
||||
fpath = os.path.join(path, f)
|
||||
if f.startswith(".") or not os.path.isfile(fpath):
|
||||
continue
|
||||
self.import_report(fpath)
|
||||
|
||||
def import_fail_reports(self, folder="fail-reports"):
|
||||
"""Import failed reports from folder."""
|
||||
path = os.path.join(os.path.dirname(__file__), folder)
|
||||
for f in os.listdir(path):
|
||||
fpath = os.path.join(path, f)
|
||||
if f.startswith(".") or not os.path.isfile(fpath):
|
||||
continue
|
||||
with self.assertRaisesMessage(SystemExit, '65'):
|
||||
self.import_report(fpath)
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
Return-Path: <abuse@163.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id IKPdD1ULmlXgLQAABvoInA
|
||||
for <tonio@ngyn.org>; Mon, 06 Jul 2015 07:00:05 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id 2645EE035B
|
||||
for <postmaster@ngyn.org>; Mon, 6 Jul 2015 07:00:05 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <postmaster@ngyn.org>;
|
||||
Mon, 6 Jul 2015 07:00:03 +0200 (CEST)
|
||||
Received: from m12-181.163.com (m12-181.163.com [220.181.12.181])
|
||||
by mail.koalabs.org (Postfix) with ESMTP
|
||||
for <postmaster@ngyn.org>; Mon, 6 Jul 2015 06:59:54 +0200 (CEST)
|
||||
Received: from 163.com (unknown [192.168.201.141])
|
||||
by mfast1 (Coremail) with SMTP id tcCowEAJixEvC5pVHJvvLg--.53754S2;
|
||||
Mon, 06 Jul 2015 12:59:27 +0800 (CST)
|
||||
Content-Type: multipart/mixed; boundary="===============2544031943362770105=="
|
||||
MIME-Version: 1.0
|
||||
From: <abuse@163.com>
|
||||
Date: Mon, 06 Jul 2015 12:59:25 +0800
|
||||
Subject: Report Domain: ngyn.org Submitter: 163.com Report-ID:
|
||||
aggr_report_ngyn.org_20150705_163.com
|
||||
To: postmaster@ngyn.org
|
||||
X-CM-TRANSID:tcCowEAJixEvC5pVHJvvLg--.53754S2
|
||||
Message-Id:<559A0B30.EBEE1F.29746@m12-181.163.com>
|
||||
X-Coremail-Antispam: 1UD129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73
|
||||
VFW2AGmfu7bjvjm3AaLaJ3UjIYCTnIWjp_UUUnI7CY07I20VC2zVCF04k26cxKx2IYs7xG
|
||||
6rWj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wAa7VASzI0EjI02j7AqF2
|
||||
xKxVCjxxvEa2IrM2AIxVAIcxkEcVAq07x20xvEncxIr21le4C267I2x7xF54xIwI1l5I8C
|
||||
rVACY4xI64kE6c02F40Ex7xfMcIj6x8ErcxFaVAv8VWrMcvjeVCFs4IE7xkEbVWUJVW8Jw
|
||||
ACjcxG0xvEwIxGrwAKzVAC0xCFj2AI6cx7M4kE6xkIj40Ew7xC0wCjxxvEa2IrMxkIecxE
|
||||
wVCm-wCY0x0Ix7I2Y4AK64vIr41l42xK82IYc2Ij64vIr41l42xK82IY6x8ErcxFaVAv8V
|
||||
WrMxCjnVAqn7xvrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18
|
||||
MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jr0_JrylIxkGc2Ij64vIr4
|
||||
1l6VACY4xI67k04243AbIYCTnIWIevJa73UjIFyTuYvjTRClkVDUUUU
|
||||
X-Originating-IP: [192.168.201.141]
|
||||
X-CM-SenderInfo: 5dex2vi6rwjhhfrp/
|
||||
|
||||
--===============2544031943362770105==
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
This is a DMARC aggregate report for domain ngyn.org on 20150705. For more information please mail to abuse@163.com.
|
||||
--===============2544031943362770105==
|
||||
MIME-Version: 1.0
|
||||
Content-Type: application/zip;
|
||||
name="163.com!ngyn.org!1436054400!1436140799.zip"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment;
|
||||
filename="163.com!ngyn.org!1436054400!1436140799.zip"
|
||||
|
||||
UEsDBBQAAAAIAGxn5kZGEGLBdAEAAJQDAAAqAAAAMTYzLmNvbSFuZ3luLm9yZyExNDM2MDU0NDAw
|
||||
ITE0MzYxNDA3OTkueG1sbVNbbsMgEPzvKXICg5M4USSEehOEzdpBsQEBbpXbF4eHadovzOzs7Owu
|
||||
JiOA6PnwoB+HA7FgtPVsAc8F93zDAqrtxBRfgLaXUzPohaCCRAIsXM6U96uDz8KJYCQkXSkonybL
|
||||
0lVNT9VsUkfcdviKO1aS94QoENwAs1xNqWSAepikou35dMHd+YwxQRHJcVDiFW3P+Hq7BT8qi6Hf
|
||||
aqVa3TYxepbDk5m1n6W7QzGiQ1uKZutBKwIxysVDLtQRFD8S6Mz4wrYzQoYqrYAgk+4uAy4jZvC0
|
||||
C4RwvCz+ZyeMddA2O7P6u/Tu9GoHYNLQtu2aIz42l3CcguAeydxBr8rTlqD4keFUEL74vIZxiRzY
|
||||
ZiCd0U56qVWyXSMVb5vBGF5BIJRxpH7HFCgzqZp8qxn2k1sjUoDycpRgXUm7Axdg2Wj1Qtdm30yN
|
||||
J6E/6YSv/h7eo1tnvytWpvaV19L10tMD3xTSNNKltLXvHb2X28hxhwSVP/EHUEsBAhQDFAAAAAgA
|
||||
bGfmRkYQYsF0AQAAlAMAACoAAAAAAAAAAAAAAKSBAAAAADE2My5jb20hbmd5bi5vcmchMTQzNjA1
|
||||
NDQwMCExNDM2MTQwNzk5LnhtbFBLBQYAAAAAAQABAFgAAAC8AQAAAAA=
|
||||
--===============2544031943362770105==--
|
||||
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
Return-Path: postmaster@amazonses.com
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id dV+vEDEApVVCdQAABvoInA
|
||||
for <tonio@ngyn.org>; Tue, 03 Jun 2021 14:27:34 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id C28EFE035E
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 03 Jun 2021 14:27:34 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <dmarc-aggrep@ngyn.org>;
|
||||
Tue, 03 Jun 2021 14:27:32 +0200 (CEST)
|
||||
Received: from a7-16.smtp-out.eu-west-1.amazonses.com (a7-16.smtp-out.eu-west-1.amazonses.com [54.240.7.16])
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <dmarc-aggrep@ngyn.org>; Mon, 7 Jun 2021 12:28:31 +0200 (CEST)
|
||||
(envelope-from 01020179e5ffe776-2049ffa3-f9ed-4b84-8bed-26aec834960c-000000@eu-west-1.amazonses.com)
|
||||
Date: Mon, 7 Jun 2021 10:23:43 +0000
|
||||
From: postmaster@amazonses.com
|
||||
To: dmarc-aggrep@ngyn.org
|
||||
Message-ID: <01020179e5ffe776-2049ffa3-f9ed-4b84-8bed-26aec834960c-000000@eu-west-1.amazonses.com>
|
||||
Subject: Dmarc Aggregate Report Domain: {ngyn.org} Submitter: {Amazon
|
||||
SES} Date: {2021-06-06} Report-ID: {12007123-9847-4f23-a7d7-c6837cce89de}
|
||||
Content-Type: multipart/mixed;
|
||||
boundary="----=_Part_8428_1073105148.1623061423987"
|
||||
MIME-Version: 1.0
|
||||
|
||||
------=_Part_8428_1073105148.1623061423987
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
This MIME email was sent through Amazon SES.
|
||||
------=_Part_8428_1073105148.1623061423987
|
||||
Content-Type: application/octet-stream;
|
||||
name=amazonses.com!ngyn.org!1622937600!1623024000.xml.gz
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment;
|
||||
filename="amazonses.com!ngyn.org!1622937600!1623024000.xml.gz"
|
||||
|
||||
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
|
||||
yanL1kmbf/kfHM/x+WY1AAA=
|
||||
|
||||
------=_Part_8428_1073105148.1623061423987--
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
Return-Path: postmaster@amazonses.com
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id dV+vEDEApVVCdQAABvoInA
|
||||
for <tonio@ngyn.org>; Tue, 03 Jun 2021 14:27:34 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id C28EFE035E
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 03 Jun 2021 14:27:34 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <dmarc-aggrep@ngyn.org>;
|
||||
Tue, 03 Jun 2021 14:27:32 +0200 (CEST)
|
||||
Received: from a7-16.smtp-out.eu-west-1.amazonses.com (a7-16.smtp-out.eu-west-1.amazonses.com [54.240.7.16])
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <dmarc-aggrep@ngyn.org>; Mon, 7 Jun 2021 12:28:31 +0200 (CEST)
|
||||
(envelope-from 01020179e5ffe776-2049ffa3-f9ed-4b84-8bed-26aec834960c-000000@eu-west-1.amazonses.com)
|
||||
Date: Mon, 7 Jun 2021 10:23:43 +0000
|
||||
From: postmaster@amazonses.com
|
||||
To: dmarc-aggrep@ngyn.org
|
||||
Message-ID: <01020179e5ffe776-2049ffa3-f9ed-4b84-8bed-26aec834960c-000000@eu-west-1.amazonses.com>
|
||||
Subject: Dmarc Aggregate Report Domain: {ngyn.org} Submitter: {Amazon
|
||||
SES} Date: {2021-06-06} Report-ID: {12007123-9847-4f23-a7d7-c6837cce89de}
|
||||
Content-Type: multipart/mixed;
|
||||
boundary="----=_Part_8428_1073105148.1623061423987"
|
||||
MIME-Version: 1.0
|
||||
|
||||
------=_Part_8428_1073105148.1623061423987
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
This MIME email was sent through Amazon SES.
|
||||
------=_Part_8428_1073105148.1623061423987
|
||||
Content-Type: application/octet-stream;
|
||||
name=amazonses.com!ngyn.org!1622937600!1623024000.xml.gz
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment;
|
||||
filename="amazonses.com!ngyn.org!1622937600!1623024000.xml.gz"
|
||||
|
||||
H4sICA343WAAA2FtYXpvbnNlcy5jb20hbmd5bi5vcmchMTYyNDIzMzYwMCExNjI0MzIwMDAwLnht
|
||||
bAClU7ty2zAQrKWv4LgX3xalGQSOi5RJCndpOBBwlDAmAQ4AOnG+PgeCryhJlYp3u4e9WxxInn50
|
||||
bfQGxkqtPjxkcfrwRPekARAXxl/pfkcmkqZxRpI5QdxAr42rO3BMMMcQ2hFtrrViHdDnz8/fvn45
|
||||
vHx6IckC+gromGxpr63rmHVgPrKO/dTKgo257kgSeF856UtBszxNqywvDudTWR3KBiNWierAj6ei
|
||||
4hxOZwEkWev9aRwJasPUdWy7Ixe4SkWzY17mRXFMU5IEZCRBiZEqsJGnfO5Fkt9Ulhar5SgivW4l
|
||||
f6/74dJKewNBd4giLjQ6UVRd31WMN4BaAZhoJl5lRy1JQjCjtm9G0H8nrKdKK/TXLwB39BFz/HgE
|
||||
o/sRPGqAazOGPtHfQ4Sx1YPhUMuenss4L+LyMc5OuNoVnyu5HpSjSIVghqd28MbaAe9HzIQ3LS2u
|
||||
Vjr/RMLUW2RT5z33zKLVMVwZbzwQPppbJn/viRuZjREpQDnZSHygy7EbMAGmbozuNovYopPMH4cJ
|
||||
G9ytNmCH1q16d7P+a8VrRRCYDE3J4mmrRjZu/195EcOXdOfDF48PI4r2JFn/819WLGN5CQQAAA==
|
||||
|
||||
------=_Part_8428_1073105148.1623061423987--
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
Return-Path: <dmarc@fastmail.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id MN7aCZgMilV1TAAABvoInA
|
||||
for <tonio@ngyn.org>; Wed, 24 Jun 2015 03:49:12 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id 0FF2EE035E
|
||||
for <postmaster@ngyn.org>; Wed, 24 Jun 2015 03:49:12 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Authentication-Results: nelson.ngyn.org (amavisd-new);
|
||||
dkim=pass (1024-bit key) header.d=fastmail.com header.b=0Nj5GpwR;
|
||||
dkim=pass (1024-bit key) header.d=messagingengine.com
|
||||
header.b=W7jB990M
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <postmaster@ngyn.org>;
|
||||
Wed, 24 Jun 2015 03:49:11 +0200 (CEST)
|
||||
Received: from bulk2-smtp.messagingengine.com (bulk2-smtp.messagingengine.com [66.111.4.225])
|
||||
(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <postmaster@ngyn.org>; Wed, 24 Jun 2015 03:49:11 +0200 (CEST)
|
||||
Received: from compute6.internal (compute6.nyi.internal [10.202.2.46])
|
||||
by mailbulk.nyi.internal (Postfix) with ESMTP id D8DDDAFE;
|
||||
Tue, 23 Jun 2015 21:49:03 -0400 (EDT)
|
||||
Received: from frontend1 ([10.202.2.160])
|
||||
by compute6.internal (MEProxy); Tue, 23 Jun 2015 21:49:03 -0400
|
||||
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=fastmail.com; h=
|
||||
content-type:date:from:message-id:mime-version:subject:to
|
||||
:x-sasl-enc:x-sasl-enc; s=mesmtp; bh=1t7zGOXcrQ9ovOrxVPikV8Cc8h4
|
||||
=; b=0Nj5GpwRFukRLOhanfU0ZrV04k7RkzI1k4Ko8nC1WFOPbK43dzMSg6zZ1QM
|
||||
+Hgb+WdYhPc1D1oInpbxoN5urVBNqOL43xyQY7Ul0fg+5kY8s8Pxndo2pFko2Sqf
|
||||
YvTXeDN9IZJgxcT3Qy1/N38sE0q+Jt3uD+0gTJhJAOZqVlxY=
|
||||
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=
|
||||
messagingengine.com; h=content-type:date:from:message-id
|
||||
:mime-version:subject:to:x-sasl-enc:x-sasl-enc; s=smtpout; bh=1t
|
||||
7zGOXcrQ9ovOrxVPikV8Cc8h4=; b=W7jB990M1394jwz9JB5XcuQlJ1qTn478nI
|
||||
nG4+68z4YRi88Nl0Mwmq3LMkamLzim/HSrTSsN2dk2yWl+JxQZNis0Nh6nqq7f60
|
||||
mkTmv74DLMnAKdqriTpkzN7PnzKTr/A4AumpPF0yFJ3DONjq1fqXFHOAx+T8xk7I
|
||||
zf1/lQlPs=
|
||||
X-Sasl-enc: pVVGFLeGBqO3p41F4hif6WoWvBVprb8iTS5Hykw0gj6x 1435110543
|
||||
Received: from root1.messagingengine.com (unknown [66.111.4.4])
|
||||
by mail.messagingengine.com (Postfix) with ESMTPA id A2C52C00288
|
||||
for <postmaster@ngyn.org>; Tue, 23 Jun 2015 21:49:03 -0400 (EDT)
|
||||
From: dmarc@fastmail.com
|
||||
To: postmaster@ngyn.org
|
||||
Date: Tue, 23 Jun 2015 21:49:03 -0400
|
||||
Subject: Report Domain: ngyn.org Submitter: fastmail.com Report-ID:
|
||||
2015.06.23.5672770
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="1435110543.af000f16737.3591227"; charset="us-ascii"
|
||||
Message-Id: <20150624014903.A2C52C00288@frontend1.nyi.internal>
|
||||
|
||||
|
||||
--1435110543.af000f16737.3591227
|
||||
Date: Tue, 23 Jun 2015 21:49:03 -0400
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset="US-ASCII"
|
||||
Content-Disposition: inline
|
||||
|
||||
|
||||
This is a DMARC aggregate report for ngyn.org
|
||||
|
||||
1 records.
|
||||
0 passed.
|
||||
1 failed.
|
||||
|
||||
Submitted by FastMail Pty Ltd
|
||||
Generated with Mail::DMARC 1.20150611
|
||||
|
||||
|
||||
--1435110543.af000f16737.3591227
|
||||
Date: Tue, 23 Jun 2015 21:49:03 -0400
|
||||
MIME-Version: 1.0
|
||||
Content-Type: application/gzip; name="fastmail.com!ngyn.org!1435017600!1435103999!5672770.xml.gz"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: inline;
|
||||
filename="fastmail.com!ngyn.org!1435017600!1435103999!5672770.xml.gz"
|
||||
|
||||
H4sIAI8MilUAA21TTXPbIBA9J7/Ck3uFlNTWuENJTjm1M/0HGgwrmYn4GEBu/O+7gCzZbk5i31t2
|
||||
31tW9PVTj5sT+KCs+fnUVPXTK3ukPYA8cPHBHh+oB2d97DRELnnkCC2Ykmy7a5/btqZkhVKC9UNn
|
||||
uAb2zkP8zdW4+RPPm19RUrJQKQ80ckxq7sVbj6kprITVlBQm53xGzzthTeQCG5jesmOMLvwg5PoK
|
||||
wTv/Z6YCKBs6z82Qez7QAwzKsOb7y7Zu2l2N4guSSTAyU039st/vsaYpjshNlcXv1Vios6MS585N
|
||||
h1GFI5R70qJAw8xwNhVaxzoFSByXH0qzQEk5ZCi4PiPpmwDHjDVAictRuIShxE5EtkUSP0nUFwrw
|
||||
rYT1RYu3f4vJYCcvoFOOtU3V7Ktmu6uatsWyC5HzhJ1MZM+UlEPG5h5w4uOEI8mVk08VnA0q4h7N
|
||||
Eq+ROSe57PG9kJwNZ0/9DM6eVyM3TXDmRT9VEkxUvcK1vTzaCUbroIuWwTdhRzucK8HT663EbWbv
|
||||
rWajOnjAUcV5527InH8ELsEXYH3DazQru1NE+RSPnYcwjXGWePG2bMRd73UtUrJAFUyn+jiVHBSi
|
||||
lGSOh5BWMAdlYpd9IXetU1pZAErW3/of7jTwqvgDAAA=
|
||||
|
||||
--1435110543.af000f16737.3591227--
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
Return-Path: <noreply-dmarc-support@google.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id dV+vEDEApVVCdQAABvoInA
|
||||
for <tonio@ngyn.org>; Tue, 03 Jun 2021 14:27:34 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id C28EFE035E
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 03 Jun 2021 14:27:34 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <dmarc-aggrep@ngyn.org>;
|
||||
Tue, 03 Jun 2021 14:27:32 +0200 (CEST)
|
||||
Received: from mail-vn0-f74.google.com (mail-vn0-f74.google.com [209.85.216.74])
|
||||
(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
|
||||
(No client certificate requested)
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 03 Jun 2021 14:27:29 +0200 (CEST)
|
||||
Received: by vnbf7 with SMTP id f7so392460vnb.1
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 03 Jun 2021 05:27:28 -0700 (PDT)
|
||||
MIME-Version: 1.0
|
||||
X-Received: by 10.52.251.34 with SMTP id zh2mr50557742vdc.8.1436869893195;
|
||||
Tue, 03 Jun 2021 03:31:33 -0700 (PDT)
|
||||
Message-ID: <14872432101891615947@google.com>
|
||||
Date: Tue, 03 Jun 2021 10:31:33 +0000
|
||||
Subject: Report domain: ngyn.org Submitter: google.com Report-ID: 1282989064754998675
|
||||
From: noreply-dmarc-support@google.com
|
||||
To: dmarc-aggrep@ngyn.org
|
||||
Content-Type: application/zip;
|
||||
name="google.com!ngyn.org!1622592000!1622678399.zip"
|
||||
Content-Disposition: attachment;
|
||||
filename="google.com!ngyn.org!1622592000!1622678399.zip"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
UEsDBBQDAAAIAMhzw1IU0YnahAIAAAQMAAAtAAAAZ29vZ2xlLmNvbSFuZ3luLm9yZyExNjIyNTky
|
||||
MDAwITE2MjI2NzgzOTkueG1s7ZbBctsgFEX3+QqP9wYJ24rUIaSrfkG71hDpWWYiAQM4if++WAJJ
|
||||
ressmridTrOSuPCu3rs+w5jev3Tt4gmMFUreLVOULBcgK1UL2dwtv339ssqXi3t2Q3cA9QOvHtnN
|
||||
YkENaGVc2YHjNXf8pHlVmaaUvAPWKNW0gCrVURzFcAY6LlomlXdoj6u646Za2YM+2X2el/XnYs2L
|
||||
M7yslHS8cqWQO8X2zmn7CeNQiqZSzDGX9hkMJpss2+YJxef1wTiMIWqWkpwUeZFkm9vtpijy7HZL
|
||||
8bgdjvtRoTRcNmEYLz1AIyRLM0K2BUkS/7FBifsg6343u83XRUExyGiGf3Sj+BeZUq1aUR1LfXho
|
||||
hd3D2Ijy6Ugmm6NEPl+KByHs8vpRdMxS3L9E0epdr/lnkDSTSgLFOqxtFGxUdOWYz8E/hhbP2hlY
|
||||
qJSJnRn1PM5u1cFUUArNSFKgfIsISVDmQ5g24tFKHaRjhOL+JcpxfHji7YG7OP4QgbBaWeE8taHr
|
||||
uTKd6yPYeZYontII4+7CxhhJgILbYBEld9TAWlXxthxaoriX5mc8eh343j3Qd5pbH3VUJmscveP6
|
||||
fMBBH2OkovYWYifA2LFsD7wGU+6M6mYMzNRoc1ZM+cHtSwP20LrJbwpmThe88E63sPJjIJKk2yQj
|
||||
a9Rwra3tnEZejtzNagdrNgQQFrPIoYXKKcOiH8VRmjKJ3cQf6WJnr7YQoAiL0XyiH/8cBcU9yb8D
|
||||
9Sa9DPXmWlD3Gb8K9b/BWXR+C00kTdbr9G00SXB/kaa0IChBBKXJKyit/zhLp40Pli6w9F7ff2eQ
|
||||
crRNPUcJWl9GKb0WSafL5/+4lU4DXY+kcCtdDSaKpz/03wFQSwECPwMUAwAACADIc8NSFNGJ2oQC
|
||||
AAAEDAAALQAkAAAAAAAAACCAtIEAAAAAZ29vZ2xlLmNvbSFuZ3luLm9yZyExNjIyNTkyMDAwITE2
|
||||
MjI2NzgzOTkueG1sCgAgAAAAAAABABgAgCVxNHRY1wGAJXE0dFjXAQBf60Z0WNcBUEsFBgAAAAAB
|
||||
AAEAfwAAAM8CAAAAAA==
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
Return-Path: <noreply-dmarc-support@google.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id dV+vEDEApVVCdQAABvoInA
|
||||
for <tonio@ngyn.org>; Tue, 14 Jul 2015 14:27:34 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id C28EFE035E
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 14 Jul 2015 14:27:34 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Authentication-Results: nelson.ngyn.org (amavisd-new);
|
||||
dkim=pass (2048-bit key) header.d=google.com
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <dmarc-aggrep@ngyn.org>;
|
||||
Tue, 14 Jul 2015 14:27:32 +0200 (CEST)
|
||||
Received: from mail-vn0-f74.google.com (mail-vn0-f74.google.com [209.85.216.74])
|
||||
(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
|
||||
(No client certificate requested)
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 14 Jul 2015 14:27:29 +0200 (CEST)
|
||||
Received: by vnbf7 with SMTP id f7so392460vnb.1
|
||||
for <dmarc-aggrep@ngyn.org>; Tue, 14 Jul 2015 05:27:28 -0700 (PDT)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
|
||||
d=google.com; s=20120113;
|
||||
h=mime-version:message-id:date:subject:from:to:content-type
|
||||
:content-disposition:content-transfer-encoding;
|
||||
bh=28gVVTJdqkSuhoNLWpBiJ0mYAF1CETmzecT8+PvUARY=;
|
||||
b=jahe/NPogONhyXBkFG2iEkgVoYJmOoXuXCsfTUiY4WtDacSfBxs4pHCYd9kv1iu7Rm
|
||||
8TUOyMG0ftm+Bu3Ldctb75lcrEb6yf/X/LIhXUyPlWSOwowqU429D8+89Lz2234K+5Ps
|
||||
9u4E4vSI4HvVKjqxs/eIkSSpmqZDZydFtqOiKg3Nj4fr9v2FzEHuiwOvqO6dU8lct3zs
|
||||
cc9/NNNp9q2z+nJ02hujEKDDrqEW+U3Xm8uk+YE4eUDvvqQQyC5SFTRWcGiQ1visZmfm
|
||||
OlHmv25II7saHmZ4VrGXFUZHE+8d0lXN+QOndSZ6aorsarKzSRlXvD2ISxKKo3Qw8UqJ
|
||||
CCnA==
|
||||
MIME-Version: 1.0
|
||||
X-Received: by 10.52.251.34 with SMTP id zh2mr50557742vdc.8.1436869893195;
|
||||
Tue, 14 Jul 2015 03:31:33 -0700 (PDT)
|
||||
Message-ID: <14872432101891615947@google.com>
|
||||
Date: Tue, 14 Jul 2015 10:31:33 +0000
|
||||
Subject: Report domain: ngyn.org Submitter: google.com Report-ID: 14872432101891615947
|
||||
From: noreply-dmarc-support@google.com
|
||||
To: dmarc-aggrep@ngyn.org
|
||||
Content-Type: application/zip;
|
||||
name="google.com!ngyn.org!1436745600!1436831999.zip"
|
||||
Content-Disposition: attachment;
|
||||
filename="google.com!ngyn.org!1436745600!1436831999.zip"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
UEsDBAoAAAAIANhS7kbvUmeO+AEAANQEAAAtAAAAZ29vZ2xlLmNvbSFuZ3luLm9yZyExNDM2NzQ1
|
||||
NjAwITE0MzY4MzE5OTkueG1spVTLcqMwELznK1y+Gxkb27ClKDnlC3bPlCwGrApIKkkk8d/vYImH
|
||||
na1c9oTo6WlNN2PTl6+uXX2AdVKr53WabNcrUEJXUjXP6z+/3zb5evXCnmgNUJ25eGdPqxW1YLT1
|
||||
ZQeeV9zzAUNU26ZUvAPWaN20kAjdUTKBgQMdly1TGhXa66bquBUb15tB7nXZFnix58tbXgqtPBe+
|
||||
lKrW7OK9cb8Iia3J3Eo44cp9giW77Hg85FvU+t4fhKMNWbE0y0+7bL9Lt2lepMf0UGQnSuZ64KNX
|
||||
KC1XTXSD0BkaqbB9fzxlh+MWbwvIWAdV3ar5Pi2KAmdRoxi5V5tuW4ZKjW6luJamP7fSXWAaRGM8
|
||||
iqnmqhIMGLUCEKq8epcdc5SEQwSdqW/Y8AyQwe+ggBIT390IuBExwrMDEvBxG/Ff42CKQttxMqs/
|
||||
J+9O91ZAKQ0rsmS3T7JDkuYpyk/4yBS6V55hKRxGOF4HH7ztMaxqLAwJSGe0kx63Ng69RBa8IQHD
|
||||
HTqfw4hu61iYEolLwd1SAiF/NcAc70wLVal7T8kNWVJw8zrA0QcL4TQrknvJKcYHX8gbw6OyQglZ
|
||||
S/xdTm0X4BXYsra6W3z5JRplvjVT3vtLacH1rZ/1HvL4cadiMoNADC2+TJ6WavQ+0f9UnheWPPoY
|
||||
yGH5KJn/oP4CUEsBAgoACgAAAAgA2FLuRu9SZ474AQAA1AQAAC0AAAAAAAAAAAAAAAAAAAAAAGdv
|
||||
b2dsZS5jb20hbmd5bi5vcmchMTQzNjc0NTYwMCExNDM2ODMxOTk5LnhtbFBLBQYAAAAAAQABAFsA
|
||||
AABDAgAAAAA=
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
Return-Path: <dmarcrep@microsoft.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id mL/aJNE4kFUCCAAABvoInA
|
||||
for <tonio@ngyn.org>; Sun, 28 Jun 2015 20:11:29 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id 7F4A2E035D
|
||||
for <postmaster@ngyn.org>; Sun, 28 Jun 2015 20:11:29 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <postmaster@ngyn.org>;
|
||||
Sun, 28 Jun 2015 20:11:28 +0200 (CEST)
|
||||
Received: from mail2.koalabs.org (alena.koalabs.org [66.175.223.133])
|
||||
by mail.koalabs.org (Postfix) with ESMTP
|
||||
for <postmaster@ngyn.org>; Sun, 28 Jun 2015 20:11:28 +0200 (CEST)
|
||||
Received: from BAY004-OMC4S15.hotmail.com (bay004-omc4s15.hotmail.com [65.54.190.217])
|
||||
by mail2.koalabs.org (Postfix) with ESMTP id 63F8D46F66
|
||||
for <postmaster@ngyn.org>; Sun, 28 Jun 2015 14:11:26 -0400 (EDT)
|
||||
Received: from BAY0-DTS-DRS01 ([65.54.190.200]) by BAY004-OMC4S15.hotmail.com with Microsoft SMTPSVC(7.5.7601.23008);
|
||||
Sun, 28 Jun 2015 11:11:18 -0700
|
||||
MIME-Version: 1.0
|
||||
From: dmarcrep@microsoft.com
|
||||
To: postmaster@ngyn.org
|
||||
Date: 28 Jun 2015 11:11:18 -0700
|
||||
Subject: =?utf-8?B?UmVwb3J0IERvbWFpbjogbmd5bi5vcmcgU3VibWl0dGVyOiBob3RtYWlsLmNvbSBSZXBvcnQtSUQ6IDw2NmYzMTdhMDIxZmY0Y2RhYmFkMmIzNTBkMzMwMzYxNUBob3RtYWlsLmNvbT4=?=
|
||||
Content-Type: multipart/mixed;
|
||||
boundary=--boundary_32281_b52cf564-2a50-4f96-aeb0-ef5f83b05463
|
||||
Message-ID: <BAY004-OMC4S15A1cZU00000eb5@BAY004-OMC4S15.hotmail.com>
|
||||
X-OriginalArrivalTime: 28 Jun 2015 18:11:18.0588 (UTC) FILETIME=[D4889FC0:01D0B1CD]
|
||||
|
||||
|
||||
----boundary_32281_b52cf564-2a50-4f96-aeb0-ef5f83b05463
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
|
||||
----boundary_32281_b52cf564-2a50-4f96-aeb0-ef5f83b05463
|
||||
Content-Type: application/zip; name=hotmail.com!ngyn.org!1435428000!1435514400.zip
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment; filename=hotmail.com!ngyn.org!1435428000!1435514400.zip
|
||||
|
||||
UEsDBBQAAgAIAGlZ3EbQIUrLnQEAADsDAAAuAF0AaG90bWFpbC5jb20hbmd5bi5vcmchMTQz
|
||||
NTQyODAwMCExNDM1NTE0NDAwLnhtbFNESACMAAAAAAgAiyIcyGNkYGkRYWBgUGCAAB0gZmQE
|
||||
M1lF0NhMDAkMLCCegATDf0Z5BkYmiBxIryITdnEFsLgIRBxqlhADphjIfABVVA0AB8Y4kFXG
|
||||
OJBVxjiQVYWT226cMBCGX2W198WwwHYrTZxIue4zIGOPWSv4INvk8Gy96CP1FWrjsCGKqt7g
|
||||
8W/+mW/G8OfXb7h/1fPhGX1Q1twdm6o+HtBwK5SZ7o5LlN8ux3sKElGMjD9R8Oisj4PGyASL
|
||||
jIL102CYRvpTcW+DlfHwaL2rgNxOADVTMxWaeZ78D3p7s+JWAymnW2Yl6Pks2+Y7q0+NlB0X
|
||||
bGTiNLZ9Ldq2bs9N/3C1MXuK/cMHiQgHz8yUao44KUObru2706WuayBFATRilfum67Kc90D2
|
||||
VvKlSWdnxd8Gt4yzClfMpWwiMNRMb6ZKjaYERQAmnpSmAUgJgAUn121ewVFjDQJxFMIWpwAc
|
||||
j7RPclrS80s1j9z6vNqXZLSL5zgoR3901amtur5qLk3Kc9OB28VEmrQSbPz4zOYlNZr5VXA2
|
||||
qJiu/R1jr8DK7lhI4KWNTC/TzDOu/GDcZSQrnBJoopIqfVEUrsgE+kF6q3eT2qtAPhnYEq+D
|
||||
x7DMMZSa/x50eY1G1A69tz5f26q8Ixbu/9lLjzdnMZHPHGQbP7n9B38BUEsBAhcLFAACAAgA
|
||||
aVncRtAhSsudAQAAOwMAAC4AEQAAAAAAAQAgALaBAAAAAGhvdG1haWwuY29tIW5neW4ub3Jn
|
||||
ITE0MzU0MjgwMDAhMTQzNTUxNDQwMC54bWxTRAQAjAAAAFVUBQAHxjiQVVBLBQYAAAAAAQAB
|
||||
AG0AAABGAgAAAAA=
|
||||
----boundary_32281_b52cf564-2a50-4f96-aeb0-ef5f83b05463--
|
||||
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
Return-Path: <noreply@dmarc.yahoo.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id 53eANBaoilWVQwAABvoInA
|
||||
for <tonio@ngyn.org>; Wed, 24 Jun 2015 14:52:38 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id BD629E0360
|
||||
for <postmaster@ngyn.org>; Wed, 24 Jun 2015 14:52:38 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Authentication-Results: nelson.ngyn.org (amavisd-new);
|
||||
dkim=pass (2048-bit key) header.d=yahoo.com
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <postmaster@ngyn.org>;
|
||||
Wed, 24 Jun 2015 14:52:37 +0200 (CEST)
|
||||
Received: from n1-vm5.bullet.mail.ne1.yahoo.com (n1-vm5.bullet.mail.ne1.yahoo.com [98.138.229.197])
|
||||
(using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits))
|
||||
(No client certificate requested)
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <postmaster@ngyn.org>; Wed, 24 Jun 2015 14:52:37 +0200 (CEST)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1435150193; bh=s8fRltU+y/nfIjdSVEbtwFXKmxeW2BeOfADZ7qSc3i4=; h=Date:From:To:Subject:From:Subject; b=Masqn66+cIcv0cwUblZZjLPFOA+l0BfXvanLooG2xAWCwGItLHUToHXwfhsbw5QsyhpptvQSIFWFUBoZqS8T27ZcLVzkPRFl38h/Yo03pBDwL6njc1yQVN2RZxz3i7VO5MXEF2XFg9z2B19dfi+GRISCGLTPA0s+sAt32I+A8FZDSzqDxb3AKuU66QabM9BJiMn/XUGAr7At96sEFyWPDBWe2Q3+MzEN5pO54uWVhjd9qaIRB6Oc/FAFM+SFcVU9UrJFRN43rP/50xV70rrV00//lWrJH+4b3RdIHjy54Vy0qLwOJ8PRdKaDbJ/NJuxbKNiYJZvE+t+QvlEpbvd7/Q==
|
||||
Received: from [98.138.226.173] by n1.bullet.mail.ne1.yahoo.com with NNFMP; 24 Jun 2015 12:49:53 -0000
|
||||
Received: from [98.138.237.130] by t2.bullet.mail.ne1.yahoo.com with NNFMP; 24 Jun 2015 12:49:53 -0000
|
||||
Received: from [127.0.0.1] by launcher100.asd.mail.corp.ne1.yahoo.com with NNFMP; 24 Jun 2015 12:49:53 -0000
|
||||
X-Yahoo-Newman-Property: asdreport
|
||||
X-Yahoo-Newman-Id: 1435111091.916236
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: binary
|
||||
Content-Type: multipart/mixed; boundary="_----------=_14351501937631101"
|
||||
X-Mailer: MIME::Lite 3.027 (F2.73; A2.04; B3.13; Q3.13)
|
||||
Date: Wed, 24 Jun 2015 05:49:53 -0700
|
||||
From: noreply@dmarc.yahoo.com
|
||||
To: postmaster@ngyn.org
|
||||
Subject: Report Domain: ngyn.org Submitter: yahoo.com Report-ID: <1435111091.916236>
|
||||
Message-Id: <1435150193.404586@dmarc.yahoo.com>
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
|
||||
--_----------=_14351501937631101
|
||||
Content-Disposition: inline
|
||||
Content-Length: 44
|
||||
Content-Transfer-Encoding: binary
|
||||
Content-Type: text/plain
|
||||
|
||||
This is an aggregate report from Yahoo! Inc.
|
||||
--_----------=_14351501937631101
|
||||
Content-Disposition: attachment; filename="yahoo.com!ngyn.org!1435017600!1435103999.zip"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Type: application/x-zip-compressed; name="yahoo.com!ngyn.org!1435017600!1435103999.zip"
|
||||
|
||||
UEsDBBQAAAAIADsu2EY7OXCQrwEAACUEAAAsABwAeWFob28uY29tIW5neW4u
|
||||
b3JnITE0MzUwMTc2MDAhMTQzNTEwMzk5OS54bWxVVAkAA3GnilVxp4pVdXgL
|
||||
AAEEAAAAAAQAAAAAlVRBcuMgEDzvvkKbB4CIY7tURche84Q9qTAa2VQkoAAl
|
||||
8e8zMhjJTi57EvQ0M90zU+Ivn+NQvYMP2prnB0bqhxfx6zfvAbqDVG94riru
|
||||
wVkf2xGi7GSUFxBh64+tkSOIf/Jk7Z/q1SjCaUEzC0apB+FsiKMMEfzfbpRe
|
||||
kfP8hig7cpoYmZ5r6U6wp82WMVY3jDRs97jZcboEMxvlQOulOV7LIXaAozaX
|
||||
1zXb7+qa04QUApicvN40TVOhAFMS0ruMpeaNee7soNW5ddNh0OEEix6LXoww
|
||||
x7Mh2AhMl4Aclt2bHkXgNB2uaHD9BZy/GXPCWAOcugKoKLZ4x0/S9aMEbJ+y
|
||||
vsjx9mOxHezkFbTaiT0jrCFsuyNsv+d0CRSuspOJouE0HQqei8K7HCZsVFci
|
||||
s3cdcMo64iZl8WtkTZy99zhzZCxtSBqxAymy9GJl9r4uTqc45LoDE3WvcZmX
|
||||
lyeQHfi293ZcTWWNXjN9f87lFE+thzANcZXyXnMe8aAPHnAUMS31zeDzZs+J
|
||||
hIEpejnMi3W5LyZvEvN1A/6/ipMh/FBitWH0m7uZn7eH09Uf4AtQSwECHgMU
|
||||
AAAACAA7LthGOzlwkK8BAAAlBAAALAAYAAAAAAABAAAApIEAAAAAeWFob28u
|
||||
Y29tIW5neW4ub3JnITE0MzUwMTc2MDAhMTQzNTEwMzk5OS54bWxVVAUAA3Gn
|
||||
ilV1eAsAAQQAAAAABAAAAABQSwUGAAAAAAEAAQByAAAAFQIAAAAA
|
||||
|
||||
--_----------=_14351501937631101--
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
Return-Path: <noreply@dmarc.yahoo.com>
|
||||
Delivered-To: <tonio@ngyn.org>
|
||||
Received: from mail.koalabs.org
|
||||
by nelson.ngyn.org (Dovecot) with LMTP id 53eANBaoilWVQwAABvoInA
|
||||
for <tonio@ngyn.org>; Wed, 24 Jun 2015 14:52:38 +0200
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by mail.koalabs.org (Postfix) with ESMTP id BD629E0360
|
||||
for <postmaster@ngyn.org>; Wed, 24 Jun 2015 14:52:38 +0200 (CEST)
|
||||
X-Virus-Scanned: Debian amavisd-new at mail.koalabs.org
|
||||
Authentication-Results: nelson.ngyn.org (amavisd-new);
|
||||
dkim=pass (2048-bit key) header.d=yahoo.com
|
||||
Received: from mail.koalabs.org ([127.0.0.1])
|
||||
by localhost (nelson.ngyn.org [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP for <postmaster@ngyn.org>;
|
||||
Wed, 24 Jun 2015 14:52:37 +0200 (CEST)
|
||||
Received: from n1-vm5.bullet.mail.ne1.yahoo.com (n1-vm5.bullet.mail.ne1.yahoo.com [98.138.229.197])
|
||||
(using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits))
|
||||
(No client certificate requested)
|
||||
by mail.koalabs.org (Postfix) with ESMTPS
|
||||
for <postmaster@ngyn.org>; Wed, 24 Jun 2015 14:52:37 +0200 (CEST)
|
||||
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1435150193; bh=s8fRltU+y/nfIjdSVEbtwFXKmxeW2BeOfADZ7qSc3i4=; h=Date:From:To:Subject:From:Subject; b=Masqn66+cIcv0cwUblZZjLPFOA+l0BfXvanLooG2xAWCwGItLHUToHXwfhsbw5QsyhpptvQSIFWFUBoZqS8T27ZcLVzkPRFl38h/Yo03pBDwL6njc1yQVN2RZxz3i7VO5MXEF2XFg9z2B19dfi+GRISCGLTPA0s+sAt32I+A8FZDSzqDxb3AKuU66QabM9BJiMn/XUGAr7At96sEFyWPDBWe2Q3+MzEN5pO54uWVhjd9qaIRB6Oc/FAFM+SFcVU9UrJFRN43rP/50xV70rrV00//lWrJH+4b3RdIHjy54Vy0qLwOJ8PRdKaDbJ/NJuxbKNiYJZvE+t+QvlEpbvd7/Q==
|
||||
Received: from [98.138.226.173] by n1.bullet.mail.ne1.yahoo.com with NNFMP; 24 Jun 2015 12:49:53 -0000
|
||||
Received: from [98.138.237.130] by t2.bullet.mail.ne1.yahoo.com with NNFMP; 24 Jun 2015 12:49:53 -0000
|
||||
Received: from [127.0.0.1] by launcher100.asd.mail.corp.ne1.yahoo.com with NNFMP; 24 Jun 2015 12:49:53 -0000
|
||||
X-Yahoo-Newman-Property: asdreport
|
||||
X-Yahoo-Newman-Id: 1435111091.916236
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: binary
|
||||
Content-Type: multipart/mixed; boundary="_----------=_14351501937631101"
|
||||
X-Mailer: MIME::Lite 3.027 (F2.73; A2.04; B3.13; Q3.13)
|
||||
Date: Wed, 24 Jun 2015 05:49:53 -0700
|
||||
From: noreply@dmarc.yahoo.com
|
||||
To: postmaster@ngyn.org
|
||||
Subject: Report Domain: ngyn.org Submitter: yahoo.com Report-ID: <1436111091.916236>
|
||||
Message-Id: <1435150193.404586@dmarc.yahoo.com>
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
|
||||
--_----------=_14351501937631101
|
||||
Content-Disposition: inline
|
||||
Content-Length: 44
|
||||
Content-Transfer-Encoding: binary
|
||||
Content-Type: text/plain
|
||||
|
||||
This is an aggregate report from Yahoo! Inc.
|
||||
--_----------=_14351501937631101
|
||||
Content-Disposition: attachment; filename="yahoo.com!ngyn.org!1436017600!1436103999.zip"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Type: application/x-zip-compressed; name="yahoo.com!ngyn.org!1436017600!1436103999.zip"
|
||||
|
||||
UEsDBBQDAAAIAHhdTFUTlAO/pwEAABkEAAAsAAAAeWFob28uY29tIW5neW4ub3JnITE0MzYwMTc2
|
||||
MDAhMTQzNjEwMzk5OS54bWylU0uu2zAMXLenSN8BLKtpExhg9brtEboyFJt21Gd9QMmvze2rSIZk
|
||||
pNl15fFwOEMSNrz+0cvhHckra7698KZ9eRUfPsKEOF7k8Bbx4QCEzlLoNQY5yiATGWlLc2+kRvFT
|
||||
Xq39dPhhhgZYYTcVaqkW4awPWvqA9H3Ukobmdu9pBquBJUWS1yw1Cv7leOKctx1vOn76fDwBq8VN
|
||||
HcfBnqSZc1ziLjgrk7pbfj61LbDEVAGazbw9dl0X803xYw+GwJ7tDs4uarj1br0syl+xtMvxTWnh
|
||||
gWWwkd5NgoClZ6acIPyFQwDmNsZXKsJNNQTB7/PfQRrmaS4QDpbKDGR/11W9XWnAXjlx5g3vGv71
|
||||
1PDzGVgpVO1gVxNEvEcCld9C8V0uqwxl2Xx/5Z31KihrhLEGge2YvTDdY5JqAZbgrhTPslUiqrHs
|
||||
SW4u1A1BjWiCmhSSr51XlCNSP5HVwsw301iage3Y4vRvO8g1XHtCvy5hZ/k482i1VEYs6kK4KB/y
|
||||
h5zZvS4bCYNrIBk3zO9FUY5RT/EfKU56/yQim2b8uF2kytcDbPfX/wVQSwECPwMUAwAACAB4XUxV
|
||||
E5QDv6cBAAAZBAAALAAkAAAAAAAAACCApIEAAAAAeWFob28uY29tIW5neW4ub3JnITE0MzYwMTc2
|
||||
MDAhMTQzNjEwMzk5OS54bWwKACAAAAAAAAEAGACASwUgH97YAYBLBSAf3tgBAFhOMR/e2AFQSwUG
|
||||
AAAAAAEAAQB+AAAA8QEAAAAA
|
||||
|
||||
--_----------=_14351501937631101--
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Management command tests."""
|
||||
|
||||
from modoboa.admin import factories as admin_factories
|
||||
from modoboa.lib.tests import ModoTestCase
|
||||
|
||||
from . import mixins
|
||||
from .. import models
|
||||
|
||||
|
||||
class ManagementCommandTestCase(mixins.CallCommandMixin, ModoTestCase):
|
||||
"""Test management command."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
super(ManagementCommandTestCase, cls).setUpTestData()
|
||||
cls.domain = admin_factories.DomainFactory(name="ngyn.org")
|
||||
|
||||
def test_import_from_archive(self):
|
||||
"""Import report from archive."""
|
||||
self.import_reports()
|
||||
self.import_fail_reports()
|
||||
self.assertTrue(self.domain.record_set.exists())
|
||||
self.assertTrue(
|
||||
models.Reporter.objects.filter(
|
||||
org_name="FastMail Pty Ltd").exists())
|
||||
# Ensure that reports from Yahoo are processed successfully.
|
||||
# These do not contain a sp attribute in policy_published
|
||||
self.assertTrue(
|
||||
models.Report.objects.filter(
|
||||
report_id="1435111091.916236",
|
||||
reporter=models.Reporter.objects.get(org_name="Yahoo! Inc."),
|
||||
).exists()
|
||||
)
|
||||
@@ -0,0 +1,77 @@
|
||||
"""Views tests."""
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from modoboa.admin import factories as admin_factories
|
||||
from modoboa.core import models as core_models
|
||||
from modoboa.lib.tests import ModoTestCase
|
||||
|
||||
from . import mixins
|
||||
|
||||
|
||||
class DMARCViewsTestCase(mixins.CallCommandMixin, ModoTestCase):
|
||||
"""Views test cases."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
"""Create test data."""
|
||||
super(DMARCViewsTestCase, cls).setUpTestData()
|
||||
cls.domain = admin_factories.DomainFactory(name="ngyn.org")
|
||||
|
||||
def test_domainlist_view(self):
|
||||
"""Test domain list view."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("admin:_domain_list")
|
||||
response = self.ajax_get(url)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
self.assertIn(url, response["rows"])
|
||||
|
||||
def test_domainreport_view(self):
|
||||
"""Test domain report view."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get("{}?period=2015-26".format(url))
|
||||
self.assertContains(response, "'Failed', 100.0")
|
||||
|
||||
def test_domainreport_view_week0(self):
|
||||
"""Test domain report view for week 0."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get("{}?period=2019-0".format(url))
|
||||
self.assertContains(response, "Dec. 31, 2018")
|
||||
|
||||
def test_domainreport_view_week1(self):
|
||||
"""Test domain report view for week 1."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get("{}?period=2019-1".format(url))
|
||||
self.assertContains(response, "Jan. 7, 2019")
|
||||
|
||||
def test_domainreport_view_week52(self):
|
||||
"""Test domain report view for week 52."""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get("{}?period=2018-52".format(url))
|
||||
self.assertContains(response, "Dec. 30, 2018")
|
||||
|
||||
def test_domainreport_view_arc(self):
|
||||
"""Test domain report view for displaying ARC results"""
|
||||
self.import_reports()
|
||||
user = core_models.User.objects.get(username="admin")
|
||||
self.client.force_login(user)
|
||||
url = reverse("dmarc:domain_report", args=[self.domain.pk])
|
||||
response = self.client.get("{}?period=2021-22".format(url))
|
||||
self.assertContains(response, "'Fully aligned', 86.0")
|
||||
self.assertContains(response, "'Partially aligned', 8.0")
|
||||
self.assertContains(response, "'Forwarded', 4.0")
|
||||
self.assertContains(response, "'Failed', 2.0")
|
||||
@@ -0,0 +1,12 @@
|
||||
"""DMARC urls."""
|
||||
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "dmarc"
|
||||
|
||||
urlpatterns = [
|
||||
path("domains/<int:pk>/", views.DomainReportView.as_view(),
|
||||
name="domain_report"),
|
||||
]
|
||||
@@ -0,0 +1,151 @@
|
||||
"""DMARC views."""
|
||||
|
||||
import concurrent.futures
|
||||
import datetime
|
||||
import tldextract
|
||||
|
||||
from dns import resolver, reversename
|
||||
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
from django.views import generic
|
||||
|
||||
from django.contrib.auth import mixins as auth_mixins
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from modoboa.admin import models as admin_models
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
def insert_record(target, record, name):
|
||||
"""Add a record."""
|
||||
|
||||
if name not in target:
|
||||
target[name] = {}
|
||||
|
||||
if record.source_ip not in target[name]:
|
||||
target[name][record.source_ip] = {
|
||||
"total": 0,
|
||||
"spf": {"pass": 0, "fail": 0},
|
||||
"dkim": {"pass": 0, "fail": 0}
|
||||
}
|
||||
target[name][record.source_ip]["total"] += record.count
|
||||
for typ in ["spf", "dkim"]:
|
||||
result = getattr(record, "{}_result".format(typ))
|
||||
target[name][record.source_ip][typ][result] += record.count
|
||||
|
||||
|
||||
def week_range(year, weeknumber):
|
||||
"""Return start and end dates of a given week."""
|
||||
tz = timezone.get_current_timezone()
|
||||
fmt = "%Y-%W-%w"
|
||||
start_week = datetime.datetime.strptime(
|
||||
"{}-{}-{}".format(year, weeknumber, 1), fmt)
|
||||
end_week = datetime.datetime.strptime(
|
||||
"{}-{}-{}".format(year, weeknumber, 0), fmt)
|
||||
return tz.localize(start_week), tz.localize(end_week)
|
||||
|
||||
|
||||
class DomainReportView(
|
||||
auth_mixins.PermissionRequiredMixin,
|
||||
generic.TemplateView):
|
||||
"""ListView for Report."""
|
||||
|
||||
permission_required = "dmarc.view_report"
|
||||
template_name = "dmarc/domain_report.html"
|
||||
|
||||
def get_queryset(self):
|
||||
"""Filter reports."""
|
||||
self.period = self.request.GET.get("period", "")
|
||||
if not self.period:
|
||||
year, week, day = timezone.now().isocalendar()
|
||||
week -= 1
|
||||
self.period = "{}-{}".format(year, week)
|
||||
else:
|
||||
year, week = self.period.split("-")
|
||||
|
||||
self.daterange = week_range(year, week)
|
||||
self.domain = admin_models.Domain.objects.get(pk=self.kwargs["pk"])
|
||||
qargs = (
|
||||
(Q(report__start_date__gte=self.daterange[0],
|
||||
report__start_date__lte=self.daterange[1]) |
|
||||
Q(report__end_date__gte=self.daterange[0],
|
||||
report__end_date__lte=self.daterange[1])) &
|
||||
Q(header_from=self.domain)
|
||||
)
|
||||
return models.Record.objects.select_related().filter(qargs)
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
"""Extra context data."""
|
||||
context = super(DomainReportView, self).get_context_data(
|
||||
*args, **kwargs)
|
||||
qset = self.get_queryset()
|
||||
stats = {
|
||||
"total": 0,
|
||||
"aligned": 0,
|
||||
"trusted": 0,
|
||||
"forwarded": 0,
|
||||
"failed": 0
|
||||
}
|
||||
aligned = {}
|
||||
trusted = {}
|
||||
forwarded = {}
|
||||
threats = {}
|
||||
all_records = qset.all()
|
||||
dns_names = {}
|
||||
if param_tools.get_global_parameter("enable_rlookups"):
|
||||
dns_resolver = resolver.Resolver()
|
||||
dns_resolver.timeout = 1.0
|
||||
dns_resolver.lifetime = 1.0
|
||||
|
||||
def get_domain_name_from_ip(ip):
|
||||
addr = reversename.from_address(ip)
|
||||
try:
|
||||
resp = dns_resolver.query(addr, "PTR")
|
||||
ext = tldextract.extract(str(resp[0].target))
|
||||
if not ext.suffix: # invalid PTR record
|
||||
raise resolver.NXDOMAIN()
|
||||
return (ip, '.'.join((ext.domain, ext.suffix)).lower())
|
||||
except (resolver.NXDOMAIN, resolver.YXDOMAIN,
|
||||
resolver.NoAnswer, resolver.NoNameservers,
|
||||
resolver.Timeout):
|
||||
return (None, None)
|
||||
|
||||
ips = (r.source_ip for r in all_records)
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=16) as pool:
|
||||
dns_names = {i: n for (i, n) in
|
||||
list(pool.map(get_domain_name_from_ip, ips))}
|
||||
|
||||
for record in all_records:
|
||||
stats["total"] += record.count
|
||||
name = dns_names.get(record.source_ip, _("Not resolved"))
|
||||
if record.dkim_result == "pass" and record.spf_result == "pass":
|
||||
stats["aligned"] += record.count
|
||||
insert_record(aligned, record, name)
|
||||
elif record.dkim_result == "pass" or record.spf_result == "pass":
|
||||
stats["trusted"] += record.count
|
||||
insert_record(trusted, record, name)
|
||||
elif record.reason_type == "local_policy" and record.reason_comment.startswith("arc=pass"):
|
||||
stats["forwarded"] += record.count
|
||||
insert_record(forwarded, record, name)
|
||||
else:
|
||||
insert_record(threats, record, name)
|
||||
stats["failed"] += record.count
|
||||
|
||||
pie_data = {}
|
||||
if stats["total"]:
|
||||
pie_data.update({
|
||||
"faligned": stats["aligned"] / float(stats["total"]) * 100,
|
||||
"paligned": stats["trusted"] / float(stats["total"]) * 100,
|
||||
"forwarded": stats["forwarded"] / float(stats["total"]) * 100,
|
||||
"failed": stats["failed"] / float(stats["total"]) * 100
|
||||
})
|
||||
|
||||
context.update({
|
||||
"stats": stats, "aligned": aligned, "trusted": trusted, "forwarded": forwarded, "threats": threats,
|
||||
"period": self.period, "daterange": self.daterange,
|
||||
"domain": self.domain, "pie_data": pie_data
|
||||
})
|
||||
return context
|
||||
@@ -71,6 +71,7 @@ class ModoTestCase(ParametersMixin, TestCase):
|
||||
params = {}
|
||||
response = getattr(self.client, method)(
|
||||
url, params, HTTP_X_REQUESTED_WITH="XMLHttpRequest")
|
||||
print(response.content)
|
||||
self.assertEqual(response.status_code, status)
|
||||
return response.json()
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ urlpatterns = [
|
||||
path('admin/', include("modoboa.admin.urls")),
|
||||
path('dnstools/', include("modoboa.dnstools.urls")),
|
||||
path('stats/', include("modoboa.maillog.urls")),
|
||||
path('dmarc/', include("modoboa.dmarc.urls")),
|
||||
|
||||
path('user/forward/', user_views.forward, name="user_forward"),
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ urlpatterns = [
|
||||
path('', include("modoboa.parameters.api.v2.urls")),
|
||||
path('', include("modoboa.limits.api.v1.urls")),
|
||||
path('', include("modoboa.relaydomains.api.v1.urls")),
|
||||
path('', include("modoboa.dmarc.api.v2.urls")),
|
||||
path('', include("modoboa.dnstools.api.v2.urls")),
|
||||
path('', include("modoboa.maillog.api.v2.urls")),
|
||||
path('', include("modoboa.transport.api.v2.urls")),
|
||||
|
||||
@@ -89,6 +89,7 @@ MODOBOA_APPS = (
|
||||
'modoboa.dnstools',
|
||||
'modoboa.policyd',
|
||||
'modoboa.maillog',
|
||||
'modoboa.dmarc',
|
||||
# Modoboa extensions here.
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user