Actually add the files, not just the directory, to CVS
Showing
17 changed files
with
1628 additions
and
0 deletions
pop3d/Makefile.am
0 → 100644
1 | INCLUDES =-I$(srcdir) -I$(top_srcdir)/libsrc -I$(top_srcdir)/libmailbox | ||
2 | |||
3 | sbin_PROGRAMS = pop3d | ||
4 | |||
5 | pop3d_DEPENDENDENCIES = ../libmailbox/libmailbox.la ../libsrc/libgetopt.la\ | ||
6 | ../libsrc/libmd5.la | ||
7 | pop3d_SOURCES = apop.c auth.c capa.c dele.c extra.c pop3d.c pop3d.h\ | ||
8 | list.c noop.c quit.c retr.c rset.c stat.c top.c uidl.c user.c | ||
9 | pop3d_LDADD = ../libmailbox/libmailbox.la | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
pop3d/apop.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | #ifdef _USE_APOP | ||
21 | |||
22 | /* Check if a username exists in APOP password file | ||
23 | returns pinter to password if found, otherwise NULL */ | ||
24 | char * | ||
25 | pop3_apopuser (const char *user) | ||
26 | { | ||
27 | char *password; | ||
28 | char buf[POP_MAXCMDLEN]; | ||
29 | struct stat st; | ||
30 | #ifdef BDB2 | ||
31 | int errno; | ||
32 | DB *dbp; | ||
33 | DBT key, data; | ||
34 | |||
35 | if (stat (APOP_PASSFILE ".db", &st) != -1) | ||
36 | #else | ||
37 | char *tmp; | ||
38 | FILE *apop_file; | ||
39 | |||
40 | if (stat (APOP_PASSFILE ".passwd", &st) != -1) | ||
41 | #endif | ||
42 | if ((st.st_mode & 0777) != 0600) | ||
43 | { | ||
44 | syslog (LOG_INFO, "Bad permissions on APOP password file"); | ||
45 | return NULL; | ||
46 | } | ||
47 | |||
48 | #ifdef BDB2 | ||
49 | if ((errno = db_open (APOP_PASSFILE ".db", DB_HASH, DB_RDONLY, 0600, | ||
50 | NULL, NULL, &dbp)) != 0) | ||
51 | { | ||
52 | syslog (LOG_ERR, "Unable to open APOP database: %s", strerror (errno)); | ||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | memset (&key, 0, sizeof (DBT)); | ||
57 | memset (&data, 0, sizeof (DBT)); | ||
58 | |||
59 | strncpy (buf, user, sizeof (buf)); | ||
60 | key.data = buf; | ||
61 | key.size = strlen (user); | ||
62 | if ((errno = dbp->get (dbp, NULL, &key, &data, 0)) != 0) | ||
63 | { | ||
64 | syslog (LOG_ERR, "db_get error: %s", strerror (errno)); | ||
65 | dbp->close (dbp, 0); | ||
66 | return NULL; | ||
67 | } | ||
68 | |||
69 | if ((password = malloc (sizeof (char) * data.size)) == NULL) | ||
70 | { | ||
71 | dbp->close (dbp, 0); | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | sprintf (password, "%.*s", (int) data.size, (char *) data.data); | ||
76 | dbp->close (dbp, 0); | ||
77 | return password; | ||
78 | #else /* !BDBD2 */ | ||
79 | if ((apop_file = fopen (APOP_PASSFILE ".passwd", "r")) == NULL) | ||
80 | { | ||
81 | syslog (LOG_INFO, "Unable to open APOP password file"); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | if ((password = malloc (sizeof (char) * APOP_DIGEST)) == NULL) | ||
86 | { | ||
87 | fclose (apop_file); | ||
88 | pop3_abquit (ERR_NO_MEM); | ||
89 | } | ||
90 | password[0] = '\0'; | ||
91 | |||
92 | while (fgets (buf, sizeof (buf) - 1, apop_file) != NULL) | ||
93 | { | ||
94 | tmp = index (buf, ':'); | ||
95 | *tmp = '\0'; | ||
96 | tmp++; | ||
97 | |||
98 | if (strncmp (user, buf, strlen (user))) | ||
99 | continue; | ||
100 | |||
101 | strncpy (password, tmp, strlen (tmp)); | ||
102 | tmp = index (password, '\n'); | ||
103 | *tmp = '\0'; | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | fclose (apop_file); | ||
108 | if (strlen (password) == 0) | ||
109 | { | ||
110 | free (password); | ||
111 | return NULL; | ||
112 | } | ||
113 | |||
114 | return password; | ||
115 | #endif /* BDB2 */ | ||
116 | } | ||
117 | |||
118 | int | ||
119 | pop3_apop (const char *arg) | ||
120 | { | ||
121 | char *tmp, *user_digest, *password; | ||
122 | struct passwd *pw; | ||
123 | char buf[POP_MAXCMDLEN]; | ||
124 | struct md5_ctx md5context; | ||
125 | unsigned char md5digest[16]; | ||
126 | int i; | ||
127 | |||
128 | if (state != AUTHORIZATION) | ||
129 | return ERR_WRONG_STATE; | ||
130 | if (strlen (arg) == 0) | ||
131 | return ERR_BAD_ARGS; | ||
132 | |||
133 | tmp = pop3_cmd (arg); | ||
134 | if (strlen (tmp) > (POP_MAXCMDLEN - APOP_DIGEST)) | ||
135 | return ERR_BAD_ARGS; | ||
136 | if ((username = strdup (tmp)) == NULL) | ||
137 | pop3_abquit (ERR_NO_MEM); | ||
138 | free (tmp); | ||
139 | |||
140 | tmp = pop3_args (arg); | ||
141 | if (strlen (tmp) > APOP_DIGEST) | ||
142 | return ERR_BAD_ARGS; | ||
143 | if ((user_digest = strdup (tmp)) == NULL) | ||
144 | pop3_abquit (ERR_NO_MEM); | ||
145 | free (tmp); | ||
146 | |||
147 | if ((password = pop3_apopuser (username)) == NULL) | ||
148 | return ERR_BAD_LOGIN; | ||
149 | |||
150 | md5_init_ctx (&md5context); | ||
151 | md5_process_bytes (md5shared, strlen (md5shared), &md5context); | ||
152 | md5_process_bytes (password, strlen (password), &md5context); | ||
153 | /* pop3_wipestr (password); */ | ||
154 | free (password); | ||
155 | md5_finish_ctx (&md5context, md5digest); | ||
156 | |||
157 | tmp = buf; | ||
158 | for (i = 0; i < 16; i++, tmp += 2) | ||
159 | sprintf (tmp, "%02x", md5digest[i]); | ||
160 | |||
161 | *tmp++ = '\0'; | ||
162 | |||
163 | if (strcmp (user_digest, buf)) | ||
164 | return ERR_BAD_LOGIN; | ||
165 | |||
166 | if ((pw = getpwnam (username)) == NULL) | ||
167 | return ERR_BAD_LOGIN; | ||
168 | |||
169 | #ifdef MAILSPOOLHOME | ||
170 | mailbox = malloc ((strlen (pw->pw_dir) + strlen (MAILSPOOLHOME) + 1) * sizeof (char)); | ||
171 | if (mailbox == NULL) | ||
172 | pop3_abquit (ERR_NO_MEM); | ||
173 | strcpy (mailbox, pw->pw_dir); | ||
174 | strcat (mailbox, MAILSPOOLHOME); | ||
175 | mbox = fopen (mailbox, "r"); | ||
176 | if (mbox == NULL) | ||
177 | { | ||
178 | free (mailbox); | ||
179 | chdir (_PATH_MAILDIR); | ||
180 | #endif | ||
181 | mailbox = malloc (sizeof (char) * (strlen (_PATH_MAILDIR) + strlen (username) + 2)); | ||
182 | strcpy (mailbox, _PATH_MAILDIR "/"); | ||
183 | strcat (mailbox, username); | ||
184 | if (mailbox == NULL) | ||
185 | pop3_abquit (ERR_NO_MEM); | ||
186 | |||
187 | mbox = fopen (mailbox, "r"); | ||
188 | if (mbox == NULL) | ||
189 | { | ||
190 | mailbox = strdup ("/dev/null"); | ||
191 | if (mailbox == NULL) | ||
192 | pop3_abquit (ERR_NO_MEM); | ||
193 | mbox = fopen (mailbox, "r"); | ||
194 | } | ||
195 | #ifdef MAILSPOOLHOME | ||
196 | } | ||
197 | else | ||
198 | #endif | ||
199 | if (pop3_lock () != OK) | ||
200 | { | ||
201 | pop3_unlock (); | ||
202 | free (mailbox); | ||
203 | state = AUTHORIZATION; | ||
204 | return ERR_MBOX_LOCK; | ||
205 | } | ||
206 | |||
207 | if ((pw->pw_uid < 1) | ||
208 | #ifdef MAILSPOOLHOME | ||
209 | /* Drop mail group for home dirs */ | ||
210 | || setgid (pw->pw_gid) == -1 | ||
211 | #endif | ||
212 | || setuid (pw->pw_uid) == -1) | ||
213 | { | ||
214 | pop3_unlock (); | ||
215 | free (mailbox); | ||
216 | return ERR_BAD_LOGIN; | ||
217 | } | ||
218 | |||
219 | state = TRANSACTION; | ||
220 | messages = NULL; | ||
221 | pop3_getsizes (); | ||
222 | fprintf (ofile, "+OK opened mailbox for %s\r\n", username); | ||
223 | syslog (LOG_INFO, "User %s logged in with mailbox %s", username, mailbox); | ||
224 | cursor = 0; | ||
225 | return OK; | ||
226 | } | ||
227 | |||
228 | #else | ||
229 | |||
230 | int | ||
231 | pop3_apop (const char *foo) | ||
232 | { | ||
233 | return ERR_NOT_IMPL; | ||
234 | } | ||
235 | |||
236 | #endif |
pop3d/auth.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* AUTH is not yet implemented */ | ||
21 | |||
22 | int | ||
23 | pop3_auth (const char *arg) | ||
24 | { | ||
25 | if (state != AUTHORIZATION) | ||
26 | return ERR_WRONG_STATE; | ||
27 | return ERR_NOT_IMPL; | ||
28 | } |
pop3d/capa.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | |||
3 | * Code for capa support by Sean 'Shaleh' Perry <shaleh@debian.org> | ||
4 | * added 4/2/1999 | ||
5 | * | ||
6 | */ | ||
7 | #include "pop3d.h" | ||
8 | |||
9 | int | ||
10 | pop3_capa (const char *arg) | ||
11 | { | ||
12 | if (strlen (arg) != 0) | ||
13 | return ERR_BAD_ARGS; | ||
14 | |||
15 | if (state != AUTHORIZATION && state != TRANSACTION) | ||
16 | return ERR_WRONG_STATE; | ||
17 | |||
18 | fprintf (ofile, "+OK Capability list follows\r\n"); | ||
19 | fprintf (ofile, "TOP\r\n"); | ||
20 | fprintf (ofile, "USER\r\n"); | ||
21 | fprintf (ofile, "RESP-CODES\r\n"); | ||
22 | if (state == TRANSACTION) /* let's not advertise to just anyone */ | ||
23 | fprintf (ofile, "IMPLEMENTATION %s %s\r\n", IMPL, VERSION); | ||
24 | fprintf (ofile, ".\r\n"); | ||
25 | return OK; | ||
26 | } |
pop3d/dele.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* DELE adds a message number to the list of messages to be deleted on QUIT */ | ||
21 | |||
22 | int | ||
23 | pop3_dele (const char *arg) | ||
24 | { | ||
25 | int num = 0; | ||
26 | |||
27 | if ((arg == NULL) || (strchr (arg, ' ') != NULL)) | ||
28 | return ERR_BAD_ARGS; | ||
29 | |||
30 | if (state != TRANSACTION) | ||
31 | return ERR_WRONG_STATE; | ||
32 | |||
33 | num = atoi (arg) - 1; | ||
34 | if (mbox_delete(mbox, num) != 0) | ||
35 | return ERR_NO_MESG; | ||
36 | |||
37 | fprintf (ofile, "+OK Message %d marked\r\n", num + 1); | ||
38 | return OK; | ||
39 | } |
pop3d/extra.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Takes a string as input and returns either the remainder of the string | ||
21 | after the first space, or a zero length string if no space */ | ||
22 | |||
23 | char * | ||
24 | pop3_args (const char *cmd) | ||
25 | { | ||
26 | int space = -1, i = 0, len; | ||
27 | char *buf; | ||
28 | |||
29 | len = strlen (cmd) + 1; | ||
30 | buf = malloc (len * sizeof (char)); | ||
31 | if (buf == NULL) | ||
32 | pop3_abquit (ERR_NO_MEM); | ||
33 | |||
34 | while (space < 0 && i < len) | ||
35 | { | ||
36 | if (cmd[i] == ' ') | ||
37 | space = i + 1; | ||
38 | else if (cmd[i] == '\0' || cmd[i] == '\r' || cmd[i] == '\n') | ||
39 | len = i; | ||
40 | i++; | ||
41 | } | ||
42 | |||
43 | if (space < 0) | ||
44 | buf[0] = '\0'; | ||
45 | else | ||
46 | { | ||
47 | for (i = space; i < len; i++) | ||
48 | if (cmd[i] == '\0' || cmd[i] == '\r' || cmd[i] == '\n') | ||
49 | buf[i - space] = '\0'; | ||
50 | else | ||
51 | buf[i - space] = cmd[i]; | ||
52 | } | ||
53 | |||
54 | return buf; | ||
55 | } | ||
56 | |||
57 | /* This takes a string and returns the string up to the first space or end of | ||
58 | the string, whichever occurs first */ | ||
59 | |||
60 | char * | ||
61 | pop3_cmd (const char *cmd) | ||
62 | { | ||
63 | char *buf; | ||
64 | int i = 0, len; | ||
65 | |||
66 | len = strlen (cmd) + 1; | ||
67 | buf = malloc (len * sizeof (char)); | ||
68 | if (buf == NULL) | ||
69 | pop3_abquit (ERR_NO_MEM); | ||
70 | |||
71 | for (i = 0; i < len; i++) | ||
72 | { | ||
73 | if (cmd[i] == ' ' || cmd[i] == '\0' || cmd[i] == '\r' || cmd[i] == '\n') | ||
74 | len = i; | ||
75 | else | ||
76 | buf[i] = cmd[i]; | ||
77 | } | ||
78 | buf[i - 1] = '\0'; | ||
79 | return buf; | ||
80 | } | ||
81 | |||
82 | /* This is called if GNU POP needs to quit without going to the UPDATE stage. | ||
83 | This is used for conditions such as out of memory, a broken socket, or | ||
84 | being killed on a signal */ | ||
85 | |||
86 | int | ||
87 | pop3_abquit (int reason) | ||
88 | { | ||
89 | mbox_close(mbox); | ||
90 | |||
91 | switch (reason) | ||
92 | { | ||
93 | case ERR_NO_MEM: | ||
94 | fprintf (ofile, "-ERR Out of memory, quitting\r\n"); | ||
95 | syslog (LOG_ERR, "Out of memory"); | ||
96 | break; | ||
97 | case ERR_DEAD_SOCK: | ||
98 | fprintf (ofile, "-ERR Socket closed, quitting\r\n"); | ||
99 | syslog (LOG_ERR, "Socket closed"); | ||
100 | break; | ||
101 | case ERR_SIGNAL: | ||
102 | fprintf (ofile, "-ERR Quitting on signal\r\n"); | ||
103 | syslog (LOG_ERR, "Quitting on signal"); | ||
104 | break; | ||
105 | case ERR_TIMEOUT: | ||
106 | fprintf (ofile, "-ERR Session timed out\r\n"); | ||
107 | if (state == TRANSACTION) | ||
108 | syslog (LOG_INFO, "Session timed out for user: %s", username); | ||
109 | else | ||
110 | syslog (LOG_INFO, "Session timed out for no user"); | ||
111 | break; | ||
112 | default: | ||
113 | fprintf (ofile, "-ERR Quitting (reason unknown)\r\n"); | ||
114 | syslog (LOG_ERR, "Unknown quit"); | ||
115 | break; | ||
116 | } | ||
117 | fflush (ofile); | ||
118 | exit (1); | ||
119 | } | ||
120 | |||
121 | /* Prints out usage information and exits the program */ | ||
122 | |||
123 | void | ||
124 | pop3_usage (char *argv0) | ||
125 | { | ||
126 | printf ("Usage: %s [OPTIONS]\n", argv0); | ||
127 | printf ("Runs the GNU POP3 daemon.\n\n"); | ||
128 | printf (" -d, --daemon=MAXCHILDREN runs in daemon mode with a maximum\n"); | ||
129 | printf (" of MAXCHILDREN child processes\n"); | ||
130 | printf (" -h, --help display this help and exit\n"); | ||
131 | printf (" -i, --inetd runs in inetd mode (default)\n"); | ||
132 | printf (" -p, --port=PORT specifies port to listen on, implies -d\n"); | ||
133 | printf (" defaults to 110, which need not be specified\n"); | ||
134 | printf (" -t, --timeout=TIMEOUT sets idle timeout to TIMEOUT seconds\n"); | ||
135 | printf (" TIMEOUT must be at least 600 (10 minutes) or\n"); | ||
136 | printf (" it will be disabled\n"); | ||
137 | printf (" -v, --version display version information and exit\n"); | ||
138 | printf ("\nReport bugs to gnu-pop-list@nodomainname.net\n"); | ||
139 | exit (0); | ||
140 | } | ||
141 | |||
142 | /* Default signal handler to call the pop3_abquit() function */ | ||
143 | |||
144 | void | ||
145 | pop3_signal (int signal) | ||
146 | { | ||
147 | if (signal == SIGCHLD) | ||
148 | { | ||
149 | int stat; | ||
150 | while (waitpid (-1, &stat, WNOHANG) > 0); | ||
151 | return; | ||
152 | } | ||
153 | else | ||
154 | pop3_abquit (ERR_SIGNAL); | ||
155 | } | ||
156 | |||
157 | /* Gets a line of input from the client */ | ||
158 | |||
159 | char * | ||
160 | pop3_readline (int fd) | ||
161 | { | ||
162 | fd_set rfds; | ||
163 | struct timeval tv; | ||
164 | char buf[1024], *ret = NULL; | ||
165 | int available; | ||
166 | |||
167 | FD_ZERO (&rfds); | ||
168 | FD_SET (fd, &rfds); | ||
169 | tv.tv_sec = timeout; | ||
170 | tv.tv_usec = 0; | ||
171 | memset (buf, '\0', 1024); | ||
172 | |||
173 | while (strchr (buf, '\n') == NULL) | ||
174 | { | ||
175 | if (timeout > 0) | ||
176 | { | ||
177 | available = select (fd + 1, &rfds, NULL, NULL, &tv); | ||
178 | if (!available) | ||
179 | pop3_abquit (ERR_TIMEOUT); | ||
180 | } | ||
181 | |||
182 | if (read (fd, buf, 1024) < 1) | ||
183 | pop3_abquit (ERR_DEAD_SOCK); | ||
184 | |||
185 | if (ret == NULL) | ||
186 | { | ||
187 | ret = malloc ((strlen (buf) + 1) * sizeof (char)); | ||
188 | strcpy (ret, buf); | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | ret = realloc (ret, (strlen (ret) + strlen (buf) + 1) * sizeof (char)); | ||
193 | strcat (ret, buf); | ||
194 | } | ||
195 | } | ||
196 | return ret; | ||
197 | } |
pop3d/list.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Displays the size of message number arg or all messages (if no arg) */ | ||
21 | |||
22 | int | ||
23 | pop3_list (const char *arg) | ||
24 | { | ||
25 | int mesg = 0; | ||
26 | |||
27 | if (state != TRANSACTION) | ||
28 | return ERR_WRONG_STATE; | ||
29 | |||
30 | if (strchr (arg, ' ') != NULL) | ||
31 | return ERR_BAD_ARGS; | ||
32 | |||
33 | if (strlen (arg) == 0) | ||
34 | { | ||
35 | fprintf (ofile, "+OK\r\n"); | ||
36 | for (mesg = 0; mesg < mbox->messages ; mesg++) | ||
37 | if (!mbox_is_deleted(mbox, mesg)) | ||
38 | fprintf (ofile, "%d %d\r\n", mesg + 1, mbox->sizes[mesg]); | ||
39 | fprintf (ofile, ".\r\n"); | ||
40 | } | ||
41 | else | ||
42 | { | ||
43 | mesg = atoi (arg) - 1; | ||
44 | if (mesg > mbox->messages || mbox_is_deleted(mbox, mesg)) | ||
45 | return ERR_NO_MESG; | ||
46 | fprintf (ofile, "+OK %d %d\r\n", mesg + 1, mbox->sizes[mesg]); | ||
47 | } | ||
48 | |||
49 | return OK; | ||
50 | } |
pop3d/noop.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Does nothing */ | ||
21 | |||
22 | int | ||
23 | pop3_noop (const char *arg) | ||
24 | { | ||
25 | if (strlen (arg) != 0) | ||
26 | return ERR_BAD_ARGS; | ||
27 | if (state != TRANSACTION) | ||
28 | return ERR_WRONG_STATE; | ||
29 | fprintf (ofile, "+OK\r\n"); | ||
30 | return OK; | ||
31 | } |
pop3d/pop3d.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | static struct option long_options[] = | ||
21 | { | ||
22 | {"daemon", 2, 0, 'd'}, | ||
23 | {"help", 0, 0, 'h'}, | ||
24 | {"inetd", 0, 0, 'i'}, | ||
25 | {"port", 1, 0, 'p'}, | ||
26 | {"timeout", 1, 0, 't'}, | ||
27 | {"version", 0, 0, 'v'}, | ||
28 | {0, 0, 0, 0} | ||
29 | }; | ||
30 | |||
31 | int | ||
32 | main (int argc, char **argv) | ||
33 | { | ||
34 | struct group *gr; | ||
35 | static int mode; | ||
36 | int maxchildren = 10; | ||
37 | int option_index = 0; | ||
38 | int c = 0; | ||
39 | |||
40 | port = 110; /* Default POP3 port */ | ||
41 | timeout = 0; /* Default timeout of 0 */ | ||
42 | |||
43 | while ((c = getopt_long (argc, argv, "d::hip:t:v", long_options, &option_index)) && c != -1) | ||
44 | { | ||
45 | switch (c) | ||
46 | { | ||
47 | case 'd': | ||
48 | mode = DAEMON; | ||
49 | maxchildren = optarg ? atoi (optarg) : 10; | ||
50 | break; | ||
51 | case 'h': | ||
52 | pop3_usage (argv[0]); | ||
53 | break; | ||
54 | case 'i': | ||
55 | mode = INTERACTIVE; | ||
56 | break; | ||
57 | case 'p': | ||
58 | mode = DAEMON; | ||
59 | port = atoi (optarg); | ||
60 | break; | ||
61 | case 't': | ||
62 | timeout = atoi (optarg); | ||
63 | break; | ||
64 | case 'v': | ||
65 | printf (IMPL " ("PACKAGE " " VERSION ")\n"); | ||
66 | exit (0); | ||
67 | break; | ||
68 | default: | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | /* First we want our group to be mail so we can access the spool */ | ||
74 | gr = getgrnam ("mail"); | ||
75 | if (gr == NULL) | ||
76 | { | ||
77 | perror ("Error getting group"); | ||
78 | exit (1); | ||
79 | } | ||
80 | |||
81 | if (setgid (gr->gr_gid) == -1) | ||
82 | { | ||
83 | perror ("Error setting group"); | ||
84 | exit (1); | ||
85 | } | ||
86 | |||
87 | /* Set the signal handlers */ | ||
88 | signal (SIGINT, pop3_signal); | ||
89 | signal (SIGQUIT, pop3_signal); | ||
90 | signal (SIGILL, pop3_signal); | ||
91 | signal (SIGBUS, pop3_signal); | ||
92 | signal (SIGFPE, pop3_signal); | ||
93 | signal (SIGSEGV, pop3_signal); | ||
94 | signal (SIGTERM, pop3_signal); | ||
95 | signal (SIGSTOP, pop3_signal); | ||
96 | |||
97 | if (timeout < 600) /* RFC 1939 says no less than 10 minutes */ | ||
98 | timeout = 0; /* So we'll turn it off */ | ||
99 | |||
100 | if (mode == DAEMON) | ||
101 | pop3_daemon_init (); | ||
102 | |||
103 | /* change directories */ | ||
104 | #ifdef MAILSPOOLHOME | ||
105 | chdir ("/"); | ||
106 | #else | ||
107 | chdir (_PATH_MAILDIR); | ||
108 | #endif | ||
109 | |||
110 | /* Set up for syslog */ | ||
111 | openlog ("gnu-pop3d", LOG_PID, LOG_MAIL); | ||
112 | |||
113 | umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */ | ||
114 | |||
115 | /* Actually run the daemon */ | ||
116 | switch (mode) | ||
117 | { | ||
118 | case DAEMON: | ||
119 | if (maxchildren < 10) | ||
120 | maxchildren = 10; | ||
121 | pop3_daemon (maxchildren); | ||
122 | break; | ||
123 | case INTERACTIVE: | ||
124 | default: | ||
125 | pop3_mainloop (fileno (stdin), fileno (stdout)); | ||
126 | break; | ||
127 | } | ||
128 | |||
129 | /* Close the syslog connection and exit */ | ||
130 | closelog (); | ||
131 | return OK; | ||
132 | } | ||
133 | |||
134 | /* Sets things up for daemon mode */ | ||
135 | |||
136 | void | ||
137 | pop3_daemon_init (void) | ||
138 | { | ||
139 | if (fork ()) | ||
140 | exit (0); /* parent exits */ | ||
141 | setsid (); /* become session leader */ | ||
142 | |||
143 | if (fork ()) | ||
144 | exit (0); /* new parent exits */ | ||
145 | |||
146 | /* close inherited file descriptors */ | ||
147 | close (0); | ||
148 | close (1); | ||
149 | close (2); | ||
150 | |||
151 | signal (SIGHUP, SIG_IGN); /* ignore SIGHUP */ | ||
152 | signal (SIGCHLD, pop3_signal); /* for forking */ | ||
153 | } | ||
154 | |||
155 | /* The main part of the daemon. This function reads input from the client and | ||
156 | executes the proper functions. Also handles the bulk of error reporting. */ | ||
157 | |||
158 | int | ||
159 | pop3_mainloop (int infile, int outfile) | ||
160 | { | ||
161 | int status = OK; | ||
162 | char *buf, *arg, *cmd; | ||
163 | struct hostent *htbuf; | ||
164 | char *local_hostname; | ||
165 | |||
166 | ifile = infile; | ||
167 | ofile = fdopen (outfile, "w+"); | ||
168 | if (ofile == NULL) | ||
169 | pop3_abquit (ERR_NO_OFILE); | ||
170 | state = AUTHORIZATION; | ||
171 | curr_time = time (NULL); | ||
172 | |||
173 | syslog (LOG_INFO, "Incoming connection opened"); | ||
174 | |||
175 | /* Prepare the shared secret for APOP */ | ||
176 | local_hostname = malloc (MAXHOSTNAMELEN + 1); | ||
177 | if (local_hostname == NULL) | ||
178 | pop3_abquit (ERR_NO_MEM); | ||
179 | |||
180 | gethostname (local_hostname, MAXHOSTNAMELEN); | ||
181 | htbuf = gethostbyname (local_hostname); | ||
182 | if (htbuf) | ||
183 | { | ||
184 | free (local_hostname); | ||
185 | local_hostname = strdup (htbuf->h_name); | ||
186 | } | ||
187 | |||
188 | md5shared = malloc (strlen (local_hostname) + 51); | ||
189 | if (md5shared == NULL) | ||
190 | pop3_abquit (ERR_NO_MEM); | ||
191 | |||
192 | snprintf (md5shared, strlen (local_hostname) + 50, "<%d.%ld@%s>", getpid (), | ||
193 | time (NULL), local_hostname); | ||
194 | free (local_hostname); | ||
195 | |||
196 | fflush (ofile); | ||
197 | fprintf (ofile, "+OK POP3 " WELCOME " %s\r\n", md5shared); | ||
198 | |||
199 | while (state != UPDATE) | ||
200 | { | ||
201 | fflush (ofile); | ||
202 | status = OK; | ||
203 | buf = pop3_readline (ifile); | ||
204 | cmd = pop3_cmd (buf); | ||
205 | arg = pop3_args (buf); | ||
206 | |||
207 | if (strlen (arg) > POP_MAXCMDLEN || strlen (cmd) > POP_MAXCMDLEN) | ||
208 | status = ERR_TOO_LONG; | ||
209 | else if (strlen (cmd) > 4) | ||
210 | status = ERR_BAD_CMD; | ||
211 | else if (strncasecmp (cmd, "USER", 4) == 0) | ||
212 | status = pop3_user (arg); | ||
213 | else if (strncasecmp (cmd, "QUIT", 4) == 0) | ||
214 | status = pop3_quit (arg); | ||
215 | else if (strncasecmp (cmd, "APOP", 4) == 0) | ||
216 | status = pop3_apop (arg); | ||
217 | else if (strncasecmp (cmd, "AUTH", 4) == 0) | ||
218 | status = pop3_auth (arg); | ||
219 | else if (strncasecmp (cmd, "STAT", 4) == 0) | ||
220 | status = pop3_stat (arg); | ||
221 | else if (strncasecmp (cmd, "LIST", 4) == 0) | ||
222 | status = pop3_list (arg); | ||
223 | else if (strncasecmp (cmd, "RETR", 4) == 0) | ||
224 | status = pop3_retr (arg); | ||
225 | else if (strncasecmp (cmd, "DELE", 4) == 0) | ||
226 | status = pop3_dele (arg); | ||
227 | else if (strncasecmp (cmd, "NOOP", 4) == 0) | ||
228 | status = pop3_noop (arg); | ||
229 | else if (strncasecmp (cmd, "RSET", 4) == 0) | ||
230 | status = pop3_rset (arg); | ||
231 | else if ((strncasecmp (cmd, "TOP", 3) == 0) && (strlen (cmd) == 3)) | ||
232 | status = pop3_top (arg); | ||
233 | else if (strncasecmp (cmd, "UIDL", 4) == 0) | ||
234 | status = pop3_uidl (arg); | ||
235 | else if (strncasecmp (cmd, "CAPA", 4) == 0) | ||
236 | status = pop3_capa (arg); | ||
237 | else | ||
238 | status = ERR_BAD_CMD; | ||
239 | |||
240 | if (status == OK) | ||
241 | fflush (ofile); | ||
242 | else if (status == ERR_WRONG_STATE) | ||
243 | fprintf (ofile, "-ERR " BAD_STATE "\r\n"); | ||
244 | else if (status == ERR_BAD_ARGS) | ||
245 | fprintf (ofile, "-ERR " BAD_ARGS "\r\n"); | ||
246 | else if (status == ERR_NO_MESG) | ||
247 | fprintf (ofile, "-ERR " NO_MESG "\r\n"); | ||
248 | else if (status == ERR_NOT_IMPL) | ||
249 | fprintf (ofile, "-ERR " NOT_IMPL "\r\n"); | ||
250 | else if (status == ERR_BAD_CMD) | ||
251 | fprintf (ofile, "-ERR " BAD_COMMAND "\r\n"); | ||
252 | else if (status == ERR_BAD_LOGIN) | ||
253 | fprintf (ofile, "-ERR " BAD_LOGIN "\r\n"); | ||
254 | else if (status == ERR_MBOX_LOCK) | ||
255 | fprintf (ofile, "-ERR [IN-USE] " MBOX_LOCK "\r\n"); | ||
256 | else if (status == ERR_TOO_LONG) | ||
257 | fprintf (ofile, "-ERR " TOO_LONG "\r\n"); | ||
258 | |||
259 | free (buf); | ||
260 | free (cmd); | ||
261 | free (arg); | ||
262 | } | ||
263 | |||
264 | fflush (ofile); | ||
265 | return OK; | ||
266 | } | ||
267 | |||
268 | /* Runs GNU POP in standalone daemon mode. This opens and binds to a port | ||
269 | (default 110) then executes a pop3_mainloop() upon accepting a connection. | ||
270 | It starts maxchildren child processes to listen to and accept socket | ||
271 | connections */ | ||
272 | |||
273 | int | ||
274 | pop3_daemon (int maxchildren) | ||
275 | { | ||
276 | int children = 0; | ||
277 | struct sockaddr_in client; | ||
278 | int sock, sock2; | ||
279 | unsigned int socksize; | ||
280 | |||
281 | sock = socket (PF_INET, SOCK_STREAM, (getprotobyname ("tcp"))->p_proto); | ||
282 | if (sock < 0) | ||
283 | { | ||
284 | syslog (LOG_ERR, "%s\n", strerror (errno)); | ||
285 | exit (1); | ||
286 | } | ||
287 | memset (&client, 0, sizeof (struct sockaddr_in)); | ||
288 | client.sin_family = AF_INET; | ||
289 | client.sin_port = htons (port); | ||
290 | client.sin_addr.s_addr = htonl (INADDR_ANY); | ||
291 | socksize = sizeof (client); | ||
292 | if (bind (sock, (struct sockaddr *) &client, socksize)) | ||
293 | { | ||
294 | perror ("Couldn't bind to socket"); | ||
295 | exit (1); | ||
296 | } | ||
297 | listen (sock, 128); | ||
298 | while (1) | ||
299 | { | ||
300 | if (children < maxchildren) | ||
301 | { | ||
302 | if (!fork ()) | ||
303 | { | ||
304 | sock2 = accept (sock, &client, &socksize); | ||
305 | pop3_mainloop (sock2, sock2); | ||
306 | close (sock2); | ||
307 | exit (OK); | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | /* wait (NULL); */ | ||
312 | children++; | ||
313 | } | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | wait (NULL); | ||
318 | children--; | ||
319 | } | ||
320 | } | ||
321 | return OK; | ||
322 | } |
pop3d/pop3d.h
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #ifndef _POP3D_H | ||
19 | #define _POP3D_H 1 | ||
20 | #include "config.h" | ||
21 | |||
22 | /* The implementation */ | ||
23 | #define IMPL "GNU POP3 Daemon" | ||
24 | |||
25 | /* You can edit the messages the POP server prints out here */ | ||
26 | |||
27 | /* Initial greeting */ | ||
28 | #define WELCOME "Welcome to " IMPL " (" PACKAGE " " VERSION ")" | ||
29 | |||
30 | /* A command that doesn't exist */ | ||
31 | #define BAD_COMMAND "Invalid command" | ||
32 | |||
33 | /* Incorrect number of arguments passed to a command */ | ||
34 | #define BAD_ARGS "Invalid arguments" | ||
35 | |||
36 | /* Command issued in wrong state */ | ||
37 | #define BAD_STATE "Incorrect state" | ||
38 | |||
39 | /* An action on a message that doesn't exist */ | ||
40 | #define NO_MESG "No such message" | ||
41 | |||
42 | /* A command that is known but not implemented */ | ||
43 | #define NOT_IMPL "Not implemented" | ||
44 | |||
45 | /* Invalid username or password */ | ||
46 | #define BAD_LOGIN "Bad login" | ||
47 | |||
48 | /* User authenticated, but mailbox is locked */ | ||
49 | #define MBOX_LOCK "Mailbox in use" | ||
50 | |||
51 | /* The command argument was > 40 characters */ | ||
52 | #define TOO_LONG "Argument too long" | ||
53 | |||
54 | /* APOP password file, without .db or .passwd, which are added based on file | ||
55 | type automatically */ | ||
56 | #define APOP_PASSFILE "/etc/apop" | ||
57 | |||
58 | /* Size of the MD5 digest for APOP */ | ||
59 | #define APOP_DIGEST 70 | ||
60 | |||
61 | /* Maximum length of a hostname (is this defined somewhere else?) */ | ||
62 | #define MAXHOSTNAMELEN 64 | ||
63 | |||
64 | /* Longest legal POP command */ | ||
65 | #define POP_MAXCMDLEN 255 | ||
66 | |||
67 | #define _GNU_SOURCE | ||
68 | #include <stdarg.h> | ||
69 | #include <stdio.h> | ||
70 | #include <stdlib.h> | ||
71 | #include <string.h> | ||
72 | #include <time.h> | ||
73 | #include <unistd.h> | ||
74 | #include <fcntl.h> | ||
75 | #include <errno.h> | ||
76 | #include <signal.h> | ||
77 | #include <sys/file.h> | ||
78 | #include <sys/types.h> | ||
79 | #include <sys/time.h> | ||
80 | #include <sys/stat.h> | ||
81 | #include <sys/wait.h> | ||
82 | #include <sys/socket.h> | ||
83 | #include <netinet/in.h> | ||
84 | #include <netdb.h> | ||
85 | #include <pwd.h> | ||
86 | #include <grp.h> | ||
87 | #include <syslog.h> | ||
88 | #include <ctype.h> | ||
89 | #include "md5.h" | ||
90 | #include "getopt.h" | ||
91 | #include "mailbox.h" | ||
92 | |||
93 | /* For Berkley DB2 APOP password file */ | ||
94 | #ifdef BDB2 | ||
95 | #include <db2/db.h> | ||
96 | #endif | ||
97 | |||
98 | /* The path to the mail spool files */ | ||
99 | #ifdef HAVE_PATHS_H | ||
100 | #include <paths.h> | ||
101 | #else | ||
102 | #define _PATH_MAILDIR "/usr/spool/mail" | ||
103 | #endif | ||
104 | |||
105 | #ifdef HAVE_SECURITY_PAM_APPL_H | ||
106 | #include <security/pam_appl.h> | ||
107 | #endif | ||
108 | |||
109 | #ifdef HAVE_SHADOW_H | ||
110 | #include <shadow.h> | ||
111 | #endif | ||
112 | |||
113 | #define AUTHORIZATION 0 | ||
114 | #define TRANSACTION 1 | ||
115 | #define UPDATE 2 | ||
116 | |||
117 | #define INTERACTIVE 0 | ||
118 | #define DAEMON 1 | ||
119 | |||
120 | #define OK 0 | ||
121 | #define ERR_WRONG_STATE 1 | ||
122 | #define ERR_BAD_ARGS 2 | ||
123 | #define ERR_BAD_LOGIN 3 | ||
124 | #define ERR_NO_MESG 4 | ||
125 | #define ERR_NOT_IMPL 5 | ||
126 | #define ERR_BAD_CMD 6 | ||
127 | #define ERR_MBOX_LOCK 7 | ||
128 | #define ERR_TOO_LONG 8 | ||
129 | #define ERR_NO_MEM 9 | ||
130 | #define ERR_DEAD_SOCK 10 | ||
131 | #define ERR_SIGNAL 11 | ||
132 | #define ERR_FILE 12 | ||
133 | #define ERR_NO_OFILE 13 | ||
134 | #define ERR_TIMEOUT 14 | ||
135 | |||
136 | mailbox *mbox; | ||
137 | |||
138 | unsigned int port; | ||
139 | unsigned int timeout; | ||
140 | int state; | ||
141 | char *username; | ||
142 | int ifile; | ||
143 | FILE *ofile; | ||
144 | time_t curr_time; | ||
145 | char *md5shared; | ||
146 | |||
147 | int pop3_dele (const char *arg); | ||
148 | int pop3_list (const char *arg); | ||
149 | int pop3_noop (const char *arg); | ||
150 | int pop3_quit (const char *arg); | ||
151 | int pop3_retr (const char *arg); | ||
152 | int pop3_rset (const char *arg); | ||
153 | int pop3_stat (const char *arg); | ||
154 | int pop3_top (const char *arg); | ||
155 | int pop3_uidl (const char *arg); | ||
156 | int pop3_user (const char *arg); | ||
157 | int pop3_apop (const char *arg); | ||
158 | int pop3_auth (const char *arg); | ||
159 | int pop3_capa (const char *arg); | ||
160 | char *pop3_args (const char *cmd); | ||
161 | char *pop3_cmd (const char *cmd); | ||
162 | int pop3_mesg_exist (int mesg); | ||
163 | int pop3_abquit (int reason); | ||
164 | int pop3_lock (void); | ||
165 | int pop3_unlock (void); | ||
166 | int pop3_getsizes (void); | ||
167 | int pop3_mainloop (int infile, int outfile); | ||
168 | int pop3_daemon (int maxchildren); | ||
169 | void pop3_usage (char *argv0); | ||
170 | void pop3_signal (int signal); | ||
171 | void pop3_daemon_init (void); | ||
172 | #ifdef _USE_APOP | ||
173 | char *pop3_apopuser (const char *user); | ||
174 | #endif | ||
175 | char *pop3_readline (int fd); | ||
176 | |||
177 | #endif /* _POP3D_H */ |
pop3d/quit.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Enters the UPDATE phase and deletes marked messages */ | ||
21 | |||
22 | int | ||
23 | pop3_quit (const char *arg) | ||
24 | { | ||
25 | if (strlen (arg) != 0) | ||
26 | return ERR_BAD_ARGS; | ||
27 | |||
28 | if (state == TRANSACTION) | ||
29 | { | ||
30 | mbox_expunge (mbox); | ||
31 | mbox_close (mbox); | ||
32 | syslog (LOG_INFO, "Session ended for user: %s", username); | ||
33 | } | ||
34 | else | ||
35 | syslog (LOG_INFO, "Session ended for no user"); | ||
36 | |||
37 | state = UPDATE; | ||
38 | free (username); | ||
39 | free (md5shared); | ||
40 | |||
41 | fprintf (ofile, "+OK\r\n"); | ||
42 | return OK; | ||
43 | } |
pop3d/retr.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Prints out the specified message */ | ||
21 | |||
22 | int | ||
23 | pop3_retr (const char *arg) | ||
24 | { | ||
25 | int mesg; | ||
26 | char *buf; | ||
27 | |||
28 | if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL)) | ||
29 | return ERR_BAD_ARGS; | ||
30 | |||
31 | if (state != TRANSACTION) | ||
32 | return ERR_WRONG_STATE; | ||
33 | |||
34 | mesg = atoi (arg) - 1; | ||
35 | |||
36 | if (mesg > mbox->messages || mbox_is_deleted(mbox, mesg)) | ||
37 | return ERR_NO_MESG; | ||
38 | |||
39 | fprintf (ofile, "+OK\r\n"); | ||
40 | buf = mbox_get_header (mbox, mesg); | ||
41 | fprintf (ofile, "%s", buf); | ||
42 | free (buf); | ||
43 | buf = mbox_get_body (mbox, mesg); | ||
44 | fprintf (ofile, "%s", buf); | ||
45 | free (buf); | ||
46 | fprintf (ofile, ".\r\n"); | ||
47 | return OK; | ||
48 | } |
pop3d/rset.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Resets the connection so that no messages are marked as deleted */ | ||
21 | |||
22 | int | ||
23 | pop3_rset (const char *arg) | ||
24 | { | ||
25 | int i; | ||
26 | |||
27 | if (strlen (arg) != 0) | ||
28 | return ERR_BAD_ARGS; | ||
29 | |||
30 | if (state != TRANSACTION) | ||
31 | return ERR_WRONG_STATE; | ||
32 | |||
33 | for (i = 0; i < mbox->messages; i++) | ||
34 | mbox_undelete (mbox, i); | ||
35 | |||
36 | fprintf (ofile, "+OK\r\n"); | ||
37 | return OK; | ||
38 | } |
pop3d/stat.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Prints the number of messages and the total size of all messages */ | ||
21 | |||
22 | int | ||
23 | pop3_stat (const char *arg) | ||
24 | { | ||
25 | int size = 0; | ||
26 | int i; | ||
27 | |||
28 | if (strlen (arg) != 0) | ||
29 | return ERR_BAD_ARGS; | ||
30 | |||
31 | if (state != TRANSACTION) | ||
32 | return ERR_WRONG_STATE; | ||
33 | |||
34 | for (i = 0; i < mbox->messages ; i++) | ||
35 | if (!mbox_is_deleted (mbox, i)) | ||
36 | size += mbox->sizes[i]; | ||
37 | |||
38 | fprintf (ofile, "+OK %d %d\r\n", mbox->messages - mbox->num_deleted, size); | ||
39 | return OK; | ||
40 | } |
pop3d/top.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | /* Prints the header of a message plus a specified number of lines */ | ||
21 | |||
22 | int | ||
23 | pop3_top (const char *arg) | ||
24 | { | ||
25 | #ifdef _HAVE_BLACK_MAGIC | ||
26 | int i = 0, header = 1, done = 0; | ||
27 | int mesg, lines; | ||
28 | char *mesgc, *linesc; | ||
29 | char *buf, buf2[80]; | ||
30 | |||
31 | if (strlen (arg) == 0) | ||
32 | return ERR_BAD_ARGS; | ||
33 | |||
34 | if (state != TRANSACTION) | ||
35 | return ERR_WRONG_STATE; | ||
36 | |||
37 | mesgc = pop3_cmd (arg); | ||
38 | linesc = pop3_args (arg); | ||
39 | mesg = atoi (mesgc) - 1; | ||
40 | lines = strlen (linesc) > 0 ? atoi (linesc) : -1; | ||
41 | free (mesgc); | ||
42 | free (linesc); | ||
43 | |||
44 | if (lines < 0) | ||
45 | return ERR_BAD_ARGS; | ||
46 | |||
47 | if (pop3_mesg_exist (mesg) != OK) | ||
48 | return ERR_NO_MESG; | ||
49 | |||
50 | mbox = freopen (mailbox, "r", mbox); | ||
51 | if (mbox == NULL) | ||
52 | return ERR_FILE; | ||
53 | fsetpos (mbox, &(messages[mesg].header)); | ||
54 | |||
55 | fprintf (ofile, "+OK\r\n"); | ||
56 | buf = malloc (sizeof (char) * 80); | ||
57 | if (buf == NULL) | ||
58 | pop3_abquit (ERR_NO_MEM); | ||
59 | |||
60 | while (fgets (buf, 80, mbox) && !done) | ||
61 | { | ||
62 | while (strchr (buf, '\n') == NULL) | ||
63 | { | ||
64 | buf = realloc (buf, sizeof (char) * (strlen (buf) + 81)); | ||
65 | if (buf == NULL) | ||
66 | pop3_abquit (ERR_NO_MEM); | ||
67 | fgets (buf2, 80, mbox); | ||
68 | strncat (buf, buf2, 80); | ||
69 | } | ||
70 | if (!strncmp (buf, "From ", 5)) | ||
71 | done = 1; | ||
72 | else | ||
73 | { | ||
74 | buf[strlen (buf) - 1] = '\0'; | ||
75 | if (header == 1) | ||
76 | { | ||
77 | if (buf[0] == '.') | ||
78 | fprintf (ofile, ".%s\r\n", buf); | ||
79 | else | ||
80 | fprintf (ofile, "%s\r\n", buf); | ||
81 | if ((buf[0] == '\r') || (buf[0] == '\n') || (buf[0]) == '\0') | ||
82 | header = 0; | ||
83 | } | ||
84 | else | ||
85 | { | ||
86 | if (++i <= lines) | ||
87 | { | ||
88 | if (buf[0] == '.') | ||
89 | fprintf (ofile, ".%s\r\n", buf); | ||
90 | else | ||
91 | fprintf (ofile, "%s\r\n", buf); | ||
92 | } | ||
93 | else | ||
94 | done = 1; | ||
95 | } | ||
96 | } | ||
97 | buf = realloc (buf, sizeof (char) * 80); | ||
98 | if (buf == NULL) | ||
99 | pop3_abquit (ERR_NO_MEM); | ||
100 | } | ||
101 | |||
102 | free (buf); | ||
103 | fprintf (ofile, ".\r\n"); | ||
104 | return OK; | ||
105 | #else | ||
106 | return ERR_NOT_IMPL; | ||
107 | #endif | ||
108 | } | ||
109 |
pop3d/uidl.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | int | ||
21 | pop3_uidl (const char *arg) | ||
22 | { | ||
23 | if (state != TRANSACTION) | ||
24 | return ERR_WRONG_STATE; | ||
25 | |||
26 | return ERR_NOT_IMPL; | ||
27 | } |
pop3d/user.c
0 → 100644
1 | /* GNU POP3 - a small, fast, and efficient POP3 daemon | ||
2 | Copyright (C) 1999 Jakob 'sparky' Kaivo <jkaivo@nodomainname.net> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software | ||
16 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
17 | |||
18 | #include "pop3d.h" | ||
19 | |||
20 | #ifdef USE_LIBPAM | ||
21 | #define COPY_STRING(s) (s) ? strdup(s) : NULL | ||
22 | |||
23 | static char *_pwd; | ||
24 | static char *_user; | ||
25 | static int _perr = 0; | ||
26 | |||
27 | #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) { \ | ||
28 | pam_end(pamh, 0); \ | ||
29 | return ERR_BAD_LOGIN; } | ||
30 | |||
31 | static int | ||
32 | PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) | ||
33 | { | ||
34 | int replies = 0; | ||
35 | struct pam_response *reply = NULL; | ||
36 | |||
37 | reply = (struct pam_response *) malloc (sizeof (struct pam_response) * num_msg); | ||
38 | if (!reply) | ||
39 | return PAM_CONV_ERR; | ||
40 | |||
41 | for (replies = 0; replies < num_msg; replies++) | ||
42 | { | ||
43 | switch (msg[replies]->msg_style) | ||
44 | { | ||
45 | case PAM_PROMPT_ECHO_ON: | ||
46 | reply[replies].resp_retcode = PAM_SUCCESS; | ||
47 | reply[replies].resp = COPY_STRING (_user); | ||
48 | /* PAM frees resp */ | ||
49 | break; | ||
50 | case PAM_PROMPT_ECHO_OFF: | ||
51 | reply[replies].resp_retcode = PAM_SUCCESS; | ||
52 | reply[replies].resp = COPY_STRING (_pwd); | ||
53 | /* PAM frees resp */ | ||
54 | break; | ||
55 | case PAM_TEXT_INFO: | ||
56 | case PAM_ERROR_MSG: | ||
57 | reply[replies].resp_retcode = PAM_SUCCESS; | ||
58 | reply[replies].resp = NULL; | ||
59 | break; | ||
60 | default: | ||
61 | free (reply); | ||
62 | _perr = 1; | ||
63 | return PAM_CONV_ERR; | ||
64 | } | ||
65 | } | ||
66 | *resp = reply; | ||
67 | return PAM_SUCCESS; | ||
68 | } | ||
69 | |||
70 | static struct pam_conv PAM_conversation = | ||
71 | {&PAM_gnupop3d_conv, NULL}; | ||
72 | #endif /* USE_LIBPAM */ | ||
73 | |||
74 | /* Basic user authentication. This also takes the PASS command and verifies | ||
75 | the user name and password. Calls setuid() upon successful verification, | ||
76 | otherwise it will (likely) return ERR_BAD_LOGIN */ | ||
77 | |||
78 | int | ||
79 | pop3_user (const char *arg) | ||
80 | { | ||
81 | char *buf, pass[POP_MAXCMDLEN], *tmp, *cmd; | ||
82 | #ifdef USE_LIBPAM | ||
83 | pam_handle_t *pamh; | ||
84 | int pamerror; | ||
85 | #endif /* !USE_LIBPAM */ | ||
86 | struct passwd *pw; | ||
87 | |||
88 | if (state != AUTHORIZATION) | ||
89 | return ERR_WRONG_STATE; | ||
90 | |||
91 | if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL)) | ||
92 | return ERR_BAD_ARGS; | ||
93 | |||
94 | fprintf (ofile, "+OK\r\n"); | ||
95 | fflush (ofile); | ||
96 | |||
97 | buf = pop3_readline (ifile); | ||
98 | cmd = pop3_cmd (buf); | ||
99 | tmp = pop3_args (buf); | ||
100 | free (buf); | ||
101 | |||
102 | if (strlen (tmp) > POP_MAXCMDLEN) | ||
103 | { | ||
104 | free (tmp); | ||
105 | return ERR_TOO_LONG; | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | strncpy (pass, tmp, POP_MAXCMDLEN); | ||
110 | free (tmp); | ||
111 | } | ||
112 | |||
113 | if (strlen (cmd) > 4) | ||
114 | { | ||
115 | free (cmd); | ||
116 | return ERR_BAD_CMD; | ||
117 | } | ||
118 | if ((strcasecmp (cmd, "PASS") == 0)) | ||
119 | { | ||
120 | free (cmd); | ||
121 | |||
122 | #ifdef _USE_APOP | ||
123 | /* Check to see if they have an APOP password. If so, refuse USER/PASS */ | ||
124 | tmp = pop3_apopuser (arg); | ||
125 | if (tmp != NULL) | ||
126 | { | ||
127 | syslog (LOG_INFO, "APOP user %s tried to log in with USER", arg); | ||
128 | free (tmp); | ||
129 | return ERR_BAD_LOGIN; | ||
130 | } | ||
131 | free (tmp); | ||
132 | #endif | ||
133 | |||
134 | pw = getpwnam (arg); | ||
135 | #ifndef USE_LIBPAM | ||
136 | if (pw == NULL) | ||
137 | return ERR_BAD_LOGIN; | ||
138 | if (pw->pw_uid < 1) | ||
139 | return ERR_BAD_LOGIN; | ||
140 | if (strcmp (pw->pw_passwd, crypt (pass, pw->pw_passwd))) | ||
141 | { | ||
142 | #ifdef HAVE_SHADOW_H | ||
143 | struct spwd *spw; | ||
144 | spw = getspnam (arg); | ||
145 | if (spw == NULL) | ||
146 | return ERR_BAD_LOGIN; | ||
147 | if (strcmp (spw->sp_pwdp, crypt (pass, spw->sp_pwdp))) | ||
148 | #endif /* HAVE_SHADOW_H */ | ||
149 | return ERR_BAD_LOGIN; | ||
150 | } | ||
151 | #else /* USE_LIBPAM */ | ||
152 | _user = (char *) arg; | ||
153 | _pwd = pass; | ||
154 | /* libpam doesn't log to LOG_MAIL */ | ||
155 | closelog (); | ||
156 | pamerror = pam_start ("gnu-pop3d", arg, &PAM_conversation, &pamh); | ||
157 | PAM_ERROR; | ||
158 | pamerror = pam_authenticate (pamh, 0); | ||
159 | PAM_ERROR; | ||
160 | pamerror = pam_acct_mgmt (pamh, 0); | ||
161 | PAM_ERROR; | ||
162 | pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED); | ||
163 | PAM_ERROR; | ||
164 | pam_end (pamh, PAM_SUCCESS); | ||
165 | openlog ("gnu-pop3d", LOG_PID, LOG_MAIL); | ||
166 | #endif /* USE_LIBPAM */ | ||
167 | |||
168 | #ifdef MAILSPOOLHOME | ||
169 | chdir (pw->pw_dir); | ||
170 | mbox = mbox_open (MAILSPOOLHOME); | ||
171 | if (mbox == NULL) | ||
172 | { | ||
173 | /* See comments below... */ | ||
174 | chdir (_PATH_MAILDIR); | ||
175 | #endif /* MAILSPOOLHOME */ | ||
176 | mbox = mbox_open (arg); | ||
177 | if (mbox == NULL) | ||
178 | { | ||
179 | /* Check the error type... */ | ||
180 | /* Until then, though */ | ||
181 | state = AUTHORIZATION; | ||
182 | return ERR_MBOX_LOCK; | ||
183 | } | ||
184 | #ifdef MAILSPOOLHOME | ||
185 | } | ||
186 | #endif | ||
187 | username = strdup (arg); | ||
188 | if (username == NULL) | ||
189 | pop3_abquit (ERR_NO_MEM); | ||
190 | state = TRANSACTION; | ||
191 | |||
192 | if (pw != NULL && pw->pw_uid > 1) | ||
193 | setuid (pw->pw_uid); | ||
194 | |||
195 | fprintf (ofile, "+OK opened mailbox for %s\r\n", username); | ||
196 | syslog (LOG_INFO, "User '%s' logged in with mailbox '%s'", username, | ||
197 | mbox->name); | ||
198 | return OK; | ||
199 | } | ||
200 | else if (strcasecmp (cmd, "QUIT") == 0) | ||
201 | { | ||
202 | free (cmd); | ||
203 | return pop3_quit (pass); | ||
204 | } | ||
205 | |||
206 | free (cmd); | ||
207 | return ERR_BAD_LOGIN; | ||
208 | } |
-
Please register or sign in to post a comment