1 /*
2  * libEtPan! -- a mail stuff library
3  *
4  * Copyright (C) 2001, 2005 - DINH Viet Hoa
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the libEtPan! project nor the names of its
16  *    contributors may be used to endorse or promote products derived
17  *    from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * $Id: nntpstorage.c,v 1.19 2008/02/17 13:13:27 hoa Exp $
34  */
35 
36 #ifdef HAVE_CONFIG_H
37 #	include <config.h>
38 #endif
39 
40 #include "nntpstorage.h"
41 
42 #include <stdlib.h>
43 #include <string.h>
44 
45 #include "maildriver.h"
46 #include "nntpdriver.h"
47 #include "nntpdriver_cached.h"
48 #include "mailstorage_tools.h"
49 #include "mail.h"
50 
51 /* nntp storage */
52 
53 #define NNTP_DEFAULT_PORT  119
54 #define NNTPS_DEFAULT_PORT 563
55 
56 static int nntp_mailstorage_connect(struct mailstorage * storage);
57 static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
58     char * pathname, mailsession ** result);
59 static void nntp_mailstorage_uninitialize(struct mailstorage * storage);
60 
61 static mailstorage_driver nntp_mailstorage_driver = {
62   /* sto_name               */ "nntp",
63   /* sto_connect            */ nntp_mailstorage_connect,
64   /* sto_get_folder_session */ nntp_mailstorage_get_folder_session,
65   /* sto_uninitialize       */ nntp_mailstorage_uninitialize
66 };
67 
68 LIBETPAN_EXPORT
nntp_mailstorage_init(struct mailstorage * storage,const char * nntp_servername,uint16_t nntp_port,const char * nntp_command,int nntp_connection_type,int nntp_auth_type,const char * nntp_login,const char * nntp_password,int nntp_cached,const char * nntp_cache_directory,const char * nntp_flags_directory)69 int nntp_mailstorage_init(struct mailstorage * storage,
70     const char * nntp_servername, uint16_t nntp_port,
71     const char * nntp_command,
72     int nntp_connection_type, int nntp_auth_type,
73     const char * nntp_login, const char * nntp_password,
74     int nntp_cached,
75     const char * nntp_cache_directory, const char * nntp_flags_directory)
76 {
77   return nntp_mailstorage_init_with_local_address(storage,
78     nntp_servername, nntp_port,
79     NULL, 0,
80     nntp_command,
81     nntp_connection_type, nntp_auth_type,
82     nntp_login, nntp_password,
83     nntp_cached, nntp_cache_directory,
84     nntp_flags_directory);
85 }
86 
87 LIBETPAN_EXPORT
nntp_mailstorage_init_with_local_address(struct mailstorage * storage,const char * nntp_servername,uint16_t nntp_port,const char * nntp_local_address,uint16_t nntp_local_port,const char * nntp_command,int nntp_connection_type,int nntp_auth_type,const char * nntp_login,const char * nntp_password,int nntp_cached,const char * nntp_cache_directory,const char * nntp_flags_directory)88 int nntp_mailstorage_init_with_local_address(struct mailstorage * storage,
89     const char * nntp_servername, uint16_t nntp_port,
90     const char * nntp_local_address, uint16_t nntp_local_port,
91     const char * nntp_command,
92     int nntp_connection_type, int nntp_auth_type,
93     const char * nntp_login, const char * nntp_password,
94     int nntp_cached, const char * nntp_cache_directory,
95     const char * nntp_flags_directory)
96 {
97   struct nntp_mailstorage * nntp_storage;
98   int res;
99 
100   nntp_storage = malloc(sizeof(* nntp_storage));
101   if (nntp_storage == NULL) {
102     res = MAIL_ERROR_MEMORY;
103     goto err;
104   }
105 
106   if (nntp_servername != NULL) {
107     nntp_storage->nntp_servername = strdup(nntp_servername);
108     if (nntp_storage->nntp_servername == NULL) {
109       res = MAIL_ERROR_MEMORY;
110       goto free;
111     }
112   }
113   else {
114     nntp_storage->nntp_servername = NULL;
115   }
116 
117   if (nntp_local_address != NULL) {
118     nntp_storage->nntp_local_address = strdup(nntp_local_address);
119     if (nntp_storage->nntp_local_address == NULL) {
120       res = MAIL_ERROR_MEMORY;
121       goto free_servername;
122     }
123   }
124   else {
125     nntp_storage->nntp_local_address = NULL;
126   }
127 
128   nntp_storage->nntp_local_port = nntp_local_port;
129 
130   nntp_storage->nntp_connection_type = nntp_connection_type;
131 
132   if (nntp_port == 0) {
133     switch (nntp_connection_type) {
134     case CONNECTION_TYPE_PLAIN:
135     case CONNECTION_TYPE_COMMAND:
136       nntp_port = NNTP_DEFAULT_PORT;
137       break;
138 
139     case CONNECTION_TYPE_TLS:
140     case CONNECTION_TYPE_COMMAND_TLS:
141       nntp_port = NNTPS_DEFAULT_PORT;
142       break;
143 
144     default:
145       nntp_port = NNTP_DEFAULT_PORT;
146       break;
147     }
148   }
149 
150   nntp_storage->nntp_port = nntp_port;
151 
152   if (nntp_command != NULL) {
153     nntp_storage->nntp_command = strdup(nntp_command);
154     if (nntp_storage->nntp_command == NULL) {
155       res = MAIL_ERROR_MEMORY;
156       goto free_local_address;
157     }
158   }
159   else
160     nntp_storage->nntp_command = NULL;
161 
162   nntp_storage->nntp_auth_type = nntp_auth_type;
163 
164   if (nntp_login != NULL) {
165     nntp_storage->nntp_login = strdup(nntp_login);
166     if (nntp_storage->nntp_login == NULL) {
167       res = MAIL_ERROR_MEMORY;
168       goto free_command;
169     }
170   }
171   else
172     nntp_storage->nntp_login = NULL;
173 
174   if (nntp_password != NULL) {
175     nntp_storage->nntp_password = strdup(nntp_password);
176     if (nntp_storage->nntp_password == NULL) {
177       res = MAIL_ERROR_MEMORY;
178       goto free_login;
179     }
180   }
181   else
182     nntp_storage->nntp_password = NULL;
183 
184   nntp_storage->nntp_cached = nntp_cached;
185 
186   if (nntp_cached && (nntp_cache_directory != NULL) &&
187       (nntp_flags_directory != NULL)) {
188     nntp_storage->nntp_cache_directory = strdup(nntp_cache_directory);
189     if (nntp_storage->nntp_cache_directory == NULL) {
190       res = MAIL_ERROR_MEMORY;
191       goto free_password;
192     }
193     nntp_storage->nntp_flags_directory = strdup(nntp_flags_directory);
194     if (nntp_storage->nntp_flags_directory == NULL) {
195       res = MAIL_ERROR_MEMORY;
196       goto free_cache_directory;
197     }
198   }
199   else {
200     nntp_storage->nntp_cached = FALSE;
201     nntp_storage->nntp_cache_directory = NULL;
202     nntp_storage->nntp_flags_directory = NULL;
203   }
204 
205   storage->sto_data = nntp_storage;
206   storage->sto_driver = &nntp_mailstorage_driver;
207 
208   return MAIL_NO_ERROR;
209 
210  free_cache_directory:
211   free(nntp_storage->nntp_cache_directory);
212  free_password:
213   free(nntp_storage->nntp_password);
214  free_login:
215   free(nntp_storage->nntp_login);
216  free_command:
217   free(nntp_storage->nntp_command);
218  free_local_address:
219   free(nntp_storage->nntp_local_address);
220  free_servername:
221   free(nntp_storage->nntp_servername);
222  free:
223   free(nntp_storage);
224  err:
225   return res;
226 }
227 
nntp_mailstorage_uninitialize(struct mailstorage * storage)228 static void nntp_mailstorage_uninitialize(struct mailstorage * storage)
229 {
230   struct nntp_mailstorage * nntp_storage;
231 
232   nntp_storage = storage->sto_data;
233 
234   free(nntp_storage->nntp_flags_directory);
235   free(nntp_storage->nntp_cache_directory);
236   free(nntp_storage->nntp_password);
237   free(nntp_storage->nntp_login);
238   free(nntp_storage->nntp_command);
239   free(nntp_storage->nntp_local_address);
240   free(nntp_storage->nntp_servername);
241   free(nntp_storage);
242 
243   storage->sto_data = NULL;
244 }
245 
nntp_mailstorage_connect(struct mailstorage * storage)246 static int nntp_mailstorage_connect(struct mailstorage * storage)
247 {
248   struct nntp_mailstorage * nntp_storage;
249   mailsession_driver * driver;
250   int r;
251   int res;
252   mailsession * session;
253 
254   nntp_storage = storage->sto_data;
255 
256   if (nntp_storage->nntp_cached)
257     driver = nntp_cached_session_driver;
258   else
259     driver = nntp_session_driver;
260 
261   r = mailstorage_generic_connect_with_local_address(driver,
262       nntp_storage->nntp_servername, nntp_storage->nntp_port,
263       nntp_storage->nntp_local_address, nntp_storage->nntp_local_port,
264       nntp_storage->nntp_command,
265       nntp_storage->nntp_connection_type,
266       NNTPDRIVER_CACHED_SET_CACHE_DIRECTORY,
267       nntp_storage->nntp_cache_directory,
268       NNTPDRIVER_CACHED_SET_FLAGS_DIRECTORY,
269       nntp_storage->nntp_flags_directory,
270       &session);
271   switch (r) {
272   case MAIL_NO_ERROR_NON_AUTHENTICATED:
273   case MAIL_NO_ERROR_AUTHENTICATED:
274   case MAIL_NO_ERROR:
275     break;
276   default:
277     res = r;
278     goto err;
279   }
280 
281   r = mailstorage_generic_auth(session, r,
282       nntp_storage->nntp_connection_type,
283       nntp_storage->nntp_login,
284       nntp_storage->nntp_password);
285   if (r != MAIL_NO_ERROR) {
286     res = r;
287     goto free;
288   }
289 
290   storage->sto_session = session;
291 
292   return MAIL_NO_ERROR;
293 
294  free:
295   mailsession_free(session);
296  err:
297   return res;
298 }
299 
nntp_mailstorage_get_folder_session(struct mailstorage * storage,char * pathname,mailsession ** result)300 static int nntp_mailstorage_get_folder_session(struct mailstorage * storage,
301     char * pathname, mailsession ** result)
302 {
303   mailsession_select_folder(storage->sto_session, pathname);
304 
305   * result = storage->sto_session;
306 
307   return MAIL_NO_ERROR;
308 }
309