/crypto/heimdal/lib/gssapi/test_ntlm.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 337 lines · 243 code · 62 blank · 32 comment · 23 complexity · 2ebb237fe40d1d2a9b16c03807b622cd MD5 · raw file

  1. /*
  2. * Copyright (c) 2006 - 2008 Kungliga Tekniska Hรถgskolan
  3. * (Royal Institute of Technology, Stockholm, Sweden).
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * 3. Neither the name of KTH nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software without
  19. * specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
  22. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  24. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
  25. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  28. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  30. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  31. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include "config.h"
  34. #include <roken.h>
  35. #include <stdio.h>
  36. #include <gssapi.h>
  37. #include <err.h>
  38. #include <getarg.h>
  39. #include "test_common.h"
  40. #include <krb5.h>
  41. #include <heimntlm.h>
  42. static int
  43. test_libntlm_v1(int flags)
  44. {
  45. const char *user = "foo",
  46. *domain = "mydomain",
  47. *password = "digestpassword";
  48. OM_uint32 maj_stat, min_stat;
  49. gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
  50. gss_buffer_desc input, output;
  51. struct ntlm_type1 type1;
  52. struct ntlm_type2 type2;
  53. struct ntlm_type3 type3;
  54. struct ntlm_buf data;
  55. krb5_error_code ret;
  56. gss_name_t src_name = GSS_C_NO_NAME;
  57. memset(&type1, 0, sizeof(type1));
  58. memset(&type2, 0, sizeof(type2));
  59. memset(&type3, 0, sizeof(type3));
  60. type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|flags;
  61. type1.domain = strdup(domain);
  62. type1.hostname = NULL;
  63. type1.os[0] = 0;
  64. type1.os[1] = 0;
  65. ret = heim_ntlm_encode_type1(&type1, &data);
  66. if (ret)
  67. errx(1, "heim_ntlm_encode_type1");
  68. input.value = data.data;
  69. input.length = data.length;
  70. output.length = 0;
  71. output.value = NULL;
  72. maj_stat = gss_accept_sec_context(&min_stat,
  73. &ctx,
  74. GSS_C_NO_CREDENTIAL,
  75. &input,
  76. GSS_C_NO_CHANNEL_BINDINGS,
  77. NULL,
  78. NULL,
  79. &output,
  80. NULL,
  81. NULL,
  82. NULL);
  83. free(data.data);
  84. if (GSS_ERROR(maj_stat))
  85. errx(1, "accept_sec_context v1: %s",
  86. gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
  87. if (output.length == 0)
  88. errx(1, "output.length == 0");
  89. data.data = output.value;
  90. data.length = output.length;
  91. ret = heim_ntlm_decode_type2(&data, &type2);
  92. if (ret)
  93. errx(1, "heim_ntlm_decode_type2");
  94. gss_release_buffer(&min_stat, &output);
  95. type3.flags = type2.flags;
  96. type3.username = rk_UNCONST(user);
  97. type3.targetname = type2.targetname;
  98. type3.ws = rk_UNCONST("workstation");
  99. {
  100. struct ntlm_buf key;
  101. heim_ntlm_nt_key(password, &key);
  102. heim_ntlm_calculate_ntlm1(key.data, key.length,
  103. type2.challenge,
  104. &type3.ntlm);
  105. if (flags & NTLM_NEG_KEYEX) {
  106. struct ntlm_buf sessionkey;
  107. heim_ntlm_build_ntlm1_master(key.data, key.length,
  108. &sessionkey,
  109. &type3.sessionkey);
  110. free(sessionkey.data);
  111. }
  112. free(key.data);
  113. }
  114. ret = heim_ntlm_encode_type3(&type3, &data);
  115. if (ret)
  116. errx(1, "heim_ntlm_encode_type3");
  117. input.length = data.length;
  118. input.value = data.data;
  119. maj_stat = gss_accept_sec_context(&min_stat,
  120. &ctx,
  121. GSS_C_NO_CREDENTIAL,
  122. &input,
  123. GSS_C_NO_CHANNEL_BINDINGS,
  124. &src_name,
  125. NULL,
  126. &output,
  127. NULL,
  128. NULL,
  129. NULL);
  130. free(input.value);
  131. if (maj_stat != GSS_S_COMPLETE)
  132. errx(1, "accept_sec_context v1 2 %s",
  133. gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
  134. gss_release_buffer(&min_stat, &output);
  135. gss_delete_sec_context(&min_stat, &ctx, NULL);
  136. if (src_name == GSS_C_NO_NAME)
  137. errx(1, "no source name!");
  138. gss_display_name(&min_stat, src_name, &output, NULL);
  139. printf("src_name: %.*s\n", (int)output.length, (char*)output.value);
  140. gss_release_name(&min_stat, &src_name);
  141. gss_release_buffer(&min_stat, &output);
  142. return 0;
  143. }
  144. static int
  145. test_libntlm_v2(int flags)
  146. {
  147. const char *user = "foo",
  148. *domain = "mydomain",
  149. *password = "digestpassword";
  150. OM_uint32 maj_stat, min_stat;
  151. gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
  152. gss_buffer_desc input, output;
  153. struct ntlm_type1 type1;
  154. struct ntlm_type2 type2;
  155. struct ntlm_type3 type3;
  156. struct ntlm_buf data;
  157. krb5_error_code ret;
  158. memset(&type1, 0, sizeof(type1));
  159. memset(&type2, 0, sizeof(type2));
  160. memset(&type3, 0, sizeof(type3));
  161. type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
  162. type1.domain = strdup(domain);
  163. type1.hostname = NULL;
  164. type1.os[0] = 0;
  165. type1.os[1] = 0;
  166. ret = heim_ntlm_encode_type1(&type1, &data);
  167. if (ret)
  168. errx(1, "heim_ntlm_encode_type1");
  169. input.value = data.data;
  170. input.length = data.length;
  171. output.length = 0;
  172. output.value = NULL;
  173. maj_stat = gss_accept_sec_context(&min_stat,
  174. &ctx,
  175. GSS_C_NO_CREDENTIAL,
  176. &input,
  177. GSS_C_NO_CHANNEL_BINDINGS,
  178. NULL,
  179. NULL,
  180. &output,
  181. NULL,
  182. NULL,
  183. NULL);
  184. free(data.data);
  185. if (GSS_ERROR(maj_stat))
  186. errx(1, "accept_sec_context v2 %s",
  187. gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
  188. if (output.length == 0)
  189. errx(1, "output.length == 0");
  190. data.data = output.value;
  191. data.length = output.length;
  192. ret = heim_ntlm_decode_type2(&data, &type2);
  193. if (ret)
  194. errx(1, "heim_ntlm_decode_type2");
  195. type3.flags = type2.flags;
  196. type3.username = rk_UNCONST(user);
  197. type3.targetname = type2.targetname;
  198. type3.ws = rk_UNCONST("workstation");
  199. {
  200. struct ntlm_buf key;
  201. unsigned char ntlmv2[16];
  202. heim_ntlm_nt_key(password, &key);
  203. heim_ntlm_calculate_ntlm2(key.data, key.length,
  204. user,
  205. type2.targetname,
  206. type2.challenge,
  207. &type2.targetinfo,
  208. ntlmv2,
  209. &type3.ntlm);
  210. free(key.data);
  211. if (flags & NTLM_NEG_KEYEX) {
  212. struct ntlm_buf sessionkey;
  213. heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
  214. &sessionkey,
  215. &type3.sessionkey);
  216. free(sessionkey.data);
  217. }
  218. }
  219. ret = heim_ntlm_encode_type3(&type3, &data);
  220. if (ret)
  221. errx(1, "heim_ntlm_encode_type3");
  222. input.length = data.length;
  223. input.value = data.data;
  224. maj_stat = gss_accept_sec_context(&min_stat,
  225. &ctx,
  226. GSS_C_NO_CREDENTIAL,
  227. &input,
  228. GSS_C_NO_CHANNEL_BINDINGS,
  229. NULL,
  230. NULL,
  231. &output,
  232. NULL,
  233. NULL,
  234. NULL);
  235. free(input.value);
  236. if (maj_stat != GSS_S_COMPLETE)
  237. errx(1, "accept_sec_context v2 2 %s",
  238. gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
  239. gss_delete_sec_context(&min_stat, &ctx, NULL);
  240. return 0;
  241. }
  242. static int version_flag = 0;
  243. static int help_flag = 0;
  244. static struct getargs args[] = {
  245. {"version", 0, arg_flag, &version_flag, "print version", NULL },
  246. {"help", 0, arg_flag, &help_flag, NULL, NULL }
  247. };
  248. static void
  249. usage (int ret)
  250. {
  251. arg_printusage (args, sizeof(args)/sizeof(*args),
  252. NULL, "");
  253. exit (ret);
  254. }
  255. int
  256. main(int argc, char **argv)
  257. {
  258. int ret = 0, optind = 0;
  259. setprogname(argv[0]);
  260. if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
  261. usage(1);
  262. if (help_flag)
  263. usage (0);
  264. if(version_flag){
  265. print_version(NULL);
  266. exit(0);
  267. }
  268. argc -= optind;
  269. argv += optind;
  270. ret += test_libntlm_v1(0);
  271. ret += test_libntlm_v1(NTLM_NEG_KEYEX);
  272. ret += test_libntlm_v2(0);
  273. ret += test_libntlm_v2(NTLM_NEG_KEYEX);
  274. return 0;
  275. }