1<?php
2/**
3 * IPTrust Plugin II
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * original @author     Andriy Lesyuk <andriy.lesyuk@softjourn.com>
7 * modified by Gero Gothe <gero.gothe@medizindoku.de>
8 *
9 */
10
11if(!defined('DOKU_INC')) die();
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13
14require_once(DOKU_PLUGIN.'action.php');
15
16class action_plugin_iptrust2 extends DokuWiki_Action_Plugin {
17
18    /**
19     * Register event handlers
20     */
21    function register(Doku_Event_Handler $controller) {
22        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_act_preprocess', array());
23        $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'ip_group', array());
24
25
26    }
27
28
29    /* This function is essential when using the include plugin.
30     * Included pages are displayed, even if the user has no rights, as long as the main page can be accessed.
31     * This function checks again on the ips and if a user is logged in => refusing access if not in the publicaccess group
32     * This, for now, solves the issue
33     */
34    function ip_group(&$event, $param) {
35        $ip = clientIP(true);
36
37    }
38
39
40    /**
41     * Check if content should be shown
42     */
43    function handle_act_preprocess(&$event, $param) {
44        global $conf;
45
46
47        if (!isset($_SERVER['REMOTE_USER'])) {
48
49            if (!in_array($event->data, array('login', 'register', 'resendpwd'))) {
50                $ip = clientIP(true);
51                $ips = @file(DOKU_CONF.'iptrust.conf', FILE_SKIP_EMPTY_LINES);
52                if (!$ips || !in_array($ip."\n", $ips)) {
53
54                    # Allow access, if allowed for the group @publicaccess
55                    global $ID;
56                    $perms = $this->aclcheck($ID);
57
58                    if (!$perms['@publicaccess'] == 1) $event->data = 'login';
59
60                }
61
62            }
63        } else {
64
65            if ($event->data == 'login') {
66                $nets = $this->getConf('log_networks');
67                if ($nets) {
68                    $ip = clientIP(true);
69                    $ips = @file(DOKU_CONF.'iptrust.conf', FILE_SKIP_EMPTY_LINES);
70                    if (!$ips || !in_array($ip."\n", $ips)) {
71                        $nets = preg_split('/, */', $nets);
72                        foreach ($nets as $net) {
73                            if (strpos($ip, $net) === 0) {
74                                $i = 0;
75                                $logins = @file($conf['cachedir'].'/iptrust', FILE_SKIP_EMPTY_LINES);
76                                if ($logins) {
77                                    for ($i = 0; $i < sizeof($logins); $i++) {
78                                        list($login, $host, $date) = explode("\t", $logins[$i]);
79                                        if ($ip == $host) {
80                                            break;
81                                        }
82                                    }
83                                } else {
84                                    $logins = array();
85                                }
86                                $logins[$i] = $_SERVER['REMOTE_USER']."\t".$ip."\t".time()."\n";
87                                io_saveFile($conf['cachedir'].'/iptrust', join('', $logins));
88                                break;
89                            }
90                        }
91                    }
92                }
93            }
94        }
95    }
96
97
98    /** This function is from the aclinfo-plug by Andreas Gohr
99     * Version 2020-10-01
100     * https://www.dokuwiki.org/plugin:aclinfo
101     */
102    function aclcheck($id){
103        global $conf;
104        global $AUTH_ACL;
105
106        $id    = cleanID($id);
107        $ns    = getNS($id);
108        $perms = array();
109
110        //check exact match first
111        $matches = preg_grep('/^'.preg_quote($id,'/').'\s+/',$AUTH_ACL);
112        if(count($matches)){
113            foreach($matches as $match){
114                $match = preg_replace('/#.*$/','',$match); //ignore comments
115                $acl   = preg_split('/\s+/',$match);
116                if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
117                if(!isset($perms[$acl[1]])) $perms[$acl[1]] = $acl[2];
118            }
119        }
120
121        //still here? do the namespace checks
122        if($ns){
123            $path = $ns.':\*';
124        }else{
125            $path = '\*'; //root document
126        }
127
128        do{
129            $matches = preg_grep('/^'.$path.'\s+/',$AUTH_ACL);
130            if(count($matches)){
131                foreach($matches as $match){
132                    $match = preg_replace('/#.*$/','',$match); //ignore comments
133                    $acl   = preg_split('/\s+/',$match);
134                    if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
135                    if(!isset($perms[$acl[1]])) $perms[$acl[1]] = $acl[2];
136                }
137            }
138
139            //get next higher namespace
140            $ns   = getNS($ns);
141
142            if($path != '\*'){
143                $path = $ns.':\*';
144                if($path == ':\*') $path = '\*';
145            }else{
146                //we did this already
147                //break here
148                break;
149            }
150        }while(1); //this should never loop endless
151
152        return $perms;
153    }
154
155}
156