*** empty log message ***
[heimdal.git] / appl / ftp / ftpd / auth.c
blobefce62375a0bc15efa3c1446c09f7c7817b2ae5b
1 /*
2 * Copyright (c) 1995, 1996, 1997 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.
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.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 RCSID("$Id$");
42 #endif
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #ifdef HAVE_SYS_TYPES_H
48 #include <sys/types.h>
49 #endif
50 #ifdef HAVE_SYS_SOCKET_H
51 #include <sys/socket.h>
52 #endif
53 #if defined(HAVE_SYS_IOCTL_H) && SunOS != 4
54 #include <sys/ioctl.h>
55 #endif
56 #ifdef HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
60 #include "extern.h"
61 #include "krb4.h"
62 #include "auth.h"
64 static struct at auth_types [] = {
65 { "KERBEROS_V4", krb4_auth, krb4_adat, krb4_pbsz, krb4_prot, krb4_ccc,
66 krb4_mic, krb4_conf, krb4_enc, krb4_read, krb4_write, krb4_userok,
67 krb4_vprintf },
68 { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
71 struct at *ct;
73 int data_protection;
74 int buffer_size;
75 unsigned char *data_buffer;
76 int auth_complete;
79 char *protection_names[] = {
80 "clear", "safe",
81 "confidential", "private"
85 void auth_init(void)
89 char *ftp_command;
90 int prot_level;
92 void new_ftp_command(char *command)
94 ftp_command = command;
97 void delete_ftp_command(void)
99 if(ftp_command){
100 free(ftp_command);
101 ftp_command = NULL;
105 int auth_ok(void)
107 return ct && auth_complete;
110 void auth(char *auth)
112 for(ct=auth_types; ct->name; ct++){
113 if(!strcasecmp(auth, ct->name)){
114 ct->auth(auth);
115 return;
118 reply(504, "%s is not a known security mechanism", auth);
121 void adat(char *auth)
123 if(ct && !auth_complete)
124 ct->adat(auth);
125 else
126 reply(503, "You must (re)issue an AUTH first.");
129 void pbsz(int size)
131 int old = buffer_size;
132 if(auth_ok())
133 ct->pbsz(size);
134 else
135 reply(503, "Incomplete security data exchange.");
136 if(buffer_size != old){
137 if(data_buffer)
138 free(data_buffer);
139 data_buffer = malloc(buffer_size + 4);
143 void prot(char *pl)
145 int p = -1;
147 if(buffer_size == 0){
148 reply(503, "No protection buffer size negotiated.");
149 return;
152 if(!strcasecmp(pl, "C"))
153 p = prot_clear;
155 if(!strcasecmp(pl, "S"))
156 p = prot_safe;
158 if(!strcasecmp(pl, "E"))
159 p = prot_confidential;
161 if(!strcasecmp(pl, "P"))
162 p = prot_private;
164 if(p == -1){
165 reply(504, "Unrecognized protection level.");
166 return;
169 if(auth_ok()){
170 if(ct->prot(p)){
171 reply(536, "%s does not support %s protection.",
172 ct->name, protection_names[p]);
173 }else{
174 data_protection = p;
175 reply(200, "Data protection is %s.",
176 protection_names[data_protection]);
178 }else{
179 reply(503, "Incomplete security data exchange.");
183 void ccc(void)
185 if(auth_ok()){
186 if(!ct->ccc())
187 prot_level = prot_clear;
188 }else
189 reply(503, "Incomplete security data exchange.");
192 void mic(char *msg)
194 if(auth_ok()){
195 if(!ct->mic(msg))
196 prot_level = prot_safe;
197 }else
198 reply(503, "Incomplete security data exchange.");
201 void conf(char *msg)
203 if(auth_ok()){
204 if(!ct->conf(msg))
205 prot_level = prot_confidential;
206 }else
207 reply(503, "Incomplete security data exchange.");
210 void enc(char *msg)
212 if(auth_ok()){
213 if(!ct->enc(msg))
214 prot_level = prot_private;
215 }else
216 reply(503, "Incomplete security data exchange.");
219 int auth_read(int fd, void *data, int length)
221 if(auth_ok() && data_protection)
222 return ct->read(fd, data, length);
223 else
224 return read(fd, data, length);
227 int auth_write(int fd, void *data, int length)
229 if(auth_ok() && data_protection)
230 return ct->write(fd, data, length);
231 else
232 return write(fd, data, length);
235 void auth_vprintf(const char *fmt, va_list ap)
237 if(auth_ok() && prot_level){
238 ct->vprintf(fmt, ap);
239 }else
240 vprintf(fmt, ap);
243 void auth_printf(const char *fmt, ...)
245 va_list ap;
246 va_start(ap, fmt);
247 auth_vprintf(fmt, ap);
248 va_end(ap);