summaryrefslogtreecommitdiff
path: root/plugins/dkimstatus/dkimstatus.php
blob: a26fac4afe13e33a607d80db5719de751581ea31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<?php

/**
 * This plugin displays an icon showing the status 
 * of dkim verification of the message 
 *
 * @version 0.4.7
 * @author Julien vehent 
 * @mail julien@linuxwall.info
 * 
 * original plugin from Vladimir Mach - wladik@gmail.com
 * http://www.wladik.net
 *
 * Changelog:
 *  20110912 - Added X-Spam-Status for spamassassin (thanks Ashish Shukla for the patch)
 *  20110619 - Added License information for GPLv2
 *  20110406 - added italian translation from Roberto Puzzanghera
 *  20110128 - updated german translation by Simon
 *  20101118 - japanese translation from Taka
 *  20100811 - from Sergio Cambra: SPF fix, image function and spanish translation
 *  20100202 - fix for amavis and add cz translation
 *  20100201 - add control of header.i and header.from to detect third party signature, change icons
 *  20100115 - add 'no information' status with image using x-dkim-authentication-results
 *  20090920 - fixed space in matching status (thanks Pim Pronk for suggestion)
 */
class dkimstatus extends rcube_plugin
{
    public $task = 'mail';
    function init()
    {
        $rcmail = rcmail::get_instance();
        if ($rcmail->action == 'show' || $rcmail->action == 'preview') {
            $this->add_hook('imap_init', array($this, 'imap_init'));
            $this->add_hook('message_headers_output', array($this, 'message_headers'));
        } else if ($rcmail->action == '') {
            // with enabled_caching we're fetching additional headers before show/preview
            $this->add_hook('imap_init', array($this, 'imap_init'));
        }
    }
    
    function imap_init($p)
    {
        $rcmail = rcmail::get_instance();
        $p['fetch_headers'] = trim($p['fetch_headers'].' ' . strtoupper('Authentication-Results').' '. strtoupper('X-DKIM-Authentication-Results').' ' .strtoupper('X-Spam-Status'));
        return $p;
    }

    function image($image, $alt, $title)
    {
        return '<img src="plugins/dkimstatus/images/'.$image.'" alt="'.$this->gettext($alt).'" title="'.$this->gettext($alt).$title.'" /> ';
    }
    
    function message_headers($p)
    {
        $this->add_texts('localization');

        /* First, if dkimproxy did not find a signature, stop here
        */
        if($p['headers']->others['x-dkim-authentication-results'] || $p['headers']->others['authentication-results'] || $p['headers']->others['x-spam-status']){

            $results = $p['headers']->others['x-dkim-authentication-results'];

            if(preg_match("/none/", $results)) {
                $image = 'nosiginfo.png';
                $alt = 'nosignature';
            } else {
                /* Second, check the authentication-results header
                */
                if($p['headers']->others['authentication-results']) {

                    $results = $p['headers']->others['authentication-results'];

                    if(preg_match("/dkim=([a-zA-Z0-9]*)/", $results, $m)) {
                        $status = ($m[1]);
                    }

                    if(preg_match("/domainkeys=([a-zA-Z0-9]*)/", $results, $m)) {
                        $status = ($m[1]);
                    }


                    if($status == 'pass') {

                        /* Verify if its an author's domain signature or a third party
                        */

                        if(preg_match("/[@][a-zA-Z0-9]+([.][a-zA-Z0-9]+)?\.[a-zA-Z]{2,4}/", $p['headers']->from, $m)) {
                            $authordomain = $m[0];
                            if(preg_match("/header\.i=(([a-zA-Z0-9]+[_\.\-]?)+)?($authordomain)/", $results) ||
                                preg_match("/header\.from=(([a-zA-Z0-9]+[_\.\-]?)+)?($authordomain)/", $results)) {
                                $image = 'authorsign.png';
                                $alt = 'verifiedsender';
                                $title = $results;
                            } else {
                                $image = 'thirdpty.png';
                                $alt = 'thirdpartysig';
                                $title = $results;
                            }
                        }

                    }
                    /* If signature proves invalid, show appropriate warning
                    */ 
                    else if ($status) {
                        $image = 'invalidsig.png';
                        $alt = 'invalidsignature';
                        $title = $results;
                    }
                    /* If no status it can be a spf verification
                    */
                    else {
                        $image = 'nosiginfo.png';
                        $alt = 'nosignature';
                    }

                /* Third, check for spamassassin's X-Spam-Status
                */
                } else if ($p['headers']->others['x-spam-status']) {
                    
                    $image = 'nosiginfo.png';
                    $alt = 'nosignature';

                    /* DKIM_* are defined at: http://search.cpan.org/~kmcgrail/Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Plugin/DKIM.pm */
                    $results = $p['headers']->others['x-spam-status'];
                    if(preg_match_all('/DKIM_[^,]+/', $results, $m)) {
                        if(array_search('DKIM_SIGNED', $m[0]) !== FALSE) {
                            if(array_search('DKIM_VALID', $m[0]) !== FALSE) {
                                if(array_search('DKIM_VALID_AU', $m[0])) {
                                    $image = 'authorsign.png';
                                    $alt = 'verifiedsender';
                                    $title = 'DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU';
                                } else {
                                    $image = 'thirdpty.png';
                                    $alt = 'thirdpartysig';
                                    $title = 'DKIM_SIGNED, DKIM_VALID';
                                }
                            } else {
                                $image = 'invalidsig.png';
                                $alt = 'invalidsignature';
                                $title = 'DKIM_SIGNED';
                            }
                        }
                    }
                }
            }
        } else {
            $image = 'nosiginfo.png';
            $alt = 'nosignature';
        }
        if ($image && $alt) {
            $p['output']['from']['value'] = $this->image($image, $alt, $title) . $p['output']['from']['value'];
        }
        return $p;
    }
}