10 #include <sys/types.h>
18 #include "sysdep_decls.h"
19 #include "citserver.h"
22 #include "dynloader.h"
40 #define SMTP ((struct citsmtp *)CtdlGetUserData(SYM_SMTP))
46 * Here's where our SMTP session begins its happy day.
48 void smtp_greeting(void) {
50 strcpy(CC->cs_clientname, "Citadel SMTP");
51 CtdlAllocUserData(SYM_SMTP, sizeof(struct citsmtp));
53 cprintf("220 Welcome to the Citadel/UX ESMTP server at %s\n",
59 * Implement HELO and EHLO commands.
61 void smtp_hello(char *argbuf, int is_esmtp) {
64 cprintf("250 Greetings and joyous salutations.\n");
67 cprintf("250-Greetings and joyous salutations.\n");
68 cprintf("250-HELP\n");
69 cprintf("250-SIZE %ld\n", config.c_maxmsglen);
70 cprintf("250 AUTH=LOGIN\n");
76 * Implement HELP command.
78 void smtp_help(void) {
79 cprintf("214-Here's the frequency, Kenneth:\n");
80 cprintf("214- EHLO\n");
81 cprintf("214- HELO\n");
82 cprintf("214- HELP\n");
83 cprintf("214- NOOP\n");
84 cprintf("214- QUIT\n");
85 cprintf("214 I'd tell you more, but then I'd have to kill you.\n");
92 void smtp_get_user(char *argbuf) {
96 decode_base64(username, argbuf);
97 lprintf(9, "Trying <%s>\n", username);
98 if (CtdlLoginExistingUser(username) == login_ok) {
99 encode_base64(buf, "Password:");
100 cprintf("334 %s\n", buf);
101 SMTP->command_state = smtp_password;
104 cprintf("500 No such user.\n");
105 SMTP->command_state = smtp_command;
113 void smtp_get_pass(char *argbuf) {
116 decode_base64(password, argbuf);
117 lprintf(9, "Trying <%s>\n", password);
118 if (CtdlTryPassword(password) == pass_ok) {
119 cprintf("235 Authentication successful.\n");
120 lprintf(9, "SMTP auth login successful\n");
123 cprintf("500 Authentication failed.\n");
125 SMTP->command_state = smtp_command;
132 void smtp_auth(char *argbuf) {
135 if (strncasecmp(argbuf, "login", 5) ) {
136 cprintf("500 We only support LOGIN authentication.\n");
140 if (strlen(argbuf) >= 7) {
141 smtp_get_user(&argbuf[6]);
145 encode_base64(buf, "Username:");
146 cprintf("334 %s\n", buf);
147 SMTP->command_state = smtp_user;
153 * Main command loop for SMTP sessions.
155 void smtp_command_loop(void) {
159 memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
160 if (client_gets(cmdbuf) < 1) {
161 lprintf(3, "SMTP socket is broken. Ending session.\n");
165 lprintf(5, "citserver[%3d]: %s\n", CC->cs_pid, cmdbuf);
166 while (strlen(cmdbuf) < 5) strcat(cmdbuf, " ");
168 if (SMTP->command_state == smtp_user) {
169 smtp_get_user(cmdbuf);
172 else if (SMTP->command_state == smtp_password) {
173 smtp_get_pass(cmdbuf);
176 else if (!strncasecmp(cmdbuf, "AUTH", 4)) {
177 smtp_auth(&cmdbuf[5]);
180 else if (!strncasecmp(cmdbuf, "EHLO", 4)) {
181 smtp_hello(&cmdbuf[5], 1);
184 else if (!strncasecmp(cmdbuf, "HELO", 4)) {
185 smtp_hello(&cmdbuf[5], 0);
188 else if (!strncasecmp(cmdbuf, "HELP", 4)) {
192 else if (!strncasecmp(cmdbuf, "NOOP", 4)) {
193 cprintf("250 This command successfully did nothing.\n");
196 else if (!strncasecmp(cmdbuf, "QUIT", 4)) {
197 cprintf("221 Goodbye...\n");
203 cprintf("500 I'm afraid I can't do that, Dave.\n");
210 char *Dynamic_Module_Init(void)
212 SYM_SMTP = CtdlGetDynamicSymbol();
213 CtdlRegisterServiceHook(25,