~ubuntu-branches/ubuntu/hardy/squirrelmail/hardy-updates

« back to all changes in this revision

Viewing changes to functions/auth.php

  • Committer: Bazaar Package Importer
  • Author(s): Sam Johnston
  • Date: 2004-02-04 01:42:12 UTC
  • Revision ID: james.westby@ubuntu.com-20040204014212-ek9533qvd2vo1wa1
Tags: upstream-1.5.0
ImportĀ upstreamĀ versionĀ 1.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
/**
 
4
 * auth.php
 
5
 *
 
6
 * Copyright (c) 1999-2003 The SquirrelMail Project Team
 
7
 * Licensed under the GNU GPL. For full terms see the file COPYING.
 
8
 *
 
9
 * Contains functions used to do authentication.
 
10
 *
 
11
 * $Id: auth.php,v 1.37 2004/01/04 06:11:15 ebullient Exp $
 
12
 * @package squirrelmail
 
13
 */
 
14
 
 
15
/** Put in a safety net here, in case a naughty admin didn't run conf.pl when they upgraded */
 
16
 
 
17
if (! isset($smtp_auth_mech)) {
 
18
  $smtp_auth_mech = 'none';
 
19
}
 
20
 
 
21
if (! isset($imap_auth_mech)) {
 
22
  $imap_auth_mech = 'login';
 
23
}
 
24
 
 
25
if (! isset($use_imap_tls)) {
 
26
  $use_imap_tls = false;
 
27
}
 
28
 
 
29
if (! isset($use_smtp_tls)) {
 
30
  $use_smtp_tls = false;
 
31
}
 
32
 
 
33
/**
 
34
 * Check if user has previously logged in to the Squirrelmail session.  If user
 
35
 * has not logged in, execution will stop inside this function.
 
36
 *
 
37
 * @return int A positive value is returned if user has previously logged in
 
38
 * successfully.
 
39
 */
 
40
function is_logged_in() {
 
41
 
 
42
    if ( sqsession_is_registered('user_is_logged_in') ) {
 
43
        return;
 
44
    } else {
 
45
        global $PHP_SELF, $session_expired_post, 
 
46
               $session_expired_location;
 
47
 
 
48
        /*  First we store some information in the new session to prevent
 
49
         *  information-loss.
 
50
         */
 
51
         
 
52
        $session_expired_post = $_POST;
 
53
        $session_expired_location = $PHP_SELF;
 
54
        if (!sqsession_is_registered('session_expired_post')) {    
 
55
           sqsession_register($session_expired_post,'session_expired_post');
 
56
        }
 
57
        if (!sqsession_is_registered('session_expired_location')) {
 
58
           sqsession_register($session_expired_location,'session_expired_location');
 
59
        }
 
60
        include_once( SM_PATH . 'functions/display_messages.php' );
 
61
        logout_error( _("You must be logged in to access this page.") );
 
62
        exit;
 
63
    }
 
64
}
 
65
 
 
66
/**
 
67
 * Given the challenge from the server, supply the response using cram-md5 (See
 
68
 * RFC 2195 for details)
 
69
 *
 
70
 * @param string $username User ID
 
71
 * @param string $password User password supplied by User
 
72
 * @param string $challenge The challenge supplied by the server
 
73
 * @return string The response to be sent to the IMAP server
 
74
 *
 
75
 */
 
76
function cram_md5_response ($username,$password,$challenge) {
 
77
    $challenge=base64_decode($challenge);
 
78
    $hash=bin2hex(hmac_md5($challenge,$password));
 
79
    $response=base64_encode($username . " " . $hash) . "\r\n";
 
80
    return $response;
 
81
}
 
82
 
 
83
/**
 
84
 * Return Digest-MD5 response.
 
85
 * Given the challenge from the server, calculate and return the
 
86
 * response-string for digest-md5 authentication.  (See RFC 2831 for more
 
87
 * details)
 
88
 *
 
89
 * @param string $username User ID
 
90
 * @param string $password User password supplied by User
 
91
 * @param string $challenge The challenge supplied by the server
 
92
 * @param string $service The service name, usually 'imap'; it is used to
 
93
 *   define the digest-uri.
 
94
 * @param string $host The host name, usually the server's FQDN; it is used to
 
95
 *   define the digest-uri.
 
96
 * @return string The response to be sent to the IMAP server
 
97
 */
 
98
function digest_md5_response ($username,$password,$challenge,$service,$host) {
 
99
  $result=digest_md5_parse_challenge($challenge);
 
100
  
 
101
// verify server supports qop=auth
 
102
  // $qop = explode(",",$result['qop']);
 
103
  //if (!in_array("auth",$qop)) {
 
104
    // rfc2831: client MUST fail if no qop methods supported
 
105
   // return false;
 
106
  //}
 
107
  $cnonce = base64_encode(bin2hex(hmac_md5(microtime())));
 
108
  $ncount = "00000001";
 
109
 
 
110
  /* This can be auth (authentication only), auth-int (integrity protection), or
 
111
     auth-conf (confidentiality protection).  Right now only auth is supported.
 
112
         DO NOT CHANGE THIS VALUE */
 
113
  $qop_value = "auth";
 
114
 
 
115
  $digest_uri_value = $service . '/' . $host;
 
116
 
 
117
  // build the $response_value
 
118
  //FIXME This will probably break badly if a server sends more than one realm
 
119
  $string_a1 = utf8_encode($username).":";
 
120
  $string_a1 .= utf8_encode($result['realm']).":";
 
121
  $string_a1 .= utf8_encode($password);
 
122
  $string_a1 = hmac_md5($string_a1);
 
123
  $A1 = $string_a1 . ":" . $result['nonce'] . ":" . $cnonce;
 
124
  $A1 = bin2hex(hmac_md5($A1));
 
125
  $A2 = "AUTHENTICATE:$digest_uri_value";
 
126
  // If qop is auth-int or auth-conf, A2 gets a little extra
 
127
  if ($qop_value != 'auth') {
 
128
    $A2 .= ':00000000000000000000000000000000';
 
129
  }
 
130
  $A2 = bin2hex(hmac_md5($A2));
 
131
 
 
132
  $string_response = $result['nonce'] . ':' . $ncount . ':' . $cnonce . ':' . $qop_value;
 
133
  $response_value = bin2hex(hmac_md5($A1.":".$string_response.":".$A2));
 
134
 
 
135
  $reply = 'charset=utf-8,username="' . $username . '",realm="' . $result["realm"] . '",';
 
136
  $reply .= 'nonce="' . $result['nonce'] . '",nc=' . $ncount . ',cnonce="' . $cnonce . '",';
 
137
  $reply .= "digest-uri=\"$digest_uri_value\",response=$response_value";
 
138
  $reply .= ',qop=' . $qop_value;
 
139
  $reply = base64_encode($reply);
 
140
  return $reply . "\r\n";
 
141
 
 
142
}
 
