00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024
00025
00026
00027
00028 char *credstr(const unsigned char *cred)
00029 {
00030 static fstring buf;
00031 slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X",
00032 cred[0], cred[1], cred[2], cred[3],
00033 cred[4], cred[5], cred[6], cred[7]);
00034 return buf;
00035 }
00036
00037
00038
00039
00040
00041
00042
00043 static void creds_init_128(struct dcinfo *dc,
00044 const DOM_CHAL *clnt_chal_in,
00045 const DOM_CHAL *srv_chal_in,
00046 const unsigned char mach_pw[16])
00047 {
00048 unsigned char zero[4], tmp[16];
00049 HMACMD5Context ctx;
00050 struct MD5Context md5;
00051
00052
00053 memcpy(dc->mach_pw, mach_pw, 16);
00054
00055 ZERO_STRUCT(dc->sess_key);
00056
00057 memset(zero, 0, sizeof(zero));
00058
00059 hmac_md5_init_rfc2104(mach_pw, 16, &ctx);
00060 MD5Init(&md5);
00061 MD5Update(&md5, zero, sizeof(zero));
00062 MD5Update(&md5, clnt_chal_in->data, 8);
00063 MD5Update(&md5, srv_chal_in->data, 8);
00064 MD5Final(tmp, &md5);
00065 hmac_md5_update(tmp, sizeof(tmp), &ctx);
00066 hmac_md5_final(dc->sess_key, &ctx);
00067
00068
00069 DEBUG(5,("creds_init_128\n"));
00070 DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
00071 DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data)));
00072 dump_data_pw("\tsession_key ", (const unsigned char *)dc->sess_key, 16);
00073
00074
00075
00076 des_crypt112(dc->clnt_chal.data,
00077 clnt_chal_in->data,
00078 dc->sess_key,
00079 1);
00080
00081 des_crypt112(dc->srv_chal.data,
00082 srv_chal_in->data,
00083 dc->sess_key,
00084 1);
00085
00086
00087 memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
00088 }
00089
00090
00091
00092
00093
00094
00095 static void creds_init_64(struct dcinfo *dc,
00096 const DOM_CHAL *clnt_chal_in,
00097 const DOM_CHAL *srv_chal_in,
00098 const unsigned char mach_pw[16])
00099 {
00100 uint32 sum[2];
00101 unsigned char sum2[8];
00102
00103
00104 if (dc->mach_pw != mach_pw) {
00105 memcpy(dc->mach_pw, mach_pw, 16);
00106 }
00107
00108 sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0);
00109 sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4);
00110
00111 SIVAL(sum2,0,sum[0]);
00112 SIVAL(sum2,4,sum[1]);
00113
00114 ZERO_STRUCT(dc->sess_key);
00115
00116 des_crypt128(dc->sess_key, sum2, dc->mach_pw);
00117
00118
00119 DEBUG(5,("creds_init_64\n"));
00120 DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
00121 DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data)));
00122 DEBUG(5,("\tclnt+srv : %s\n", credstr(sum2)));
00123 DEBUG(5,("\tsess_key_out : %s\n", credstr(dc->sess_key)));
00124
00125
00126
00127 des_crypt112(dc->clnt_chal.data,
00128 clnt_chal_in->data,
00129 dc->sess_key,
00130 1);
00131
00132 des_crypt112(dc->srv_chal.data,
00133 srv_chal_in->data,
00134 dc->sess_key,
00135 1);
00136
00137
00138 memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
00139 }
00140
00141
00142
00143
00144
00145
00146 static void creds_step(struct dcinfo *dc)
00147 {
00148 DOM_CHAL time_chal;
00149
00150 DEBUG(5,("\tsequence = 0x%x\n", (unsigned int)dc->sequence ));
00151
00152 DEBUG(5,("\tseed: %s\n", credstr(dc->seed_chal.data) ));
00153
00154 SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence);
00155 SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
00156
00157 DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) ));
00158
00159 des_crypt112(dc->clnt_chal.data, time_chal.data, dc->sess_key, 1);
00160
00161 DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) ));
00162
00163 SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
00164 SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
00165
00166 DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) ));
00167
00168 des_crypt112(dc->srv_chal.data, time_chal.data, dc->sess_key, 1);
00169
00170 DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) ));
00171 }
00172
00173
00174
00175
00176
00177 void creds_server_init(uint32 neg_flags,
00178 struct dcinfo *dc,
00179 DOM_CHAL *clnt_chal,
00180 DOM_CHAL *srv_chal,
00181 const unsigned char mach_pw[16],
00182 DOM_CHAL *init_chal_out)
00183 {
00184 DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags));
00185 DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) ));
00186 DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) ));
00187 dump_data_pw("creds_server_init: machine pass", mach_pw, 16);
00188
00189
00190 if (neg_flags & NETLOGON_NEG_128BIT) {
00191 creds_init_128(dc,
00192 clnt_chal,
00193 srv_chal,
00194 mach_pw);
00195 } else {
00196 creds_init_64(dc,
00197 clnt_chal,
00198 srv_chal,
00199 mach_pw);
00200 }
00201
00202 dump_data_pw("creds_server_init: session key", dc->sess_key, 16);
00203
00204 DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
00205 DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) ));
00206 DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) ));
00207
00208 memcpy(init_chal_out->data, dc->srv_chal.data, 8);
00209 }
00210
00211
00212
00213
00214
00215 BOOL creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in)
00216 {
00217 if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) {
00218 DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data)));
00219 DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data)));
00220 DEBUG(2,("creds_server_check: credentials check failed.\n"));
00221 return False;
00222 }
00223 DEBUG(10,("creds_server_check: credentials check OK.\n"));
00224 return True;
00225 }
00226
00227
00228
00229
00230
00231 static void creds_reseed(struct dcinfo *dc)
00232 {
00233 DOM_CHAL time_chal;
00234
00235 SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
00236 SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
00237
00238 dc->seed_chal = time_chal;
00239
00240 DEBUG(5,("cred_reseed: seed %s\n", credstr(dc->seed_chal.data) ));
00241 }
00242
00243
00244
00245
00246
00247 BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out)
00248 {
00249 BOOL ret;
00250 struct dcinfo tmp_dc = *dc;
00251
00252
00253
00254
00255 tmp_dc.sequence = received_cred->timestamp.time;
00256
00257 creds_step(&tmp_dc);
00258
00259
00260 cred_out->timestamp.time = tmp_dc.sequence + 1;
00261 cred_out->challenge = tmp_dc.srv_chal;
00262
00263 creds_reseed(&tmp_dc);
00264
00265 ret = creds_server_check(&tmp_dc, &received_cred->challenge);
00266 if (!ret) {
00267 return False;
00268 }
00269
00270
00271 *dc = tmp_dc;
00272 return True;
00273 }
00274
00275
00276
00277
00278
00279 void creds_client_init(uint32 neg_flags,
00280 struct dcinfo *dc,
00281 DOM_CHAL *clnt_chal,
00282 DOM_CHAL *srv_chal,
00283 const unsigned char mach_pw[16],
00284 DOM_CHAL *init_chal_out)
00285 {
00286 dc->sequence = time(NULL);
00287
00288 DEBUG(10,("creds_client_init: neg_flags : %x\n", (unsigned int)neg_flags));
00289 DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) ));
00290 DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) ));
00291 dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16);
00292
00293
00294 if (neg_flags & NETLOGON_NEG_128BIT) {
00295 creds_init_128(dc,
00296 clnt_chal,
00297 srv_chal,
00298 mach_pw);
00299 } else {
00300 creds_init_64(dc,
00301 clnt_chal,
00302 srv_chal,
00303 mach_pw);
00304 }
00305
00306 dump_data_pw("creds_client_init: session key", dc->sess_key, 16);
00307
00308 DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
00309 DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) ));
00310 DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));
00311
00312 memcpy(init_chal_out->data, dc->clnt_chal.data, 8);
00313 }
00314
00315
00316
00317
00318
00319 BOOL creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in)
00320 {
00321 if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) {
00322 DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data)));
00323 DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data)));
00324 DEBUG(0,("creds_client_check: credentials check failed.\n"));
00325 return False;
00326 }
00327 DEBUG(10,("creds_client_check: credentials check OK.\n"));
00328 return True;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338 void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out)
00339 {
00340 dc->sequence += 2;
00341 creds_step(dc);
00342 creds_reseed(dc);
00343
00344 next_cred_out->challenge = dc->clnt_chal;
00345 next_cred_out->timestamp.time = dc->sequence;
00346 }