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

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

A python module which provides a function to start the daemon can be
built using the setup.py script. This method of invoking the server
has been briefly tested but no test cases yet.

I've taken out the initialisation/finalisation hooks from the auth API because
we shouldn't need them now. They were written assuming the python interpretter
was going to be embedded within bbftpd, but I've inverted the embedding by
wrapping bbftpd.c:main in a python extension function.

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