PageRenderTime 49ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/crypto/heimdal/appl/telnet/libtelnet/krb4encpwd.c

https://github.com/tpn/freebsd-head
C | 436 lines | 295 code | 60 blank | 81 comment | 47 complexity | 2532f9a60ea36af6353453cdcbeb9944 MD5 | raw file
  1. /*-
  2. * Copyright (c) 1992, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. * must display the following acknowledgement:
  15. * This product includes software developed by the University of
  16. * California, Berkeley and its contributors.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. #include <config.h>
  34. RCSID("$Id: krb4encpwd.c 22071 2007-11-14 20:04:50Z lha $");
  35. #ifdef KRB4_ENCPWD
  36. /*
  37. * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
  38. * ALL RIGHTS RESERVED
  39. *
  40. * "Digital Equipment Corporation authorizes the reproduction,
  41. * distribution and modification of this software subject to the following
  42. * restrictions:
  43. *
  44. * 1. Any partial or whole copy of this software, or any modification
  45. * thereof, must include this copyright notice in its entirety.
  46. *
  47. * 2. This software is supplied "as is" with no warranty of any kind,
  48. * expressed or implied, for any purpose, including any warranty of fitness
  49. * or merchantibility. DIGITAL assumes no responsibility for the use or
  50. * reliability of this software, nor promises to provide any form of
  51. * support for it on any basis.
  52. *
  53. * 3. Distribution of this software is authorized only if no profit or
  54. * remuneration of any kind is received in exchange for such distribution.
  55. *
  56. * 4. This software produces public key authentication certificates
  57. * bearing an expiration date established by DIGITAL and RSA Data
  58. * Security, Inc. It may cease to generate certificates after the expiration
  59. * date. Any modification of this software that changes or defeats
  60. * the expiration date or its effect is unauthorized.
  61. *
  62. * 5. Software that will renew or extend the expiration date of
  63. * authentication certificates produced by this software may be obtained
  64. * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
  65. * 94065, (415)595-8782, or from DIGITAL"
  66. *
  67. */
  68. #include <sys/types.h>
  69. #include <arpa/telnet.h>
  70. #include <pwd.h>
  71. #include <stdio.h>
  72. #include <krb.h>
  73. #include <stdlib.h>
  74. #include <string.h>
  75. #ifdef SOCKS
  76. #include <socks.h>
  77. #endif
  78. #include "encrypt.h"
  79. #include "auth.h"
  80. #include "misc.h"
  81. int krb_mk_encpwd_req (KTEXT, char *, char *, char *, char *, char *, char *);
  82. int krb_rd_encpwd_req (KTEXT, char *, char *, u_long, AUTH_DAT *, char *, char *, char *, char *);
  83. extern auth_debug_mode;
  84. static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
  85. AUTHTYPE_KRB4_ENCPWD, };
  86. static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
  87. TELQUAL_NAME, };
  88. #define KRB4_ENCPWD_AUTH 0 /* Authentication data follows */
  89. #define KRB4_ENCPWD_REJECT 1 /* Rejected (reason might follow) */
  90. #define KRB4_ENCPWD_ACCEPT 2 /* Accepted */
  91. #define KRB4_ENCPWD_CHALLENGE 3 /* Challenge for mutual auth. */
  92. #define KRB4_ENCPWD_ACK 4 /* Acknowledge */
  93. #define KRB_SERVICE_NAME "rcmd"
  94. static KTEXT_ST auth;
  95. static char name[ANAME_SZ];
  96. static char user_passwd[ANAME_SZ];
  97. static AUTH_DAT adat = { 0 };
  98. static des_key_schedule sched;
  99. static char challenge[REALM_SZ];
  100. static int
  101. Data(ap, type, d, c)
  102. Authenticator *ap;
  103. int type;
  104. void *d;
  105. int c;
  106. {
  107. unsigned char *p = str_data + 4;
  108. unsigned char *cd = (unsigned char *)d;
  109. if (c == -1)
  110. c = strlen(cd);
  111. if (0) {
  112. printf("%s:%d: [%d] (%d)",
  113. str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
  114. str_data[3],
  115. type, c);
  116. printd(d, c);
  117. printf("\r\n");
  118. }
  119. *p++ = ap->type;
  120. *p++ = ap->way;
  121. *p++ = type;
  122. while (c-- > 0) {
  123. if ((*p++ = *cd++) == IAC)
  124. *p++ = IAC;
  125. }
  126. *p++ = IAC;
  127. *p++ = SE;
  128. if (str_data[3] == TELQUAL_IS)
  129. printsub('>', &str_data[2], p - (&str_data[2]));
  130. return(telnet_net_write(str_data, p - str_data));
  131. }
  132. int
  133. krb4encpwd_init(ap, server)
  134. Authenticator *ap;
  135. int server;
  136. {
  137. char hostname[80], *cp, *realm;
  138. des_clock skey;
  139. if (server) {
  140. str_data[3] = TELQUAL_REPLY;
  141. } else {
  142. str_data[3] = TELQUAL_IS;
  143. gethostname(hostname, sizeof(hostname));
  144. realm = krb_realmofhost(hostname);
  145. cp = strchr(hostname, '.');
  146. if (*cp != NULL) *cp = NULL;
  147. if (read_service_key(KRB_SERVICE_NAME, hostname, realm, 0,
  148. KEYFILE, (char *)skey)) {
  149. return(0);
  150. }
  151. }
  152. return(1);
  153. }
  154. int
  155. krb4encpwd_send(ap)
  156. Authenticator *ap;
  157. {
  158. printf("[ Trying KRB4ENCPWD ... ]\r\n");
  159. if (!UserNameRequested) {
  160. return(0);
  161. }
  162. if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
  163. return(0);
  164. }
  165. if (!Data(ap, KRB4_ENCPWD_ACK, NULL, 0)) {
  166. return(0);
  167. }
  168. return(1);
  169. }
  170. void
  171. krb4encpwd_is(ap, data, cnt)
  172. Authenticator *ap;
  173. unsigned char *data;
  174. int cnt;
  175. {
  176. Session_Key skey;
  177. des_cblock datablock;
  178. char r_passwd[ANAME_SZ], r_user[ANAME_SZ];
  179. char lhostname[ANAME_SZ], *cp;
  180. int r;
  181. time_t now;
  182. if (cnt-- < 1)
  183. return;
  184. switch (*data++) {
  185. case KRB4_ENCPWD_AUTH:
  186. memmove(auth.dat, data, auth.length = cnt);
  187. gethostname(lhostname, sizeof(lhostname));
  188. if ((cp = strchr(lhostname, '.')) != 0) *cp = '\0';
  189. if (r = krb_rd_encpwd_req(&auth, KRB_SERVICE_NAME, lhostname, 0, &adat, NULL, challenge, r_user, r_passwd)) {
  190. Data(ap, KRB4_ENCPWD_REJECT, "Auth failed", -1);
  191. auth_finished(ap, AUTH_REJECT);
  192. return;
  193. }
  194. auth_encrypt_userpwd(r_passwd);
  195. if (passwdok(UserNameRequested, UserPassword) == 0) {
  196. /*
  197. * illegal username and password
  198. */
  199. Data(ap, KRB4_ENCPWD_REJECT, "Illegal password", -1);
  200. auth_finished(ap, AUTH_REJECT);
  201. return;
  202. }
  203. memmove(session_key, adat.session, sizeof(des_cblock));
  204. Data(ap, KRB4_ENCPWD_ACCEPT, 0, 0);
  205. auth_finished(ap, AUTH_USER);
  206. break;
  207. case KRB4_ENCPWD_CHALLENGE:
  208. /*
  209. * Take the received random challenge text and save
  210. * for future authentication.
  211. */
  212. memmove(challenge, data, sizeof(des_cblock));
  213. break;
  214. case KRB4_ENCPWD_ACK:
  215. /*
  216. * Receive ack, if mutual then send random challenge
  217. */
  218. /*
  219. * If we are doing mutual authentication, get set up to send
  220. * the challenge, and verify it when the response comes back.
  221. */
  222. if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  223. int i;
  224. time(&now);
  225. snprintf(challenge, sizeof(challenge), "%x", now);
  226. Data(ap, KRB4_ENCPWD_CHALLENGE, challenge, strlen(challenge));
  227. }
  228. break;
  229. default:
  230. Data(ap, KRB4_ENCPWD_REJECT, 0, 0);
  231. break;
  232. }
  233. }
  234. void
  235. krb4encpwd_reply(ap, data, cnt)
  236. Authenticator *ap;
  237. unsigned char *data;
  238. int cnt;
  239. {
  240. Session_Key skey;
  241. KTEXT_ST krb_token;
  242. des_cblock enckey;
  243. CREDENTIALS cred;
  244. int r;
  245. char randchal[REALM_SZ], instance[ANAME_SZ], *cp;
  246. char hostname[80], *realm;
  247. if (cnt-- < 1)
  248. return;
  249. switch (*data++) {
  250. case KRB4_ENCPWD_REJECT:
  251. if (cnt > 0) {
  252. printf("[ KRB4_ENCPWD refuses authentication because %.*s ]\r\n",
  253. cnt, data);
  254. } else
  255. printf("[ KRB4_ENCPWD refuses authentication ]\r\n");
  256. auth_send_retry();
  257. return;
  258. case KRB4_ENCPWD_ACCEPT:
  259. printf("[ KRB4_ENCPWD accepts you ]\r\n");
  260. auth_finished(ap, AUTH_USER);
  261. return;
  262. case KRB4_ENCPWD_CHALLENGE:
  263. /*
  264. * Verify that the response to the challenge is correct.
  265. */
  266. gethostname(hostname, sizeof(hostname));
  267. realm = krb_realmofhost(hostname);
  268. memmove(challenge, data, cnt);
  269. memset(user_passwd, 0, sizeof(user_passwd));
  270. des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0);
  271. UserPassword = user_passwd;
  272. Challenge = challenge;
  273. strlcpy(instance, RemoteHostName, sizeof(instance));
  274. if ((cp = strchr(instance, '.')) != 0) *cp = '\0';
  275. if (r = krb_mk_encpwd_req(&krb_token, KRB_SERVICE_NAME, instance, realm, Challenge, UserNameRequested, user_passwd)) {
  276. krb_token.length = 0;
  277. }
  278. if (!Data(ap, KRB4_ENCPWD_AUTH, krb_token.dat, krb_token.length)) {
  279. return;
  280. }
  281. break;
  282. default:
  283. return;
  284. }
  285. }
  286. int
  287. krb4encpwd_status(ap, name, name_sz, level)
  288. Authenticator *ap;
  289. char *name;
  290. size_t name_sz;
  291. int level;
  292. {
  293. if (level < AUTH_USER)
  294. return(level);
  295. if (UserNameRequested && passwdok(UserNameRequested, UserPassword)) {
  296. strlcpy(name, UserNameRequested, name_sz);
  297. return(AUTH_VALID);
  298. } else {
  299. return(AUTH_USER);
  300. }
  301. }
  302. #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
  303. #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
  304. void
  305. krb4encpwd_printsub(data, cnt, buf, buflen)
  306. unsigned char *data, *buf;
  307. int cnt, buflen;
  308. {
  309. int i;
  310. buf[buflen-1] = '\0'; /* make sure it's NULL terminated */
  311. buflen -= 1;
  312. switch(data[3]) {
  313. case KRB4_ENCPWD_REJECT: /* Rejected (reason might follow) */
  314. strlcpy((char *)buf, " REJECT ", buflen);
  315. goto common;
  316. case KRB4_ENCPWD_ACCEPT: /* Accepted (name might follow) */
  317. strlcpy((char *)buf, " ACCEPT ", buflen);
  318. common:
  319. BUMP(buf, buflen);
  320. if (cnt <= 4)
  321. break;
  322. ADDC(buf, buflen, '"');
  323. for (i = 4; i < cnt; i++)
  324. ADDC(buf, buflen, data[i]);
  325. ADDC(buf, buflen, '"');
  326. ADDC(buf, buflen, '\0');
  327. break;
  328. case KRB4_ENCPWD_AUTH: /* Authentication data follows */
  329. strlcpy((char *)buf, " AUTH", buflen);
  330. goto common2;
  331. case KRB4_ENCPWD_CHALLENGE:
  332. strlcpy((char *)buf, " CHALLENGE", buflen);
  333. goto common2;
  334. case KRB4_ENCPWD_ACK:
  335. strlcpy((char *)buf, " ACK", buflen);
  336. goto common2;
  337. default:
  338. snprintf(buf, buflen, " %d (unknown)", data[3]);
  339. common2:
  340. BUMP(buf, buflen);
  341. for (i = 4; i < cnt; i++) {
  342. snprintf(buf, buflen, " %d", data[i]);
  343. BUMP(buf, buflen);
  344. }
  345. break;
  346. }
  347. }
  348. int passwdok(name, passwd)
  349. char *name, *passwd;
  350. {
  351. char *crypt();
  352. char *salt, *p;
  353. struct passwd *pwd;
  354. int passwdok_status = 0;
  355. if (pwd = k_getpwnam(name))
  356. salt = pwd->pw_passwd;
  357. else salt = "xx";
  358. p = crypt(passwd, salt);
  359. if (pwd && !strcmp(p, pwd->pw_passwd)) {
  360. passwdok_status = 1;
  361. } else passwdok_status = 0;
  362. return(passwdok_status);
  363. }
  364. #endif
  365. #ifdef notdef
  366. prkey(msg, key)
  367. char *msg;
  368. unsigned char *key;
  369. {
  370. int i;
  371. printf("%s:", msg);
  372. for (i = 0; i < 8; i++)
  373. printf(" %3d", key[i]);
  374. printf("\r\n");
  375. }
  376. #endif