remove krb4
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@24500 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		| @@ -1,340 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan |  | ||||||
|  * (Royal Institute of Technology, Stockholm, Sweden). |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions |  | ||||||
|  * are met: |  | ||||||
|  * |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer. |  | ||||||
|  * |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright |  | ||||||
|  *    notice, this list of conditions and the following disclaimer in the |  | ||||||
|  *    documentation and/or other materials provided with the distribution. |  | ||||||
|  * |  | ||||||
|  * 3. Neither the name of the Institute nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND |  | ||||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE |  | ||||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |  | ||||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |  | ||||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |  | ||||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |  | ||||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |  | ||||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |  | ||||||
|  * SUCH DAMAGE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| #ifdef FTP_SERVER |  | ||||||
| #include "ftpd_locl.h" |  | ||||||
| #else |  | ||||||
| #include "ftp_locl.h" |  | ||||||
| #endif |  | ||||||
| #include <krb.h> |  | ||||||
|  |  | ||||||
| RCSID("$Id$"); |  | ||||||
|  |  | ||||||
| #ifdef FTP_SERVER |  | ||||||
| #define LOCAL_ADDR ctrl_addr |  | ||||||
| #define REMOTE_ADDR his_addr |  | ||||||
| #else |  | ||||||
| #define LOCAL_ADDR myctladdr |  | ||||||
| #define REMOTE_ADDR hisctladdr |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| extern struct sockaddr *LOCAL_ADDR, *REMOTE_ADDR; |  | ||||||
|  |  | ||||||
| struct krb4_data { |  | ||||||
|     des_cblock key; |  | ||||||
|     des_key_schedule schedule; |  | ||||||
|     char name[ANAME_SZ]; |  | ||||||
|     char instance[INST_SZ]; |  | ||||||
|     char realm[REALM_SZ]; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_check_prot(void *app_data, int level) |  | ||||||
| { |  | ||||||
|     if(level == prot_confidential) |  | ||||||
| 	return -1; |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_decode(void *app_data, void *buf, int len, int level) |  | ||||||
| { |  | ||||||
|     MSG_DAT m; |  | ||||||
|     int e; |  | ||||||
|     struct krb4_data *d = app_data; |  | ||||||
|  |  | ||||||
|     if(level == prot_safe) |  | ||||||
| 	e = krb_rd_safe(buf, len, &d->key, |  | ||||||
| 			(struct sockaddr_in *)REMOTE_ADDR, |  | ||||||
| 			(struct sockaddr_in *)LOCAL_ADDR, &m); |  | ||||||
|     else |  | ||||||
| 	e = krb_rd_priv(buf, len, d->schedule, &d->key, |  | ||||||
| 			(struct sockaddr_in *)REMOTE_ADDR, |  | ||||||
| 			(struct sockaddr_in *)LOCAL_ADDR, &m); |  | ||||||
|     if(e){ |  | ||||||
| 	syslog(LOG_ERR, "krb4_decode: %s", krb_get_err_text(e)); |  | ||||||
| 	return -1; |  | ||||||
|     } |  | ||||||
|     memmove(buf, m.app_data, m.app_length); |  | ||||||
|     return m.app_length; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_overhead(void *app_data, int level, int len) |  | ||||||
| { |  | ||||||
|     return 31; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_encode(void *app_data, void *from, int length, int level, void **to) |  | ||||||
| { |  | ||||||
|     struct krb4_data *d = app_data; |  | ||||||
|     *to = malloc(length + 31); |  | ||||||
|     if(level == prot_safe) |  | ||||||
| 	return krb_mk_safe(from, *to, length, &d->key, |  | ||||||
| 			   (struct sockaddr_in *)LOCAL_ADDR, |  | ||||||
| 			   (struct sockaddr_in *)REMOTE_ADDR); |  | ||||||
|     else if(level == prot_private) |  | ||||||
| 	return krb_mk_priv(from, *to, length, d->schedule, &d->key, |  | ||||||
| 			   (struct sockaddr_in *)LOCAL_ADDR, |  | ||||||
| 			   (struct sockaddr_in *)REMOTE_ADDR); |  | ||||||
|     else |  | ||||||
| 	return -1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #ifdef FTP_SERVER |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_adat(void *app_data, void *buf, size_t len) |  | ||||||
| { |  | ||||||
|     KTEXT_ST tkt; |  | ||||||
|     AUTH_DAT auth_dat; |  | ||||||
|     char *p; |  | ||||||
|     int kerror; |  | ||||||
|     uint32_t cs; |  | ||||||
|     char msg[35]; /* size of encrypted block */ |  | ||||||
|     int tmp_len; |  | ||||||
|     struct krb4_data *d = app_data; |  | ||||||
|     char inst[INST_SZ]; |  | ||||||
|     struct sockaddr_in *his_addr_sin = (struct sockaddr_in *)his_addr; |  | ||||||
|  |  | ||||||
|     memcpy(tkt.dat, buf, len); |  | ||||||
|     tkt.length = len; |  | ||||||
|  |  | ||||||
|     k_getsockinst(0, inst, sizeof(inst)); |  | ||||||
|     kerror = krb_rd_req(&tkt, "ftp", inst, |  | ||||||
| 			his_addr_sin->sin_addr.s_addr, &auth_dat, ""); |  | ||||||
|     if(kerror == RD_AP_UNDEC){ |  | ||||||
| 	k_getsockinst(0, inst, sizeof(inst)); |  | ||||||
| 	kerror = krb_rd_req(&tkt, "rcmd", inst, |  | ||||||
| 			    his_addr_sin->sin_addr.s_addr, &auth_dat, ""); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if(kerror){ |  | ||||||
| 	reply(535, "Error reading request: %s.", krb_get_err_text(kerror)); |  | ||||||
| 	return -1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     memcpy(d->key, auth_dat.session, sizeof(d->key)); |  | ||||||
|     des_set_key(&d->key, d->schedule); |  | ||||||
|  |  | ||||||
|     strlcpy(d->name, auth_dat.pname, sizeof(d->name)); |  | ||||||
|     strlcpy(d->instance, auth_dat.pinst, sizeof(d->instance)); |  | ||||||
|     strlcpy(d->realm, auth_dat.prealm, sizeof(d->instance)); |  | ||||||
|  |  | ||||||
|     cs = auth_dat.checksum + 1; |  | ||||||
|     { |  | ||||||
| 	unsigned char tmp[4]; |  | ||||||
| 	KRB_PUT_INT(cs, tmp, 4, sizeof(tmp)); |  | ||||||
| 	tmp_len = krb_mk_safe(tmp, msg, 4, &d->key, |  | ||||||
| 			      (struct sockaddr_in *)LOCAL_ADDR, |  | ||||||
| 			      (struct sockaddr_in *)REMOTE_ADDR); |  | ||||||
|     } |  | ||||||
|     if(tmp_len < 0){ |  | ||||||
| 	reply(535, "Error creating reply: %s.", strerror(errno)); |  | ||||||
| 	return -1; |  | ||||||
|     } |  | ||||||
|     len = tmp_len; |  | ||||||
|     if(base64_encode(msg, len, &p) < 0) { |  | ||||||
| 	reply(535, "Out of memory base64-encoding."); |  | ||||||
| 	return -1; |  | ||||||
|     } |  | ||||||
|     reply(235, "ADAT=%s", p); |  | ||||||
|     sec_complete = 1; |  | ||||||
|     free(p); |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_userok(void *app_data, char *user) |  | ||||||
| { |  | ||||||
|     struct krb4_data *d = app_data; |  | ||||||
|     return krb_kuserok(d->name, d->instance, d->realm, user); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct sec_server_mech krb4_server_mech = { |  | ||||||
|     "KERBEROS_V4", |  | ||||||
|     sizeof(struct krb4_data), |  | ||||||
|     NULL, /* init */ |  | ||||||
|     NULL, /* end */ |  | ||||||
|     krb4_check_prot, |  | ||||||
|     krb4_overhead, |  | ||||||
|     krb4_encode, |  | ||||||
|     krb4_decode, |  | ||||||
|     /* */ |  | ||||||
|     NULL, |  | ||||||
|     krb4_adat, |  | ||||||
|     NULL, /* pbsz */ |  | ||||||
|     NULL, /* ccc */ |  | ||||||
|     krb4_userok |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #else /* FTP_SERVER */ |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_init(void *app_data) |  | ||||||
| { |  | ||||||
|    return !use_kerberos; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| mk_auth(struct krb4_data *d, KTEXT adat, |  | ||||||
| 	char *service, char *host, int checksum) |  | ||||||
| { |  | ||||||
|     int ret; |  | ||||||
|     CREDENTIALS cred; |  | ||||||
|     char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ]; |  | ||||||
|  |  | ||||||
|     strlcpy(sname, service, sizeof(sname)); |  | ||||||
|     strlcpy(inst, krb_get_phost(host), sizeof(inst)); |  | ||||||
|     strlcpy(realm, krb_realmofhost(host), sizeof(realm)); |  | ||||||
|     ret = krb_mk_req(adat, sname, inst, realm, checksum); |  | ||||||
|     if(ret) |  | ||||||
| 	return ret; |  | ||||||
|     strlcpy(sname, service, sizeof(sname)); |  | ||||||
|     strlcpy(inst, krb_get_phost(host), sizeof(inst)); |  | ||||||
|     strlcpy(realm, krb_realmofhost(host), sizeof(realm)); |  | ||||||
|     ret = krb_get_cred(sname, inst, realm, &cred); |  | ||||||
|     memmove(&d->key, &cred.session, sizeof(des_cblock)); |  | ||||||
|     des_key_sched(&d->key, d->schedule); |  | ||||||
|     memset(&cred, 0, sizeof(cred)); |  | ||||||
|     return ret; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static int |  | ||||||
| krb4_auth(void *app_data, char *host) |  | ||||||
| { |  | ||||||
|     int ret; |  | ||||||
|     char *p; |  | ||||||
|     int len; |  | ||||||
|     KTEXT_ST adat; |  | ||||||
|     MSG_DAT msg_data; |  | ||||||
|     int checksum; |  | ||||||
|     uint32_t cs; |  | ||||||
|     struct krb4_data *d = app_data; |  | ||||||
|     struct sockaddr_in *localaddr  = (struct sockaddr_in *)LOCAL_ADDR; |  | ||||||
|     struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR; |  | ||||||
|  |  | ||||||
|     checksum = getpid(); |  | ||||||
|     ret = mk_auth(d, &adat, "ftp", host, checksum); |  | ||||||
|     if(ret == KDC_PR_UNKNOWN) |  | ||||||
| 	ret = mk_auth(d, &adat, "rcmd", host, checksum); |  | ||||||
|     if(ret){ |  | ||||||
| 	printf("%s\n", krb_get_err_text(ret)); |  | ||||||
| 	return AUTH_CONTINUE; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| #ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM |  | ||||||
|     if (krb_get_config_bool("nat_in_use")) { |  | ||||||
|       struct in_addr natAddr; |  | ||||||
|  |  | ||||||
|       if (krb_get_our_ip_for_realm(krb_realmofhost(host), |  | ||||||
| 				   &natAddr) != KSUCCESS |  | ||||||
| 	  && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS) |  | ||||||
| 	printf("Can't get address for realm %s\n", |  | ||||||
| 	       krb_realmofhost(host)); |  | ||||||
|       else { |  | ||||||
| 	if (natAddr.s_addr != localaddr->sin_addr.s_addr) { |  | ||||||
| 	  printf("Using NAT IP address (%s) for kerberos 4\n", |  | ||||||
| 		 inet_ntoa(natAddr)); |  | ||||||
| 	  localaddr->sin_addr = natAddr; |  | ||||||
| 	 |  | ||||||
| 	  /* |  | ||||||
| 	   * This not the best place to do this, but it |  | ||||||
| 	   * is here we know that (probably) NAT is in |  | ||||||
| 	   * use! |  | ||||||
| 	   */ |  | ||||||
|  |  | ||||||
| 	  passivemode = 1; |  | ||||||
| 	  printf("Setting: Passive mode on.\n"); |  | ||||||
| 	} |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|     printf("Local address is %s\n", inet_ntoa(localaddr->sin_addr)); |  | ||||||
|     printf("Remote address is %s\n", inet_ntoa(remoteaddr->sin_addr)); |  | ||||||
|  |  | ||||||
|    if(base64_encode(adat.dat, adat.length, &p) < 0) { |  | ||||||
| 	printf("Out of memory base64-encoding.\n"); |  | ||||||
| 	return AUTH_CONTINUE; |  | ||||||
|     } |  | ||||||
|     ret = command("ADAT %s", p); |  | ||||||
|     free(p); |  | ||||||
|  |  | ||||||
|     if(ret != COMPLETE){ |  | ||||||
| 	printf("Server didn't accept auth data.\n"); |  | ||||||
| 	return AUTH_ERROR; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     p = strstr(reply_string, "ADAT="); |  | ||||||
|     if(!p){ |  | ||||||
| 	printf("Remote host didn't send adat reply.\n"); |  | ||||||
| 	return AUTH_ERROR; |  | ||||||
|     } |  | ||||||
|     p += 5; |  | ||||||
|     len = base64_decode(p, adat.dat); |  | ||||||
|     if(len < 0){ |  | ||||||
| 	printf("Failed to decode base64 from server.\n"); |  | ||||||
| 	return AUTH_ERROR; |  | ||||||
|     } |  | ||||||
|     adat.length = len; |  | ||||||
|     ret = krb_rd_safe(adat.dat, adat.length, &d->key, |  | ||||||
| 		      (struct sockaddr_in *)hisctladdr, |  | ||||||
| 		      (struct sockaddr_in *)myctladdr, &msg_data); |  | ||||||
|     if(ret){ |  | ||||||
| 	printf("Error reading reply from server: %s.\n", |  | ||||||
| 	       krb_get_err_text(ret)); |  | ||||||
| 	return AUTH_ERROR; |  | ||||||
|     } |  | ||||||
|     krb_get_int(msg_data.app_data, &cs, 4, 0); |  | ||||||
|     if(cs - checksum != 1){ |  | ||||||
| 	printf("Bad checksum returned from server.\n"); |  | ||||||
| 	return AUTH_ERROR; |  | ||||||
|     } |  | ||||||
|     return AUTH_OK; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| struct sec_client_mech krb4_client_mech = { |  | ||||||
|     "KERBEROS_V4", |  | ||||||
|     sizeof(struct krb4_data), |  | ||||||
|     krb4_init, /* init */ |  | ||||||
|     krb4_auth, |  | ||||||
|     NULL, /* end */ |  | ||||||
|     krb4_check_prot, |  | ||||||
|     krb4_overhead, |  | ||||||
|     krb4_encode, |  | ||||||
|     krb4_decode |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif /* FTP_SERVER */ |  | ||||||
		Reference in New Issue
	
	Block a user
	 Love Hörnquist Åstrand
					Love Hörnquist Åstrand