2 * Copyright (c) 1989 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
14 pop_net_read(POP
*p
, int fd
, void *buf
, size_t len
)
17 return krb5_net_read(p
->context
, &fd
, buf
, len
);
19 #error must define KRB5
24 static char *addr_log
;
27 pop_write_addr(POP
*p
, struct sockaddr
*addr
)
36 strftime(ts
, sizeof(ts
), "%Y%m%d%H%M%S", localtime(&t
));
37 if(inet_ntop (addr
->sa_family
, socket_get_address(addr
),
38 as
, sizeof(as
)) == NULL
) {
39 pop_log(p
, POP_PRIORITY
, "failed to print address");
43 f
= fopen(addr_log
, "a");
45 pop_log(p
, POP_PRIORITY
, "failed to open address log (%s)", addr_log
);
48 fprintf(f
, "%s %s\n", as
, ts
);
54 krb5_authenticate (POP
*p
, int s
, u_char
*buf
, struct sockaddr
*addr
)
57 krb5_auth_context auth_context
= NULL
;
62 if (memcmp (buf
, "\x00\x00\x00\x13", 4) != 0)
64 len
= (buf
[0] << 24) | (buf
[1] << 16) | (buf
[2] << 8) | (buf
[3]);
66 if (krb5_net_read(p
->context
, &s
, buf
, len
) != len
)
68 if (len
!= sizeof(KRB5_SENDAUTH_VERSION
)
69 || memcmp (buf
, KRB5_SENDAUTH_VERSION
, len
) != 0)
72 ret
= krb5_recvauth (p
->context
,
76 NULL
, /* let rd_req figure out what server to use */
77 KRB5_RECVAUTH_IGNORE_VERSION
,
81 pop_log(p
, POP_PRIORITY
, "krb5_recvauth: %s",
82 krb5_get_err_text(p
->context
, ret
));
87 ret
= krb5_unparse_name(p
->context
, ticket
->server
, &server
);
89 pop_log(p
, POP_PRIORITY
, "krb5_unparse_name: %s",
90 krb5_get_err_text(p
->context
, ret
));
94 /* does this make sense? */
95 if(strncmp(server
, "pop/", 4) != 0) {
96 pop_log(p
, POP_PRIORITY
,
97 "Got ticket for service `%s'", server
);
101 pop_log(p
, POP_DEBUG
,
102 "Accepted ticket for service `%s'", server
);
105 krb5_auth_con_free (p
->context
, auth_context
);
106 krb5_copy_principal (p
->context
, ticket
->client
, &p
->principal
);
107 krb5_free_ticket (p
->context
, ticket
);
114 krb_authenticate(POP
*p
, struct sockaddr
*addr
)
119 if (pop_net_read (p
, 0, buf
, 4) != 4) {
120 pop_msg(p
, POP_FAILURE
, "Reading four bytes: %s",
124 if (krb5_authenticate (p
, 0, buf
, addr
) == 0){
125 pop_write_addr(p
, addr
);
136 plain_authenticate (POP
*p
, struct sockaddr
*addr
)
141 static int kerberos_flag
;
142 static char *auth_str
;
143 static int debug_flag
;
144 static int interactive_flag
;
145 static char *port_str
;
146 static char *trace_file
;
148 static int help_flag
;
149 static int version_flag
;
151 static struct getargs args
[] = {
153 { "kerberos", 'k', arg_flag
, &kerberos_flag
, "use kerberos" },
155 { "auth-mode", 'a', arg_string
, &auth_str
, "required authentication",
164 { "debug", 'd', arg_flag
, &debug_flag
},
165 { "interactive", 'i', arg_flag
, &interactive_flag
, "create new socket" },
166 { "port", 'p', arg_string
, &port_str
, "port to listen to", "port" },
167 { "trace-file", 't', arg_string
, &trace_file
, "trace all command to file", "file" },
168 { "timeout", 'T', arg_integer
, &timeout
, "timeout", "seconds" },
169 { "address-log", 0, arg_string
, &addr_log
, "enable address log", "file" },
170 { "help", 'h', arg_flag
, &help_flag
},
171 { "version", 'v', arg_flag
, &version_flag
}
174 static int num_args
= sizeof(args
) / sizeof(args
[0]);
177 * init: Start a Post Office Protocol session
181 pop_getportbyname(POP
*p
, const char *service
,
182 const char *proto
, short def
)
185 return krb5_getportbyname(p
->context
, service
, proto
, def
);
187 return htons(default);
192 pop_init(POP
*p
,int argcount
,char **argmessage
)
194 struct sockaddr_storage cs_ss
;
195 struct sockaddr
*cs
= (struct sockaddr
*)&cs_ss
;
197 char * trace_file_name
= "/tmp/popper-trace";
202 /* Initialize the POP parameter block */
203 memset (p
, 0, sizeof(POP
));
205 setprogname(argmessage
[0]);
207 /* Save my name in a global variable */
208 p
->myname
= (char*)getprogname();
210 /* Get the name of our host */
211 gethostname(p
->myhost
,MaxHostNameLen
);
217 ret
= krb5_init_context (&p
->context
);
219 errx (1, "krb5_init_context failed: %d", ret
);
221 krb5_openlog(p
->context
, p
->myname
, &p
->logf
);
222 krb5_set_warn_dest(p
->context
, p
->logf
);
225 /* Open the log file */
226 roken_openlog(p
->myname
,POP_LOGOPTS
,POP_FACILITY
);
229 p
->auth_level
= AUTH_NONE
;
231 if(getarg(args
, num_args
, argcount
, argmessage
, &optind
)){
232 arg_printusage(args
, num_args
, NULL
, "");
236 arg_printusage(args
, num_args
, NULL
, "");
245 argmessage
+= optind
;
248 arg_printusage(args
, num_args
, NULL
, "");
253 if (strcasecmp (auth_str
, "plaintext") == 0 ||
254 strcasecmp (auth_str
, "none") == 0)
255 p
->auth_level
= AUTH_NONE
;
256 else if(strcasecmp(auth_str
, "otp") == 0) {
258 p
->auth_level
= AUTH_OTP
;
260 pop_log (p
, POP_PRIORITY
, "support for OTP not enabled");
263 } else if(strcasecmp(auth_str
, "sasl") == 0) {
265 p
->auth_level
= AUTH_SASL
;
267 pop_log (p
, POP_PRIORITY
, "support for SASL not enabled");
271 pop_log (p
, POP_PRIORITY
, "bad value for -a: %s", auth_str
);
275 /* Debugging requested */
276 p
->debug
= debug_flag
;
279 portnum
= htons(atoi(port_str
));
282 if ((p
->trace
= fopen(trace_file
, "a+")) == NULL
) {
283 pop_log(p
, POP_PRIORITY
,
284 "Unable to open trace file \"%s\", err = %d",
288 trace_file_name
= trace_file
;
292 p
->kerberosp
= kerberos_flag
;
296 pop_timeout
= timeout
;
299 if (interactive_flag
) {
301 portnum
= p
->kerberosp
?
302 pop_getportbyname(p
, "kpop", "tcp", 1109) :
303 pop_getportbyname(p
, "pop", "tcp", 110);
304 mini_inetd (portnum
);
307 /* Get the address and socket of the client to whom I am speaking */
309 if (getpeername(STDIN_FILENO
, cs
, &len
) < 0) {
310 pop_log(p
,POP_PRIORITY
,
311 "Unable to obtain socket and address of client, err = %d",errno
);
315 /* Save the dotted decimal form of the client's IP address
316 in the POP parameter block */
317 inet_ntop (cs
->sa_family
, socket_get_address (cs
),
318 p
->ipaddr
, sizeof(p
->ipaddr
));
320 /* Save the client's port */
321 p
->ipport
= ntohs(socket_get_port (cs
));
323 /* Get the canonical name of the host to whom I am speaking */
324 error
= getnameinfo_verified (cs
, len
, p
->client
, sizeof(p
->client
),
327 pop_log (p
, POP_PRIORITY
,
328 "getnameinfo: %s", gai_strerror (error
));
329 strlcpy (p
->client
, p
->ipaddr
, sizeof(p
->client
));
332 /* Create input file stream for TCP/IP communication */
333 if ((p
->input
= fdopen(STDIN_FILENO
,"r")) == NULL
){
334 pop_log(p
,POP_PRIORITY
,
335 "Unable to open communication stream for input, err = %d",errno
);
339 /* Create output file stream for TCP/IP communication */
340 if ((p
->output
= fdopen(STDOUT_FILENO
,"w")) == NULL
){
341 pop_log(p
,POP_PRIORITY
,
342 "Unable to open communication stream for output, err = %d",errno
);
346 pop_log(p
,POP_PRIORITY
,
347 "(v%s) Servicing request from \"%s\" at %s\n",
348 VERSION
,p
->client
,p
->ipaddr
);
352 pop_log(p
,POP_PRIORITY
,
353 "Tracing session and debugging information in file \"%s\"",
356 pop_log(p
,POP_PRIORITY
,"Debugging turned on");
361 return krb_authenticate(p
, cs
);
363 return plain_authenticate(p
, cs
);