PageRenderTime 1210ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/contrib/telnet/libtelnet/krb4encpwd.c

https://github.com/okuoku/freebsd-head
C | 428 lines | 288 code | 59 blank | 81 comment | 46 complexity | 1f1610d218eb121bad74f05b1b765307 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 <sys/cdefs.h>
  34. __FBSDID("$FreeBSD$");
  35. #ifndef lint
  36. static char sccsid[] = "@(#)krb4encpwd.c 8.3 (Berkeley) 5/30/95";
  37. #endif /* not lint */
  38. #ifdef KRB4_ENCPWD
  39. /*
  40. * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
  41. * ALL RIGHTS RESERVED
  42. *
  43. * "Digital Equipment Corporation authorizes the reproduction,
  44. * distribution and modification of this software subject to the following
  45. * restrictions:
  46. *
  47. * 1. Any partial or whole copy of this software, or any modification
  48. * thereof, must include this copyright notice in its entirety.
  49. *
  50. * 2. This software is supplied "as is" with no warranty of any kind,
  51. * expressed or implied, for any purpose, including any warranty of fitness
  52. * or merchantibility. DIGITAL assumes no responsibility for the use or
  53. * reliability of this software, nor promises to provide any form of
  54. * support for it on any basis.
  55. *
  56. * 3. Distribution of this software is authorized only if no profit or
  57. * remuneration of any kind is received in exchange for such distribution.
  58. *
  59. * 4. This software produces public key authentication certificates
  60. * bearing an expiration date established by DIGITAL and RSA Data
  61. * Security, Inc. It may cease to generate certificates after the expiration
  62. * date. Any modification of this software that changes or defeats
  63. * the expiration date or its effect is unauthorized.
  64. *
  65. * 5. Software that will renew or extend the expiration date of
  66. * authentication certificates produced by this software may be obtained
  67. * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
  68. * 94065, (415)595-8782, or from DIGITAL"
  69. *
  70. */
  71. #include <sys/types.h>
  72. #include <openssl/des.h>
  73. #include <arpa/telnet.h>
  74. #include <krb.h>
  75. #include <pwd.h>
  76. #include <stdio.h>
  77. #include <stdlib.h>
  78. #include <string.h>
  79. #include "encrypt.h"
  80. #include "auth.h"
  81. #include "misc.h"
  82. int krb_mk_encpwd_req(KTEXT, char *, char *, char *, char *, char *, char *);
  83. int krb_rd_encpwd_req(KTEXT, char *, char *, u_long, AUTH_DAT *, char *, char *, char *, char *);
  84. extern auth_debug_mode;
  85. static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
  86. AUTHTYPE_KRB4_ENCPWD, };
  87. static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
  88. TELQUAL_NAME, };
  89. #define KRB4_ENCPWD_AUTH 0 /* Authentication data follows */
  90. #define KRB4_ENCPWD_REJECT 1 /* Rejected (reason might follow) */
  91. #define KRB4_ENCPWD_ACCEPT 2 /* Accepted */
  92. #define KRB4_ENCPWD_CHALLENGE 3 /* Challenge for mutual auth. */
  93. #define KRB4_ENCPWD_ACK 4 /* Acknowledge */
  94. #define KRB_SERVICE_NAME "rcmd"
  95. static KTEXT_ST auth;
  96. static char name[ANAME_SZ];
  97. static char user_passwd[ANAME_SZ];
  98. static AUTH_DAT adat = { 0 };
  99. #ifdef ENCRYPTION
  100. static Block session_key = { 0 };
  101. #endif /* ENCRYPTION */
  102. static char challenge[REALM_SZ];
  103. static int
  104. Data(ap, type, d, c)
  105. Authenticator *ap;
  106. int type;
  107. void *d;
  108. int c;
  109. {
  110. unsigned char *p = str_data + 4;
  111. unsigned char *cd = (unsigned char *)d;
  112. if (c == -1)
  113. c = strlen((char *)cd);
  114. if (0) {
  115. printf("%s:%d: [%d] (%d)",
  116. str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
  117. str_data[3],
  118. type, c);
  119. printd(d, c);
  120. printf("\r\n");
  121. }
  122. *p++ = ap->type;
  123. *p++ = ap->way;
  124. *p++ = type;
  125. while (c-- > 0) {
  126. if ((*p++ = *cd++) == IAC)
  127. *p++ = IAC;
  128. }
  129. *p++ = IAC;
  130. *p++ = SE;
  131. if (str_data[3] == TELQUAL_IS)
  132. printsub('>', &str_data[2], p - (&str_data[2]));
  133. return(net_write(str_data, p - str_data));
  134. }
  135. int
  136. krb4encpwd_init(ap, server)
  137. Authenticator *ap;
  138. int server;
  139. {
  140. char hostname[80], *cp, *realm;
  141. C_Block skey;
  142. if (server) {
  143. str_data[3] = TELQUAL_REPLY;
  144. } else {
  145. str_data[3] = TELQUAL_IS;
  146. gethostname(hostname, sizeof(hostname));
  147. realm = krb_realmofhost(hostname);
  148. cp = strchr(hostname, '.');
  149. if (*cp != NULL) *cp = NULL;
  150. if (read_service_key(KRB_SERVICE_NAME, hostname, realm, 0,
  151. KEYFILE, (char *)skey)) {
  152. return(0);
  153. }
  154. }
  155. return(1);
  156. }
  157. int
  158. krb4encpwd_send(ap)
  159. Authenticator *ap;
  160. {
  161. printf("[ Trying KRB4ENCPWD ... ]\n");
  162. if (!UserNameRequested) {
  163. return(0);
  164. }
  165. if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
  166. return(0);
  167. }
  168. if (!Data(ap, KRB4_ENCPWD_ACK, (void *)NULL, 0)) {
  169. return(0);
  170. }
  171. return(1);
  172. }
  173. void
  174. krb4encpwd_is(ap, data, cnt)
  175. Authenticator *ap;
  176. unsigned char *data;
  177. int cnt;
  178. {
  179. Session_Key skey;
  180. Block datablock;
  181. char r_passwd[ANAME_SZ], r_user[ANAME_SZ];
  182. char lhostname[ANAME_SZ], *cp;
  183. int r;
  184. time_t now;
  185. if (cnt-- < 1)
  186. return;
  187. switch (*data++) {
  188. case KRB4_ENCPWD_AUTH:
  189. memmove((void *)auth.dat, (void *)data, auth.length = cnt);
  190. gethostname(lhostname, sizeof(lhostname));
  191. if ((cp = strchr(lhostname, '.')) != 0) *cp = '\0';
  192. if (r = krb_rd_encpwd_req(&auth, KRB_SERVICE_NAME, lhostname, 0, &adat, NULL, challenge, r_user, r_passwd)) {
  193. Data(ap, KRB4_ENCPWD_REJECT, (void *)"Auth failed", -1);
  194. auth_finished(ap, AUTH_REJECT);
  195. return;
  196. }
  197. auth_encrypt_userpwd(r_passwd);
  198. if (passwdok(UserNameRequested, UserPassword) == 0) {
  199. /*
  200. * illegal username and password
  201. */
  202. Data(ap, KRB4_ENCPWD_REJECT, (void *)"Illegal password", -1);
  203. auth_finished(ap, AUTH_REJECT);
  204. return;
  205. }
  206. memmove((void *)session_key, (void *)adat.session, sizeof(Block));
  207. Data(ap, KRB4_ENCPWD_ACCEPT, (void *)0, 0);
  208. auth_finished(ap, AUTH_USER);
  209. break;
  210. case KRB4_ENCPWD_CHALLENGE:
  211. /*
  212. * Take the received random challenge text and save
  213. * for future authentication.
  214. */
  215. memmove((void *)challenge, (void *)data, sizeof(Block));
  216. break;
  217. case KRB4_ENCPWD_ACK:
  218. /*
  219. * Receive ack, if mutual then send random challenge
  220. */
  221. /*
  222. * If we are doing mutual authentication, get set up to send
  223. * the challenge, and verify it when the response comes back.
  224. */
  225. if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
  226. register int i;
  227. time(&now);
  228. sprintf(challenge, "%x", now);
  229. Data(ap, KRB4_ENCPWD_CHALLENGE, (void *)challenge, strlen(challenge));
  230. }
  231. break;
  232. default:
  233. Data(ap, KRB4_ENCPWD_REJECT, 0, 0);
  234. break;
  235. }
  236. }
  237. void
  238. krb4encpwd_reply(ap, data, cnt)
  239. Authenticator *ap;
  240. unsigned char *data;
  241. int cnt;
  242. {
  243. Session_Key skey;
  244. KTEXT_ST krb_token;
  245. Block enckey;
  246. CREDENTIALS cred;
  247. int r;
  248. char randchal[REALM_SZ], instance[ANAME_SZ], *cp;
  249. char hostname[80], *realm;
  250. if (cnt-- < 1)
  251. return;
  252. switch (*data++) {
  253. case KRB4_ENCPWD_REJECT:
  254. if (cnt > 0) {
  255. printf("[ KRB4_ENCPWD refuses authentication because %.*s ]\r\n",
  256. cnt, data);
  257. } else
  258. printf("[ KRB4_ENCPWD refuses authentication ]\r\n");
  259. auth_send_retry();
  260. return;
  261. case KRB4_ENCPWD_ACCEPT:
  262. printf("[ KRB4_ENCPWD accepts you ]\n");
  263. auth_finished(ap, AUTH_USER);
  264. return;
  265. case KRB4_ENCPWD_CHALLENGE:
  266. /*
  267. * Verify that the response to the challenge is correct.
  268. */
  269. gethostname(hostname, sizeof(hostname));
  270. realm = krb_realmofhost(hostname);
  271. memmove((void *)challenge, (void *)data, cnt);
  272. memset(user_passwd, 0, sizeof(user_passwd));
  273. local_des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0);
  274. UserPassword = user_passwd;
  275. Challenge = challenge;
  276. strcpy(instance, RemoteHostName);
  277. if ((cp = strchr(instance, '.')) != 0) *cp = '\0';
  278. if (r = krb_mk_encpwd_req(&krb_token, KRB_SERVICE_NAME, instance, realm, Challenge, UserNameRequested, user_passwd)) {
  279. krb_token.length = 0;
  280. }
  281. if (!Data(ap, KRB4_ENCPWD_AUTH, (void *)krb_token.dat, krb_token.length)) {
  282. return;
  283. }
  284. break;
  285. default:
  286. return;
  287. }
  288. }
  289. int
  290. krb4encpwd_status(ap, name, level)
  291. Authenticator *ap;
  292. char *name;
  293. int level;
  294. {
  295. if (level < AUTH_USER)
  296. return(level);
  297. if (UserNameRequested && passwdok(UserNameRequested, UserPassword)) {
  298. strcpy(name, UserNameRequested);
  299. return(AUTH_VALID);
  300. } else {
  301. return(AUTH_USER);
  302. }
  303. }
  304. #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
  305. #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
  306. void
  307. krb4encpwd_printsub(data, cnt, buf, buflen)
  308. unsigned char *data, *buf;
  309. int cnt, buflen;
  310. {
  311. char lbuf[32];
  312. register int i;
  313. buf[buflen-1] = '\0'; /* make sure its NULL terminated */
  314. buflen -= 1;
  315. switch(data[3]) {
  316. case KRB4_ENCPWD_REJECT: /* Rejected (reason might follow) */
  317. strncpy((char *)buf, " REJECT ", buflen);
  318. goto common;
  319. case KRB4_ENCPWD_ACCEPT: /* Accepted (name might follow) */
  320. strncpy((char *)buf, " ACCEPT ", buflen);
  321. common:
  322. BUMP(buf, buflen);
  323. if (cnt <= 4)
  324. break;
  325. ADDC(buf, buflen, '"');
  326. for (i = 4; i < cnt; i++)
  327. ADDC(buf, buflen, data[i]);
  328. ADDC(buf, buflen, '"');
  329. ADDC(buf, buflen, '\0');
  330. break;
  331. case KRB4_ENCPWD_AUTH: /* Authentication data follows */
  332. strncpy((char *)buf, " AUTH", buflen);
  333. goto common2;
  334. case KRB4_ENCPWD_CHALLENGE:
  335. strncpy((char *)buf, " CHALLENGE", buflen);
  336. goto common2;
  337. case KRB4_ENCPWD_ACK:
  338. strncpy((char *)buf, " ACK", buflen);
  339. goto common2;
  340. default:
  341. sprintf(lbuf, " %d (unknown)", data[3]);
  342. strncpy((char *)buf, lbuf, buflen);
  343. common2:
  344. BUMP(buf, buflen);
  345. for (i = 4; i < cnt; i++) {
  346. sprintf(lbuf, " %d", data[i]);
  347. strncpy((char *)buf, lbuf, buflen);
  348. BUMP(buf, buflen);
  349. }
  350. break;
  351. }
  352. }
  353. int passwdok(name, passwd)
  354. char *name, *passwd;
  355. {
  356. char *crypt();
  357. char *salt, *p;
  358. struct passwd *pwd;
  359. int passwdok_status = 0;
  360. if (pwd = getpwnam(name))
  361. salt = pwd->pw_passwd;
  362. else salt = "xx";
  363. p = crypt(passwd, salt);
  364. if (pwd && !strcmp(p, pwd->pw_passwd)) {
  365. passwdok_status = 1;
  366. } else passwdok_status = 0;
  367. return(passwdok_status);
  368. }
  369. #endif