home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / samba-1.9.18p7.tar.gz / samba-1.9.18p7.tar / samba-1.9.18p7 / source / credentials.c < prev    next >
C/C++ Source or Header  |  1998-05-12  |  7KB  |  223 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    code to manipulate domain credentials
  5.    Copyright (C) Andrew Tridgell 1997-1998
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include "includes.h"
  23.  
  24. extern int DEBUGLEVEL;
  25.  
  26.  
  27.  
  28. /****************************************************************************
  29. represent a credential as a string
  30. ****************************************************************************/
  31. char *credstr(uchar *cred)
  32. {
  33.     static fstring buf;
  34.     slprintf(buf,sizeof(buf)-1,"%02X%02X%02X%02X%02X%02X%02X%02X",
  35.         cred[0], cred[1], cred[2], cred[3], 
  36.         cred[4], cred[5], cred[6], cred[7]);
  37.     return buf;
  38. }
  39.  
  40.  
  41. /****************************************************************************
  42.   setup the session key. 
  43. Input: 8 byte challenge block
  44.        8 byte server challenge block
  45.       16 byte md4 encrypted password
  46. Output:
  47.       8 byte session key
  48. ****************************************************************************/
  49. void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, 
  50.               uchar session_key[8])
  51. {
  52.     uint32 sum[2];
  53.     unsigned char sum2[8];
  54.  
  55.     sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0);
  56.     sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4);
  57.  
  58.     SIVAL(sum2,0,sum[0]);
  59.     SIVAL(sum2,4,sum[1]);
  60.  
  61.     cred_hash1(session_key, sum2,(unsigned char *)pass);
  62.  
  63.     /* debug output */
  64.     DEBUG(4,("cred_session_key\n"));
  65.  
  66.     DEBUG(5,("    clnt_chal: %s\n", credstr(clnt_chal->data)));
  67.     DEBUG(5,("    srv_chal : %s\n", credstr(srv_chal->data)));
  68.     DEBUG(5,("    clnt+srv : %s\n", credstr(sum2)));
  69.     DEBUG(5,("    sess_key : %s\n", credstr(session_key)));
  70. }
  71.  
  72.  
  73. /****************************************************************************
  74. create a credential
  75.  
  76. Input:
  77.       8 byte sesssion key
  78.       8 byte stored credential
  79.       4 byte timestamp
  80.  
  81. Output:
  82.       8 byte credential
  83. ****************************************************************************/
  84. void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, 
  85.          DOM_CHAL *cred)
  86. {
  87.     DOM_CHAL time_cred;
  88.  
  89.     SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time);
  90.     SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4));
  91.  
  92.     cred_hash2(cred->data, time_cred.data, session_key);
  93.  
  94.     /* debug output*/
  95.     DEBUG(4,("cred_create\n"));
  96.  
  97.     DEBUG(5,("    sess_key : %s\n", credstr(session_key)));
  98.     DEBUG(5,("    stor_cred: %s\n", credstr(stor_cred->data)));
  99.     DEBUG(5,("    timestamp: %lx\n"    , timestamp.time));
  100.     DEBUG(5,("    timecred : %s\n", credstr(time_cred.data)));
  101.     DEBUG(5,("    calc_cred: %s\n", credstr(cred->data)));
  102. }
  103.  
  104.  
  105. /****************************************************************************
  106.   check a supplied credential
  107.  
  108. Input:
  109.       8 byte received credential
  110.       8 byte sesssion key
  111.       8 byte stored credential
  112.       4 byte timestamp
  113.  
  114. Output:
  115.       returns 1 if computed credential matches received credential
  116.       returns 0 otherwise
  117. ****************************************************************************/
  118. int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
  119.         UTIME timestamp)
  120. {
  121.     DOM_CHAL cred2;
  122.  
  123.     cred_create(session_key, stored_cred, timestamp, &cred2);
  124.  
  125.     /* debug output*/
  126.     DEBUG(4,("cred_assert\n"));
  127.  
  128.     DEBUG(5,("    challenge : %s\n", credstr(cred->data)));
  129.     DEBUG(5,("    calculated: %s\n", credstr(cred2.data)));
  130.  
  131.     if (memcmp(cred->data, cred2.data, 8) == 0)
  132.     {
  133.         DEBUG(5, ("credentials check ok\n"));
  134.         return True;
  135.     }
  136.     else
  137.     {
  138.         DEBUG(5, ("credentials check wrong\n"));
  139.         return False;
  140.     }
  141. }
  142.  
  143.  
  144. /****************************************************************************
  145.   checks credentials; generates next step in the credential chain
  146. ****************************************************************************/
  147. BOOL clnt_deal_with_creds(uchar sess_key[8],
  148.               DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred)
  149. {
  150.     UTIME new_clnt_time;
  151.     uint32 new_cred;
  152.  
  153.     DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__));
  154.  
  155.     /* increment client time by one second */
  156.     new_clnt_time.time = sto_clnt_cred->timestamp.time + 1;
  157.  
  158.     /* check that the received server credentials are valid */
  159.     if (!cred_assert(&(rcv_srv_cred->challenge), sess_key,
  160.              &(sto_clnt_cred->challenge), new_clnt_time))
  161.     {
  162.         return False;
  163.     }
  164.  
  165.     /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
  166.     new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
  167.     new_cred += new_clnt_time.time;
  168.  
  169.     /* store new seed in client credentials */
  170.     SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
  171.  
  172.     DEBUG(5,("    new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data)));
  173.     return True;
  174. }
  175.  
  176.  
  177. /****************************************************************************
  178.   checks credentials; generates next step in the credential chain
  179. ****************************************************************************/
  180. BOOL deal_with_creds(uchar sess_key[8],
  181.              DOM_CRED *sto_clnt_cred, 
  182.              DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
  183. {
  184.     UTIME new_clnt_time;
  185.     uint32 new_cred;
  186.  
  187.     DEBUG(5,("deal_with_creds: %d\n", __LINE__));
  188.  
  189.     /* check that the received client credentials are valid */
  190.     if (!cred_assert(&(rcv_clnt_cred->challenge), sess_key,
  191.                     &(sto_clnt_cred->challenge), rcv_clnt_cred->timestamp))
  192.     {
  193.         return False;
  194.     }
  195.  
  196.     /* increment client time by one second */
  197.     new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1;
  198.  
  199.     /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
  200.     new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
  201.     new_cred += new_clnt_time.time;
  202.  
  203.     DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred));
  204.  
  205.     /* doesn't matter that server time is 0 */
  206.     rtn_srv_cred->timestamp.time = 0;
  207.  
  208.     DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time));
  209.  
  210.     /* create return credentials for inclusion in the reply */
  211.     cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time,
  212.                 &(rtn_srv_cred->challenge));
  213.     
  214.     DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
  215.  
  216.     /* store new seed in client credentials */
  217.     SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
  218.  
  219.     return True;
  220. }
  221.  
  222.  
  223.