OSDN Git Service

e829552c001ce511b2ab2b3904e1e456f0b563a4
[opengatem/opengatem.git] / mngsrc / auth-ftps.c
1 /**************************************************
2 OpengateM - MAC address authentication system 
3  module for Authentication by FTPS
4        (Explicit and Implicit FTP modes)
5
6 Copyright (C) 2006 Opengate Project Team
7 Written by Yoshiaki Watanabe
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 Email: watanaby@is.saga-u.ac.jp
24 **************************************************/
25 /*
26   Thanks to programs and documentations refered.
27    Sample client application cli.cpp found in the OpenSSL site 
28     (developed by Sampo Kellomaki and simplified by Wade Scholine) 
29    Apache module mod_auth_pam.c by Ingo Luetkebohle
30 */
31
32 #include "opengatemmng.h"
33
34 /*****************************************/
35 /* Auth by FTP on SSL - Explicit Mode    */
36 /*****************************************/
37 int authFtpse(char *userid, char *passwd)
38 {
39   int           sockfd, n;
40   char          recvline[BUFFMAXLN];
41   int           authResult;
42   char* serverAddr; /* auth server address */
43   char* port;      /* auth server port */
44   SSL_CTX    *ctx;
45   SSL        *ssl;
46   const SSL_METHOD *meth;
47
48   /* get auth server address */
49   serverAddr=GetConfValue("AuthServer/Address");
50
51   if(isNull(serverAddr)){
52     err_msg("ERR at %s#%d: Missing address for FTP server in config",
53             __FILE__,__LINE__);
54     return DENY;
55   }
56
57   /* get auth server port */
58   port=GetConfValue("AuthServer/Port");
59
60   /* FTP server connect */
61   if(isNull(port)){
62     sockfd = Tcp_connect(serverAddr, "ftp"); /* use ftp port in explicit */
63   }else{
64     sockfd = Tcp_connect(serverAddr, port);
65   }
66   if(sockfd<0){
67     err_msg("ERR at %s#%d: Ftpse server is not normal 0",__FILE__,__LINE__);
68     return DENY;
69   }
70
71   /* get [220 <host> FTP server ..]*/
72   if((n = readln(sockfd, recvline, BUFFMAXLN)) < 0) {
73     err_msg("ERR at %s#%d: Ftpse server is not normal 1",__FILE__,__LINE__);
74     Close(sockfd);
75     return DENY;
76   }
77   if(strstr(recvline,"220")!=recvline){
78     err_msg("ERR at %s#%d: Ftpse server is not normal 2",__FILE__,__LINE__);
79     Close(sockfd);
80     return DENY;
81   }
82
83   /* put [AUTH TLS] */
84   Writefmt(sockfd, "AUTH TLS\r\n");
85
86   /* get [234 AUTH TLS successful] */
87   if((n = readln(sockfd, recvline, BUFFMAXLN)) < 0) {
88     err_msg("ERR at %s#%d: Ftpse server is not normal 3",__FILE__,__LINE__);
89     Close(sockfd);
90     return DENY;
91   }
92   if(strstr(recvline,"234")!=recvline){
93     err_msg("ERR at %s#%d: Ftpse server is not normal 4",__FILE__,__LINE__);
94     Close(sockfd);
95     return DENY;
96   }
97
98   /* ----------------------------------------------- */
99   /* prepare SSL */
100   SSLeay_add_ssl_algorithms();
101   meth = SSLv23_client_method();
102   SSL_load_error_strings();
103   ctx = SSL_CTX_new (meth);
104   if( ctx == NULL ){
105     err_msg("ERR at %s#%d: SSL_CTX_new returns NULL",__FILE__,__LINE__);
106     return DENY;
107   }
108   
109   /* ----------------------------------------------- */
110   /* start SSL negotiation. */
111   
112   ssl = SSL_new (ctx);
113   if( ssl == NULL ){
114     err_msg("ERR at %s#%d: SSL_new returns NULL",__FILE__,__LINE__);
115     return DENY;
116   }
117
118   SSL_set_fd (ssl, sockfd);
119   if( SSL_connect (ssl) == -1 ){
120     err_msg("ERR at %s#%d: SSL_connect returns error",__FILE__,__LINE__);
121     return DENY;
122   }
123
124   /* --------------------------------------------------- */
125   /* DATA EXCHANGE - Send a message and receive a reply. */
126
127   /* put [USER <userid>] */
128   WritefmtSSL(ssl, "USER %s\r\n", userid);
129
130   /* get [331 Password required ..] */
131   if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
132     err_msg("ERR at %s#%d: Ftpse server is not normal 5",__FILE__,__LINE__);
133     authResult=DENY;
134     goto EXITPOINT;
135   }
136
137   /* if multi-line greeting [220 ...] exist, skip them. */
138   while(strstr(recvline,"220")==recvline){
139     if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
140       err_msg("ERR at %s#%d: Ftpse server is not normal 6",__FILE__,__LINE__);
141       authResult=DENY;
142       goto EXITPOINT;
143     }
144   }
145
146   /* check [331 Password required ..] */
147   if(strstr(recvline,"331")!=recvline){
148     err_msg("ERR at %s#%d: Ftpse server is not normal 7",__FILE__,__LINE__);
149     authResult=DENY;
150     goto EXITPOINT;
151   }
152
153   /* put [PASS <password>] */
154   WritefmtSSL(ssl, "PASS %s\r\n", passwd);
155
156   /* get [230 User <userid> logged in] */
157   if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
158     err_msg("ERR at %s#%d: Ftpse server is not normal 8",__FILE__,__LINE__);
159     authResult=DENY;
160     goto EXITPOINT;
161   }
162   if(strstr(recvline,"230")==recvline){
163     authResult=ACCEPT;
164   }else{
165     authResult=DENY;
166   }
167   
168   /* put [quit] */
169   WritefmtSSL(ssl,"quit\r\n");
170
171 EXITPOINT:
172   SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
173
174   /* Clean up. */
175   Close(sockfd);
176   SSL_free (ssl);
177   SSL_CTX_free (ctx);
178
179   return authResult;
180 }
181
182
183 /*****************************************/
184 /* Auth by FTP on SSL - Implicit Mode    */
185 /*****************************************/
186 int authFtpsi(char *userid, char *passwd)
187 {
188   int           sockfd, n;
189   char          recvline[BUFFMAXLN];
190   int           authResult;
191   char* serverAddr; /* auth server address */
192   char* port;      /* auth server port */
193   SSL_CTX    *ctx;
194   SSL        *ssl;
195   const SSL_METHOD *meth;
196
197   /* get auth server address */
198   serverAddr=GetConfValue("AuthServer/Address");
199
200   if(isNull(serverAddr)){
201     err_msg("ERR at %s#%d: Missing address for FTP server in config",
202             __FILE__,__LINE__);
203     return DENY;
204   }
205
206   /* get auth server port */
207   port=GetConfValue("AuthServer/Port");
208
209   /* FTP server connect */
210   if(port==NULL){
211     sockfd = Tcp_connect(serverAddr, "ftps");
212   }else{
213     sockfd = Tcp_connect(serverAddr, port);
214   }
215   if(sockfd<0){
216     err_msg("ERR at %s#%d: Ftpsi server is not normal 0",__FILE__,__LINE__);
217     return DENY;
218   }
219
220   /* ----------------------------------------------- */
221   /* prepare SSL */
222   SSLeay_add_ssl_algorithms();
223   meth = SSLv2_client_method();
224   SSL_load_error_strings();
225   ctx = SSL_CTX_new (meth);
226   if( ctx == NULL ){
227     err_msg("ERR at %s#%d: SSL_CTX_new returns NULL",__FILE__,__LINE__);
228     return DENY;
229   }
230   
231   /* ----------------------------------------------- */
232   /* start SSL negotiation. */
233   
234   ssl = SSL_new (ctx);
235   if( ssl == NULL ){
236     err_msg("ERR at %s#%d: SSL_new returns NULL",__FILE__,__LINE__);
237     return DENY;
238   }
239
240   SSL_set_fd (ssl, sockfd);
241   if( SSL_connect (ssl) == -1 ){
242     err_msg("ERR at %s#%d: SSL_connect returns error",__FILE__,__LINE__);
243     return DENY;
244   }
245
246   /* --------------------------------------------------- */
247   /* DATA EXCHANGE - Send a message and receive a reply. */
248
249   /* get [220 <host> FTP server ..]*/
250   if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
251     err_msg("ERR at %s#%d: Ftpsi server is not normal 1",__FILE__,__LINE__);
252     authResult=DENY;
253     goto EXITPOINT;
254   }
255   if(strstr(recvline,"220")!=recvline){
256     err_msg("ERR at %s#%d: Ftpsi server is not normal 2",__FILE__,__LINE__);
257     authResult=DENY;
258     goto EXITPOINT;
259   }
260
261   /* put [USER <userid>] */
262   WritefmtSSL(ssl, "USER %s\r\n", userid);
263
264   /* get [331 Password required ..] */
265   if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
266     err_msg("ERR at %s#%d: Ftpi server is not normal 3",__FILE__,__LINE__);
267     authResult=DENY;
268     goto EXITPOINT;
269   }
270
271   /* if multi-line greeting [220 ...] exist, skip them. */
272   while(strstr(recvline,"220")==recvline){
273     if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
274       err_msg("ERR at %s#%d: Ftpsi server is not normal 4",__FILE__,__LINE__);
275       authResult=DENY;
276       goto EXITPOINT;
277     }
278   }
279
280   /* check [331 Password required ..] */
281   if(strstr(recvline,"331")!=recvline){
282     err_msg("ERR at %s#%d: Ftpsi server is not normal 5",__FILE__,__LINE__);
283     authResult=DENY;
284     goto EXITPOINT;
285   }
286
287   /* put [PASS <password>] */
288   WritefmtSSL(ssl, "PASS %s\r\n", passwd);
289
290   /* get [230 User <userid> logged in] */
291   if((n = readlnSSL(ssl, recvline, BUFFMAXLN)) < 0) {
292     err_msg("ERR at %s#%d: Ftpsi server is not normal 6",__FILE__,__LINE__);
293     authResult=DENY;
294     goto EXITPOINT;
295   }
296   if(strstr(recvline,"230")==recvline){
297     authResult=ACCEPT;
298   }else{
299     authResult=DENY;
300   }
301   
302   /* put [quit] */
303   WritefmtSSL(ssl,"quit\r\n");
304
305 EXITPOINT:
306   SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
307
308   /* Clean up. */
309   Close(sockfd);
310   SSL_free (ssl);
311   SSL_CTX_free (ctx);
312
313   return authResult;
314 }
315
316 /***************************/
317
318 int AuthFtpse(char *userid, char *passwd)
319 {
320   int ret;
321
322   if(debug>1) err_msg("DEBUG:=>authFtpse(%s,passwd)",userid);
323   ret=authFtpse(userid,passwd);
324   if(debug>1) err_msg("DEBUG:(%d)<=authFtpse( )",ret);
325
326   return ret;
327 }
328
329 int AuthFtpsi(char *userid, char *passwd)
330 {
331   int ret;
332
333   if(debug>1) err_msg("DEBUG:=>authFtpsi(%s,passwd)",userid);
334   ret=authFtpsi(userid,passwd);
335   if(debug>1) err_msg("DEBUG:(%d)<=authFtpsi( )",ret);
336
337   return ret;
338 }
339