source: TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_private.c @ 1390

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_private.c@1390
Revision 1390, 13.7 KB checked in by spascoe, 13 years ago (diff)

Eliminated many socket related compile time warnings. These
were due to missing #include statements in the bbftp source.

MOST test cases now succeed on callisto! cross-platform stability
is looking more optimistic :-)

Line 
1/*
2 * bbftpd/bbftpd_private.c
3 * Copyright (C) 1999, 2000, 2001, 2002 IN2P3, CNRS
4 * bbftp@in2p3.fr
5 * http://doc.in2p3.fr/bbftp
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */ 
21
22/****************************************************************************
23
24 
25 
26 bbftpd_private.c   v 2.1.0 2001/05/21  - Routines creation
27
28*****************************************************************************/
29#include <errno.h>
30#include <netinet/in.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <bbftpd_private_log.h>
34#include <sys/socket.h>
35#if TIME_WITH_SYS_TIME
36# include <sys/time.h>
37# include <time.h>
38#else
39# if HAVE_SYS_TIME_H
40#  include <sys/time.h>
41# else
42#  include <time.h>
43# endif
44#endif
45#include <utime.h>
46
47#include <openssl/rsa.h>
48#include <openssl/err.h>
49
50#include <bbftpd.h>
51#include <bbftpd_private.h>
52#include <config.h>
53#include <common.h>
54#include <daemon_proto.h>
55#include <daemon.h>
56#include <structures.h>
57#include <version.h>
58
59extern  int     incontrolsock ;
60extern  int     outcontrolsock ;
61extern  int         recvcontrolto ;
62extern  int         sendcontrolto ;
63extern  RSA     *myrsa ;
64
65
66/*******************************************************************************
67** bbftpd_private_receive_connection :                                         *
68**                                                                             *
69**      This routine is called when a connection occurs in private             *
70**      authentication mode. It receives the plublic key of the client and     *
71**      gives the hand to the bbftpd_private_auth routine and then if this     *
72**      routine returns 0 to set up correctly the global parameters            *
73**                                                                             *
74**      OUPUT variable :                                                       *
75**          logmessage :  to write the error message in case of error          *
76**                                                                             *
77**      GLOBAL VARIABLE USED :                                                 *                                                                      *
78**          hisrsa              MODIFIED                                       *
79**                                                                             *
80**                                                                             *
81**      RETURN:                                                                *
82**          -1  Unrecoverable error                                            *
83**           0  OK                                                             *
84**                                                                             *
85*******************************************************************************/
86int bbftpd_private_receive_connection(int msglen) 
87{
88
89    char    *receive_buffer ;
90    char    logmessage[1024] ;
91    int     lenkey ;
92    int     lenexpo ;
93    unsigned char   *pubkey ;
94    unsigned char   *pubexponent ;
95    int     retcode ;
96    struct  mess_sec    *msg_sec ;
97   
98    sprintf(logmessage,"bbftpd version %s",VERSION) ;
99#ifndef WORDS_BIGENDIAN
100    msglen = ntohl(msglen) ;
101#endif
102    /*
103    ** First allocate the buffer
104    */
105    if ( (receive_buffer = (char *) malloc (msglen+1)) == NULL ) {
106        bbftpd_log(BBFTPD_ERR,"Error allocation memory for receive_buffer (bbftpd_private_receive_connection) ") ;
107        strcat(logmessage," : Error allocation memory for receive_buffer") ;
108        reply(MSG_BAD,logmessage) ;
109        return -1 ;
110    }
111    if ( (retcode = readmessage(incontrolsock,receive_buffer,msglen,recvcontrolto)) < 0 ) {
112        FREE(receive_buffer) ;
113        /*
114        ** Error ...
115        */
116        return(retcode) ;
117    }
118    msg_sec = (struct mess_sec *)receive_buffer ;
119    if ( msg_sec->crtype ==  CRYPT_RSA_PKCS1_OAEP_PADDING) {
120#ifndef WORDS_BIGENDIAN
121        lenkey = ntohl(msg_sec->pubkeylen) ;
122        lenexpo = ntohl(msg_sec->expolen) ;
123#else
124        lenkey = msg_sec->pubkeylen ;
125        lenexpo = msg_sec->expolen ;
126#endif
127        pubkey  = (unsigned char *)receive_buffer  + CRYPTMESSLEN ;
128        pubexponent = pubkey + lenkey ;
129        if ( (hisrsa = RSA_new()) == NULL) {
130            FREE(receive_buffer) ;
131            bbftpd_log(BBFTPD_ERR,"Error RSA_new (bbftpd_private_receive_connection) ") ;
132            strcat(logmessage," : RSA Error") ;
133            reply(MSG_BAD,logmessage) ;
134            return -1 ;
135        }
136        /*
137        ** Getting BIGNUM structures to store the key and exponent
138        */
139        if ( (hisrsa->n = BN_new()) == NULL) {
140            FREE(receive_buffer) ;
141            bbftpd_log(BBFTPD_ERR,"Error BN_new (bbftpd_private_receive_connection) ") ;
142            strcat(logmessage," : RSA Error") ;
143            reply(MSG_BAD,logmessage) ;
144            return -1 ;
145        }
146        if ( (hisrsa->e = BN_new()) == NULL) { 
147            FREE(receive_buffer) ;
148            bbftpd_log(BBFTPD_ERR,"Error BN_new (bbftpd_private_receive_connection) ") ;
149            strcat(logmessage," : RSA Error") ;
150            reply(MSG_BAD,logmessage) ;
151            return -1 ;
152        }
153        /*
154        ** Copy the key and exponent received
155        */
156        if ( BN_mpi2bn(pubkey,lenkey,hisrsa->n) == NULL ) {
157            FREE(receive_buffer) ;
158            bbftpd_log(BBFTPD_ERR,"Error BN_mpi2bn (bbftpd_private_receive_connection) ") ;
159            strcat(logmessage," : RSA Error") ;
160            reply(MSG_BAD,logmessage) ;
161            return -1 ;
162        }
163        if ( BN_mpi2bn(pubexponent,lenexpo,hisrsa->e) == NULL ) {
164            FREE(receive_buffer) ;
165            bbftpd_log(BBFTPD_ERR,"Error BN_mpi2bn (bbftpd_private_receive_connection) ") ;
166            strcat(logmessage," : RSA Error") ;
167            reply(MSG_BAD,logmessage) ;
168            return -1 ;
169        }
170    } else {
171        bbftpd_log(BBFTPD_ERR,"Unkwown encryption %d",msg_sec->crtype) ;
172        strcat(logmessage," : Unknown encryption") ;
173        reply(MSG_BAD,logmessage) ;
174        return -1 ;
175    }
176    /*
177    ** Now give hand to user routine
178    */
179
180    if ( bbftpd_private_auth(logmessage) < 0 ) {
181        bbftpd_log(BBFTPD_ERR,"bbftpd_private_auth failed : %s",logmessage) ;
182        reply(MSG_BAD,logmessage) ;
183        return -1 ;
184    }
185
186    return 0 ;
187}
188/*******************************************************************************
189** bbftpd_private_send    :                                                    *
190**                                                                             *
191**      This routine is going to crypt the buffer and to send it to the server *
192**                                                                             *
193**      OUPUT variable :                                                       *
194**          logmessage :  to write the error message in case of error          *
195**                                                                             *
196**      GLOBAL VARIABLE USED :                                                 *                                                                      *
197**                                                                             *
198**      RETURN:                                                                *
199**          -1  Unrecoverable error                                            *
200**           0  OK                                                             *
201**                                                                             *
202*******************************************************************************/
203int bbftpd_private_send(char *buffertosend, int buffertosendlength, char *logmessage)
204{
205    int     lenrsa ;
206    int     nbpackets ;
207    char    minbuffer[MINMESSLEN] ;
208    struct  message     *msg ;
209    struct  mess_private    *msg_private ;
210    char    privatebuffer[PRIVRSAMESSLEN] ;
211    char    *strtocrypt ;
212    int     lentocrypt ;
213    int     i ;
214   
215    /*
216    ** Minimum check
217    */
218    if ( buffertosendlength <=0 ) {
219        sprintf(logmessage,"buffertosendlength has to be > 0") ;
220        return -1 ;
221    } 
222    /*
223    ** First get the RSA length
224    */
225    lenrsa = RSA_size(hisrsa) ;
226    /*
227    ** Calculate the number of encrypted packets
228    ** we are going to send
229    */
230    nbpackets = buffertosendlength/(lenrsa - 42) ;
231    if (  buffertosendlength - (nbpackets*(lenrsa - 42)) != 0 ) nbpackets++ ;
232    /*
233    ** So the total length to send is nbpackets*PRIVRSAMESSLEN+MINMESSLEN
234    */
235    msg = (struct message *)minbuffer ;
236    msg->code = MSG_PRIV_DATA ;
237#ifndef WORDS_BIGENDIAN
238    msg->msglen = ntohl(nbpackets*PRIVRSAMESSLEN) ;
239#else
240    msg->msglen = nbpackets*PRIVRSAMESSLEN ;
241#endif
242    if ( writemessage(outcontrolsock,minbuffer,MINMESSLEN,recvcontrolto) < 0) {
243        sprintf(logmessage,"Error sending data") ;
244        return -1 ;
245    }
246    /*
247    ** loop on packets
248    */
249    msg_private = ( struct mess_private *) privatebuffer ;
250    strtocrypt = buffertosend ;
251    lentocrypt = lenrsa - 42 ;
252    for (i=1; i<= nbpackets ; i++ ) {
253        if ( i == nbpackets ) {
254            lentocrypt = buffertosendlength - ((nbpackets-1)*(lenrsa - 42)) ;
255        }
256        if ( (msg_private->lengthdata = RSA_public_encrypt(lentocrypt,(unsigned char *)strtocrypt,msg_private->cryptdata,hisrsa,RSA_PKCS1_OAEP_PADDING)) < 0 ) {
257            sprintf(logmessage,"Error crypting message : %s ",(char *) ERR_error_string(ERR_get_error(),NULL)) ;
258            return -1 ;
259        }
260#ifndef WORDS_BIGENDIAN
261        msg_private->lengthdata = ntohl(msg_private->lengthdata) ;
262#endif
263        if ( writemessage(outcontrolsock,privatebuffer,PRIVRSAMESSLEN,recvcontrolto) < 0) {
264            sprintf(logmessage,"Error sending encrypted data") ;
265            return -1 ;
266        }
267        strtocrypt = strtocrypt + lentocrypt ;
268    }
269    return 0 ;
270}
271/*******************************************************************************
272** bbftpd_private_recv :                                                       *
273**                                                                             *
274**      This routine is going get a message, decrypt it and fill the buffer    *
275**                                                                             *
276**      OUPUT variable :                                                       *
277**          logmessage :  to write the error message in case of error          *
278**                                                                             *
279**      GLOBAL VARIABLE USED :                                                 *                                                                      *
280**                                                                             *
281**      RETURN:                                                                *
282**          -1  Unrecoverable error                                            *
283**           >0 Number of bytes received                                       *
284**                                                                             *
285*******************************************************************************/
286int bbftpd_private_recv(char *buffertorecv, int lengthtorecv, char *logmessage)
287{
288    char    minbuffer[MINMESSLEN] ;
289    struct  message     *msg ;
290    struct  mess_private    *msg_private ;
291    char    privatebuffer[PRIVRSAMESSLEN] ;
292    char    tempbuffer[PRIVRSAMESSLEN] ;
293    int     code ;
294    int     msglen ;
295    int     expectedpackets ;
296    int      i ;
297    int     lentodecrypt ;
298    int     lendecrypted, totallendecrypted ;
299    char    *tostore ;
300
301    totallendecrypted = 0 ;
302    tostore = buffertorecv ;
303    /*
304    ** Now wait for the MSG_PRIV_DATA
305    */
306    if ( readmessage(incontrolsock,minbuffer,MINMESSLEN,recvcontrolto) < 0 ) {
307        sprintf(logmessage,"Error reading data ") ;
308        return -1 ;
309    }
310    msg = (struct message *) minbuffer ;
311    code = msg->code ;
312    if (  code != MSG_PRIV_DATA ) {
313        sprintf(logmessage,"Incorrect message header") ;
314        return -1 ;
315    } 
316#ifndef WORDS_BIGENDIAN
317    msglen = ntohl(msg->msglen) ;
318#else
319    msglen = msg->msglen ;
320#endif
321    expectedpackets = msglen/PRIVRSAMESSLEN ;
322    if ( msglen != (PRIVRSAMESSLEN * expectedpackets ) ) {
323        sprintf(logmessage,"Incorrect message length ") ;
324        return -1 ;
325    }
326    msg_private = (struct  mess_private *) privatebuffer ;
327    for ( i = 1 ; i <= expectedpackets ; i++ ) {
328        if ( readmessage(incontrolsock,privatebuffer,PRIVRSAMESSLEN,recvcontrolto) < 0 ) {
329            sprintf(logmessage,"Error reading encrypted data") ;
330            return -1 ;
331        }
332#ifndef WORDS_BIGENDIAN
333        lentodecrypt = ntohl(msg_private->lengthdata) ;
334#else
335        lentodecrypt = msg_private->lengthdata ;
336#endif
337        lendecrypted = RSA_private_decrypt(lentodecrypt,msg_private->cryptdata,(unsigned char *)tempbuffer,myrsa,RSA_PKCS1_OAEP_PADDING) ;
338        if ( totallendecrypted + lendecrypted > lengthtorecv) {
339            sprintf(logmessage,"Too much data (max=%d, receive=%d)",lengthtorecv,totallendecrypted+lendecrypted) ;
340            return -1;
341        }
342        memcpy(tostore,tempbuffer,lendecrypted) ;
343        tostore =  tostore + lendecrypted ;
344        totallendecrypted = totallendecrypted + lendecrypted ;
345    }
346    buffertorecv[totallendecrypted] = '\0' ;
347    return totallendecrypted ;
348}
349
Note: See TracBrowser for help on using the repository browser.