root/lib/session.php @ 152

Revision 152, 7.3 KB (checked in by dez, 7 years ago)

Adds new mail check

Line 
1<?
2// To use:
3// include_once "session.php"
4// $mysession = new Session;
5//
6// $mysession->loggedin is TRUE if they have logged in
7//
8// other attributes are :
9// username   - the username they logged in with
10// fullname   - whatever full name we know for them
11// last   - unix timestamp for their previous page access
12// data   - var/array for persistant data, commit by calling the 'save' method
13
14
15// Session management and authentication mechanism.
16class Session {
17public    $loggedin=FALSE;    // Is this a valid logged in user ?
18public    $username='';        // Username
19public    $fullname;        // Fullname
20public  $email=0;        // Email waiting?
21public  $groups  =array();    // users groups
22public    $data='';        // Var/array for session persistant data
23public    $token='';        // session identifier
24public    $last='';        // Time of last page request
25private    $timeout = 300;        // Idle timeout limit in minutes
26private    $table = "session";    // session storage table (const)
27private $datahash='';        // hash of data field
28
29    // Create a new session id
30    private function newsession()
31    {
32        global $DB;
33        $try = 0;
34
35        do {
36            $tt=date("D M d H:i:s Y");
37            $ip = $_SERVER['REMOTE_ADDR'];
38            $token = md5("$ip$tt$try");
39            $old = $DB->GetAll("select hash from session where hash=?", array($token));
40        }while ($old);
41        $DB->Execute("insert into session (hash, time, ip) values (?,NOW(),?)", array($token, $ip));
42        setcookie("session", $token, NULL, "/");
43        $this->token = $token;
44        return;
45    }
46
47    // Public Object constructor
48    function __construct()
49    {
50        global $DB;
51        unset($token);
52
53        // The possible form elements
54        $submit = @$_POST['Login'];
55        $logout = @$_POST['Logout'];
56        $session_user = strtolower(@$_POST['session_user']);
57        $session_pass = @$_POST['session_pass'];
58
59        // We havent logged them in yet
60        $this->loggedin = FALSE;
61
62        // Time out any old sessions
63        $DB->Execute("delete from {$this->table} where time < NOW() - '{$this->timeout} minutes'::reltime");
64
65        // Log them out if they ask
66        if ($logout=="Logout") {
67            $this->logout();
68            return;
69        }
70
71        // the possible token data passed from a form
72        if (isset($_REQUEST['token']))
73            $token = $_REQUEST['token'];
74
75        // Check if we were handed a specific token identifier
76        // Otherwise use the value from the cookie we gave out
77        if (!isset($token) && isset($_COOKIE['session']))
78            $token=@$_COOKIE['session'];
79
80        if (isset($token)) $this->token = $token;
81
82        // Okay, so we still dont have a session id
83        // so issue a new one and go back to core
84        if (!isset($token)) 
85        {
86            $this->newsession();
87            return;
88        }
89
90        // Is this a login attempt ?
91        if ($submit != '' && $session_user != '' && $session_pass != '')
92        {
93            $this->session_init($session_user, $session_pass);
94        }
95
96        // Retrieve session information
97        $oldsess=$DB->GetAll("select * from {$this->table} where hash=?", array($this->token));
98
99        if (!$oldsess || count($oldsess) < 1) {
100            $this->errormsg="Session timed out";
101            $this->newsession();
102            return;
103        }
104
105        // Extract detail of session for pass-back
106        $detail = $oldsess[0];
107        $this->data = unserialize((string)$detail['data']);
108        $this->last = strtotime($detail['time']);
109        $this->datahash = md5(serialize($this->data));
110
111        // are we actually logged in, fill in more
112        if ($detail['username']) {
113            // Are we using HTTPS?
114            if (!isset($_SERVER['HTTPS'])) {
115                $this->errormsg = "Insecure Connection";
116                $this->loggedin = FALSE;
117                return;
118            }
119            // User is valid but they're coming from the wrong IP
120            if ($detail['ip'] != $_SERVER['REMOTE_ADDR']) {
121                $this->errormsg = "Invalid IP";
122                $this->loggedin = FALSE;
123                return;
124            }
125            $this->username=$detail['username'];
126            $this->fetch_detail($detail['username']);
127            $this->loggedin = TRUE;
128        }
129
130        // update time stamp
131        $DB->Execute( "update {$this->table} set time=NOW() where hash=?", array($this->token));
132    }
133
134    // Public function: Store the session data away in the database
135    public function save( )
136    {
137        global $DB;
138        $newhash = md5(serialize($this->data));
139        if ($newhash == $this->datahash) {
140            // no change in data, dont save
141            return;
142        }
143
144        $DB->Execute("update {$this->table} set data=? where hash=?", array(serialize($this->data),$this->token));
145
146    }
147
148    // Public function: force a logout of the session
149    public function logout( )
150    {
151        global $DB;
152        $DB->Execute("delete from session where hash=?", array($this->token));
153        $this->newsession();
154        $this->loggedin = FALSE;
155    }
156
157    // Fill out any extra details we know about the user
158    private function fetch_detail( $user )
159    {
160        if (!($ldap = @ldap_connect("ldap://localhost"))) {
161            $this->errormsg="LDAP connect failed";
162            return FALSE;
163        }
164        $info = $this->ldap_getuser($ldap, $user);
165        if (!$info) return FALSE;
166
167        ldap_close($ldap);
168
169        // Check the user's email status
170        $mailstat = stat("/var/spool/mail/".$user);
171        if ($mailstat[size]>0) {
172            if ($mailstat[mtime]>$mailstat[atime]) $this->email = 2;
173            else $this->email = 1;
174        }
175
176        $this->fullname = $info['cn'][0];
177        $this->groups = $info['grouplist'];
178
179    }
180
181    /* check using mod_auth_externals helper
182    private function check_pass($user, $pass)
183    {
184
185        if ($fd === FALSE) {
186            $this->errormsg = "Auth system error";
187            return FALSE;
188        }
189
190        fwrite($fd, "$user\n");
191        fwrite($fd, "$pass\n");
192        $ret = pclose($fd);
193        if ($ret == 0) return TRUE;
194
195        $this->autherror = "u='$user' p='$pass' ret=$ret";
196        $this->errormsg = "Invalid Username or Password";
197        return FALSE;
198    }
199    */
200
201    // Get a users full record from ldap
202    private function ldap_getuser($ldap, $user)
203    {
204        // publically bind to find user
205        if (!($bind=@ldap_bind($ldap, "", ""))) {
206            $this->errormsg="LDAP bind failed";
207            return NULL;
208        }
209        // find the user
210        if (!($search=@ldap_search($ldap, "dc=sucs,dc=org", "(&(uid=$user))"))) {
211            $this->errormsg="LDAP search fail";
212            return NULL;
213        }
214        $n = ldap_count_entries($ldap, $search);
215        if ($n < 1) {
216            $this->errormsg = "Username or Password Incorrect";
217            return NULL;
218        }
219        $info = ldap_get_entries($ldap, $search);
220
221        if (($grpsearch=@ldap_search($ldap, "ou=Group,dc=sucs,dc=org", "memberuid=$user"))) {
222            $gn = ldap_count_entries($ldap,$grpsearch);
223            $gpile = ldap_get_entries($ldap, $grpsearch);
224            $glist=array();
225            for ($i=0;$i<$gn;$i++) {
226                $glist$gpile[$i]['cn'][0] ] = $gpile[$i]['gidnumber'][0];
227            }
228            $info[0]['grouplist'] = $glist;
229        }
230        return $info[0];
231    }
232
233    /* check using ldap directly */
234    private function check_pass($user, $pass)
235    {
236        // Open connection
237        if (!($ldap = @ldap_connect("ldap://localhost"))) {
238            $this->errormsg="LDAP connect failed";
239            return FALSE;
240        }
241        $info = $this->ldap_getuser($ldap, $user);
242        if (!$info) return FALSE;
243
244        $real = @ldap_bind($ldap, $info['dn'], $pass);
245
246        ldap_close($ldap);
247        if ($real) return TRUE;
248        $this->errormsg="Username or Password Incorrect";
249        return FALSE;
250
251    }
252
253    // Private function: process login form
254    private function session_init($user, $pass)
255    {
256        global $DB;
257        // Check that this is a valid session start
258        // This prevents replay attacks
259        $sess = $DB->GetAll("select * from {$this->table} where hash=? and username is NULL", array($this->token));
260        if (!$sess || count($sess)<1) {
261            $this->errormsg = "Invalid session, login again.";
262            return;
263        }
264
265        if (!$this->check_pass($user, $pass)) return;
266        $this->username = $user;
267
268        // Update the session, filling in the blanks
269        $DB->Execute("update {$this->table} set username=?, time='NOW()', ip=? where hash=?", array($this->username, $_SERVER['REMOTE_ADDR'], $this->token));
270
271        // Return back to normal session retrieval
272    }
273
274} // end of Class
Note: See TracBrowser for help on using the browser.