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

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

More missing #includes exposed when compiling on easterly.

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