1 /*
2  * AUTHORIZATION state handling.
3  */
4 
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <syslog.h>
9 
10 #include "misc.h"
11 #include "params.h"
12 #include "protocol.h"
13 #include "pop_auth.h"
14 #if POP_VIRTUAL
15 #include "virtual.h"
16 #endif
17 #include "pop_db.h"
18 
19 static char *pop_user, *pop_pass;
20 
pop_auth_quit(char * params)21 static int pop_auth_quit(char *params)
22 {
23 	if (params) return POP_ERROR;
24 	return POP_LEAVE;
25 }
26 
pop_auth_user(char * params)27 static int pop_auth_user(char *params)
28 {
29 	char *user;
30 
31 	user = pop_get_param(&params);
32 	if (!user || pop_user || params) return POP_ERROR;
33 	if (!(pop_user = strdup(user))) return POP_CRASH_SERVER;
34 	return POP_OK;
35 }
36 
pop_auth_pass(char * params)37 static int pop_auth_pass(char *params)
38 {
39 	if (!params || !pop_user) return POP_ERROR;
40 	if (!(pop_pass = strdup(params))) return POP_CRASH_SERVER;
41 	return POP_STATE;
42 }
43 
44 static struct pop_command pop_auth_commands[] = {
45 	{"QUIT", pop_auth_quit},
46 	{"USER", pop_auth_user},
47 	{"PASS", pop_auth_pass},
48 	{NULL, NULL}
49 };
50 
do_pop_auth(int channel)51 int do_pop_auth(int channel)
52 {
53 	pop_init();
54 
55 	if (pop_reply_ok()) return 1;
56 
57 	pop_user = NULL;
58 	if (pop_handle_state(pop_auth_commands) == POP_STATE) {
59 		pop_clean();
60 		write_loop(channel, (char *)&pop_buffer, sizeof(pop_buffer));
61 		write_loop(channel, pop_user, strlen(pop_user) + 1);
62 		write_loop(channel, pop_pass, strlen(pop_pass) + 1);
63 		if (close(channel)) return 1;
64 	}
65 
66 	return 0;
67 }
68 
log_pop_auth(int result,char * user)69 void log_pop_auth(int result, char *user)
70 {
71 	if (result == AUTH_NONE) {
72 		syslog(SYSLOG_PRI_LO, "Didn't attempt authentication");
73 		return;
74 	}
75 
76 #if POP_VIRTUAL
77 	if (virtual_domain) {
78 		syslog(result == AUTH_OK ? SYSLOG_PRI_LO : SYSLOG_PRI_HI,
79 			"Authentication %s for %s@%s from %s",
80 			result == AUTH_OK ? "passed" : "failed",
81 			user ? user : "UNKNOWN USER",
82 			virtual_domain,
83 			client_addr(1) );
84 		return;
85 	}
86 #endif
87 	syslog(result == AUTH_OK ? SYSLOG_PRI_LO : SYSLOG_PRI_HI,
88 		"Authentication %s for %s from %s",
89 		result == AUTH_OK ? "passed" : "failed",
90 		user ? user : "UNKNOWN USER",
91 		client_addr(1));
92 }
93