143
 
 
144
/**
 
145
 * Parse Digest-MD5 challenge.
 
146
 * This function parses the challenge sent during DIGEST-MD5 authentication and
 
147
 * returns an array. See the RFC for details on what's in the challenge string.
 
148
 *
 
149
 * @param string $challenge Digest-MD5 Challenge
 
150
 * @return array Digest-MD5 challenge decoded data
 
151
 */
 
152
function digest_md5_parse_challenge($challenge) {
 
153
  $challenge=base64_decode($challenge);
 
154
  while (isset($challenge)) {
 
155
    if ($challenge{0} == ',') { // First char is a comma, must not be 1st time through loop
 
156
      $challenge=substr($challenge,1);
 
157
    }
 
158
    $key=explode('=',$challenge,2);
 
159
    $challenge=$key[1];
 
160
    $key=$key[0];
 
161
    if ($challenge{0} == '"') {
 
162
      // We're in a quoted value
 
163
      // Drop the first quote, since we don't care about it
 
164
      $challenge=substr($challenge,1);
 
165
      // Now explode() to the next quote, which is the end of our value
 
166
      $val=explode('"',$challenge,2);
 
167
      $challenge=$val[1]; // The rest of the challenge, work on it in next iteration of loop
 
168
      $value=explode(',',$val[0]);
 
169
      // Now, for those quoted values that are only 1 piece..
 
170
      if (sizeof($value) == 1) {
 
171
        $value=$value[0];  // Convert to non-array
 
172
      }
 
173
    } else {
 
174
      // We're in a "simple" value - explode to next comma
 
175
      $val=explode(',',$challenge,2);
 
176
      if (isset($val[1])) {
 
177
                $challenge=$val[1];
 
178
          } else {
 
179
            unset($challenge);
 
180
          }
 
181
      $value=$val[0];
 
182
    }
 
183
    $parsed["$key"]=$value;
 
184
  } // End of while loop
 
185
  return $parsed;
 
186
}
 
187
 
 
188
/**
 
189
 * Creates a HMAC digest that can be used for auth purposes
 
190
 * See RFCs 2104, 2617, 2831
 
191
 * Uses mhash() extension if available
 
192
 *
 
193
 * @param string $data Data to apply hash function to.
 
194
 * @param string $key Optional key, which, if supplied, will be used to
 
195
 * calculate data's HMAC.
 
196
 * @return string HMAC Digest string
 
197
 */
 
198
function hmac_md5($data, $key='') {
 
199
    if (extension_loaded('mhash')) {
 
200
      if ($key== '') {
 
201
        $mhash=mhash(MHASH_MD5,$data);
 
202
      } else {
 
203
        $mhash=mhash(MHASH_MD5,$data,$key);
 
204
      }
 
205
      return $mhash;
 
206
    }
 
207
    if (!$key) {
 
208
         return pack('H*',md5($data));
 
209
    }
 
210
    $key = str_pad($key,64,chr(0x00));
 
211
    if (strlen($key) > 64) {
 
212
        $key = pack("H*",md5($key));
 
213
    }
 
214
    $k_ipad =  $key ^ str_repeat(chr(0x36), 64) ;
 
215
    $k_opad =  $key ^ str_repeat(chr(0x5c), 64) ;
 
216
    /* Heh, let's get recursive. */
 
217
    $hmac=hmac_md5($k_opad . pack("H*",md5($k_ipad . $data)) );
 
218
    return $hmac;
 
219
}
 
220
 
 
221
/** 
 
222
 * Fillin user and password based on SMTP auth settings.
 
223
 *
 
224
 * @global
 
225
 * @param string $user Reference to SMTP username
 
226
 * @param string $pass Reference to SMTP password (unencrypted)
 
227
 */
 
228
function get_smtp_user(&$user, &$pass) {
 
229
    global $username, $smtp_auth_mech, 
 
230
           $smtp_sitewide_user, $smtp_sitewide_pass;
 
231
 
 
232
    if ($smtp_auth_mech == 'none') {
 
233
        $user = '';
 
234
        $pass = '';
 
235
    } elseif ( isset($smtp_sitewide_user) && isset($smtp_sitewide_pass) ) {
 
236
        $user = $smtp_sitewide_user;
 
237
        $pass = $smtp_sitewide_pass;
 
238
    } else {
 
239
        global $key, $onetimepad;
 
240
        $user = $username;
 
241
        $pass = OneTimePadDecrypt($key, $onetimepad);
 
242
    }
 
243
}
 
244
 
 
245
?>