|
Re: segmentation error while using mpz_powm in a loop
Actually it is a milter which decrypts the incoming mail messages...
/* sample_milter - example mail filter module
**
** Copyright © 2004 by Jef Poskanzer .
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
** For commentary on this license please see [url]http://www.acme.com/license.html[/url]
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "libmilter/mfapi.h"
//////////////////////////////////////////////////////////////
#include "gmp.h"
/* Forwards. */
static void usage( void );
static sfsistat sample_connect( SMFICTX* ctx, char* connhost, _SOCK_ADDR* connaddr );
static sfsistat sample_helo( SMFICTX* ctx, char* helohost );
static sfsistat sample_envfrom( SMFICTX* ctx, char** fromargs );
static sfsistat sample_envrcpt( SMFICTX* ctx, char** rcptargs );
static sfsistat sample_header( SMFICTX* ctx, char* name, char* value );
static sfsistat sample_eoh( SMFICTX* ctx );
static sfsistat sample_body( SMFICTX* ctx, unsigned char* bytes, size_t len );
static sfsistat sample_eom( SMFICTX* ctx );
static sfsistat sample_abort( SMFICTX* ctx );
static sfsistat sample_close( SMFICTX* ctx );
static void thread_data_destructor( void* data );
////////////////////////////////////////////////////////////////////////////////////////////
int smfi_replacebody(
SMFICTX *ctx,
unsigned char *bodyp,
int bodylen
);
int smfi_chgheader(
SMFICTX *ctx,
char *name,
int hdridx,
char *value
);
////////////////////////////////////////////////////////////////////////////////////////////
/* Globals. */
static char* argv0;
static pthread_key_t key;
static int connections;
static char* data_buffer, *contentTypeBuffer;
//data_buffer=(char *) malloc(100);
void *ret; // This line is compulsory to get correct output
size_t size;
int flag=0;
GMimeMessage *message;
GMimeStream *stream;
GMimeParser *parser;
GMimeMultipart *multipart;
GMimePart *mime_part,*mime_part0;
GMimeContentType *contentType,*contentType1;
static struct smfiDesc smfilter =
{
"SAMPLE", /* filter name */
SMFI_VERSION, /* version code -- do not change */
SMFIF_CHGBODY | SMFIF_CHGHDRS, /* flags */
sample_connect, /* connection info filter */
sample_helo, /* SMTP HELO command filter */
sample_envfrom, /* envelope sender filter */
sample_envrcpt, /* envelope recipient filter */
sample_header, /* header filter */
sample_eoh, /* end of header */
sample_body, /* body block filter */
sample_eom, /* end of message */
sample_abort, /* message aborted */
sample_close /* connection cleanup */
};
int
main( int argc, char** argv )
{
char* sockarg;
////////////////////////////////////////////
/* init the gmime library */
g_mime_init (0);
message = g_mime_message_new(FALSE);
/////////////////////////////////////////////
argv0 = strrchr( argv[0], '/' );
if ( argv0 != (char*) 0 )
++argv0;
else
argv0 = argv[0];
connections = 0;
if ( argc != 2 )
usage();
sockarg = argv[1];
if ( pthread_key_create( &key, &thread_data_destructor ) )
{
perror( "pthread_key_create" );
exit( 1 );
}
openlog( argv0, 0, LOG_MAIL );
(void) smfi_setconn( sockarg );
if ( smfi_register( smfilter ) == MI_FAILURE )
{
(void) fprintf( stderr, "%s: register failed\n", argv0 );
exit( 1 );
}
if ( smfi_main() == MI_FAILURE )
{
(void) fprintf( stderr, "%s: milter failed\n", argv0 );
exit( 1 );
}
syslog( LOG_INFO, "exitting - %d connections", connections );
(void) pthread_key_delete( key );
closelog();
exit( 0 );
}
static void
usage( void )
{
(void) fprintf( stderr, "usage: %s socket\n", argv0 );
exit( 1 );
}
/* The filter routines. These can return the following values:
**
** SMFIS_CONTINUE Continue processing the current connection, message,
** or recipient.
** SMFIS_REJECT For a connection-oriented routine, reject this
** connection; call xxfi_close.
** For a recipient-oriented routine, reject the current
** recipient (but continue processing the current message).
** For a message-oriented routine (except xxfi_eom or
** xxfi_abort), reject this message.
** SMFIS_DISCARD For a message- or recipient-oriented routine, accept
** this message, but silently discard it.
** This should not be returned by a connection-oriented
** routine.
** SMFIS_ACCEPT For a connection-oriented routine, accept this
** connection without further filter processing;
** call xxfi_close.
** For a message- or recipient-oriented routine, accept
** this message without further filtering.
** SMFIS_TEMPFAIL Return a temporary failure, i.e. the corresponding
** SMTP command will return an appropriate 4xx status
** code.
** For a connection-oriented routine, fail for this
** connection; call xxfi_close.
** For a recipient-oriented routine, only fail for the
** current recipient; continue message processing.
** For a message-oriented routine (except xxfi_envfrom),
** fail for this message.
**
** The milter API is fully documented here:
** [url]http://www.milter.org/milter_api/[/url]
**
** The sequence of callbacks is as follows:
**
** The SMTP connection is accepted - sample_connect()
** The client sends a HELO/EHLO command - sample_helo()
** For each message:
** The client sends a MAIL FROM command - sample_envfrom()
** The client sends one or more RCPT TO commands - sample_envrcpt()
** The client sends a DATA command.
** The client sends one or more headers - sample_header()
** The client sends a blank line - sample_eoh()
** The client sends the message body - zero or more calls to sample_body()
** The client sends a dot - sample_eom()
** The client sends a QUIT command - sample_close().
*/
/* Per-thread data structure. */
struct thread_data {
int junk;
};
/* Per-connection data structure. */
struct connection_data {
int connection_num;
int messages;
int recipients;
int headers;
int bodyblocks;
size_t bodybytes;
int aborts;
};
/* sample_connect - handle the initial TCP connection
**
** Called at the start of a connection. Any per-connection data should
** be initialized here.
**
** connhost: The hostname of the client, based on a reverse lookup.
** connaddr: The client's IP address, based on getpeername().
*/
static sfsistat
sample_connect( SMFICTX* ctx, char* connhost, _SOCK_ADDR* connaddr )
{
struct thread_data* td;
struct connection_data* cd;
struct sockaddr_in* sin;
td = (struct thread_data*) pthread_getspecific( key );
if ( td == (struct thread_data*) 0 )
{
td = (struct thread_data*) malloc( sizeof(struct thread_data) );
if ( td == (struct thread_data*) 0 )
return SMFIS_TEMPFAIL;
if ( pthread_setspecific( key, (void*) td ) )
{
free( (void*) td );
return SMFIS_TEMPFAIL;
}
}
cd = (struct connection_data*) malloc( sizeof(struct connection_data) );
if ( cd == (struct connection_data*) 0 )
return SMFIS_TEMPFAIL;
(void) smfi_setpriv( ctx, (void*) cd );
cd->connection_num = ++connections;
sin = (struct sockaddr_in*) connaddr;
syslog( LOG_INFO, "conn# %d - sample_connect( \"%s\" [%s] )", cd->connection_num, connhost, inet_ntoa( sin->sin_addr ) );
cd->messages = 0;
cd->aborts = 0;
return SMFIS_CONTINUE;
}
/* sample_helo - handle the MAIL HELO
**
** Called at the start of a connection.
**
** helohost: The string passed to the HELO/EHLO command.
*/
static sfsistat
sample_helo( SMFICTX* ctx, char* helohost )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_helo( \"%s\" )", cd->connection_num, helohost );
return SMFIS_CONTINUE;
}
/* sample_envfrom - handle the MAIL FROM:<> command
**
** Called at the start of each message. There may be multiple messages
** in a connection. Any per-message data should be initialized here.
**
** The sender address is also known as the "envelope from" address.
**
** fromargs: Null-terminated SMTP command arguments; fromargs[0] is the
** sender address.
*/
static sfsistat
sample_envfrom( SMFICTX* ctx, char** fromargs )
{
data_buffer=(char*)malloc(100000000);
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_envfrom( \"%s\" )", cd->connection_num, fromargs[0] );
/* if(fromargs[0]!="")
{
return SMFIS_REJECT;
}
*/
++cd->messages;
cd->recipients = 0;
cd->headers = 0;
cd->bodyblocks = 0;
cd->bodybytes = 0;
return SMFIS_CONTINUE;
}
/* sample_envrcpt - handle a RCPT TO:<> command
**
** Called separately for each recipient of a message.
**
** rcptargs: Null-terminated SMTP command arguments; rcptargs[0] is the
** recipient address.
*/
static sfsistat
sample_envrcpt( SMFICTX* ctx, char** rcptargs )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_envrcpt( \"%s\" )", cd->connection_num, rcptargs[0] );
++cd->recipients;
return SMFIS_CONTINUE;
}
/* sample_header - handle a header line
**
** Called separately for each header line in a message.
**
** name: Header field name.
** value: Header vield value, including folded whitespace. The final CRLF
** is removed.
*/
static sfsistat
sample_header( SMFICTX* ctx, char* name, char* value )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_header( \"%s\", \"%s\" )", cd->connection_num, name, value );
++cd->headers;
return SMFIS_CONTINUE;
}
/* sample_eoh - handle the end of the headers
**
** Called once per message after all headers have been processed.
*/
static sfsistat
sample_eoh( SMFICTX* ctx )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_eoh()", cd->connection_num );
return SMFIS_CONTINUE;
}
/* sample_body - handle a block of body bytes
**
** The body of the message is filtered via zero or more calls to this
** routine. Most messages are handled with a single body call, but
** some do take more than one.
**
** bytes: Pointer to the block of body data.
** len: Length of the block.
*/
static sfsistat
sample_body( SMFICTX* ctx, unsigned char* bytes, size_t len )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
strncat(data_buffer, bytes, len);
//syslog( LOG_INFO, "conn# %d - sample_body( %d ) length= %d sample body(%s)", cd->connection_num, flag,strlen(data_buffer), bytes );
//flag=flag+1;
++cd->bodyblocks;
cd->bodybytes += len;
return SMFIS_CONTINUE;
}
/* sample_eom - handle the end of the message
**
** Called once per message after all bod y blocks have been processed.
** Any per-message data should be freed both here and in sample_abort().
*/
static sfsistat
sample_eom( SMFICTX* ctx )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_eom(), %d recipients, %d headers, %d bodyblocks with %d bytes", cd->connection_num, cd->recipients, cd->headers, cd->bodyblocks, (int) cd->bodybytes );
//syslog( LOG_INFO, "conn# %d - sample_body( %d ) length= %d sample body(%s)", cd->connection_num, flag,strlen(data_buffer), data_buffer );
/***Retrieving the body of the message which is the
****actual required message to be decrypted
***/
/* create the parts' content stream */
stream = g_mime_stream_mem_new_with_buffer (data_buffer, strlen(data_buffer) );
/* create a new parser object to parse the stream */
parser = g_mime_parser_new_with_stream (stream);
/* unref the stream (parser owns a ref, so this object does not actually get free'd until we destroy the parser) */
g_object_unref (stream);
/* parse the message from the stream */
message = g_mime_parser_construct_message (parser);
/* free the parser (and the stream) */
g_object_unref (parser);
gboolean *is_html;
//const char *content;
//content=(char*)malloc(10000000);
const char *content = g_mime_message_get_body ( message , FALSE , is_html);
//free(data_buffer);
strncpy(data_buffer,content,strlen(content));
//*(data_buffer+strlen(content))='\0';
/****************************Decrypting the message**********************************************************************/
syslog( LOG_INFO, "conn# %d - body = %s", cd->connection_num, content );
int noOfBlocks = strlen(data_buffer)/308;
syslog( LOG_INFO, "conn# %d - body = %d no of blocks = %d", cd->connection_num, strlen(data_buffer), noOfBlocks );
mpz_t bigbody,encbody,decbody,n,d,e;
mpz_init_set_str (e, "5", 10);
mpz_init_set_str (n, "81072118814004638617775947138239917744589505176471539666269773100315781097546894455560658571445286325125766632676152452856383447352821337178984474781813475276075048299705214136395672502245955793627681061360075723595075874516950614187016991430293887968216015097675955399134514678660046996064181098182893072761", 10);
mpz_init_set_str (d, "32428847525601855447110378855295967097835802070588615866507909240126312439018757782224263428578114530050306653070460981142553378941128534871593789912725382636961637010791821646038659077539848411532121133465246631106852802485583932352673149866783600963924490576147444236696494852521901563664557493382382127469", 10);
char *STR;
STR=(char*)malloc(1000);
//mpz_init(bigbody);
//mpz_init(decbody);
mpz_t array[10];
mpz_array_init (array, 10, 308);
mpz_t array1[10];
mpz_array_init (array1, 10, 100000);
char substring[400];
int i=0,lower=0,upper=308;
while(i
{
syslog( LOG_INFO, "conn# %d - i = %d", cd->connection_num, i );
strncpy(substring, data_buffer + lower, upper);
*(substring+308)='\0';
syslog( LOG_INFO, "conn# %d - substring = %s", cd->connection_num, substring );
lower=upper;
upper=upper+308;
//mpz_init_set_str(bigbody,substring,10);
mpz_init_set_str(array[i],substring,10);
//size=len;
//mpz_get_str (STR, 10, bigbody);
mpz_get_str (STR, 10, array[i]);
strcat(STR,"\0");
syslog( LOG_INFO, "conn# %d - Encrypted-Biginteger = %s", cd->connection_num, STR );
/* mpz_get_str (STR, 10, d);
strcat(STR,"\0");
syslog( LOG_INFO, "conn# %d - d = %s", cd->connection_num, STR );
mpz_get_str (STR, 10, n);
strcat(STR,"\0");
syslog( LOG_INFO, "conn# %d - n = %s", cd->connection_num, STR );
*/
//fflush(stdin);
//array1[i]=(mpz_t)malloc(400);
//mpz_init_set_str(array1[i],"0",10);
//mpz_init(decbody);
//mpz_powm (decbody, bigbody, d, n);
mpz_init(array1[i]);
mpz_powm (array1[i], array[i], d, n);
//char *decSTR;
//decSTR=(char*)malloc(1000);
//mpz_get_str (STR, 10, decbody);
mpz_get_str (STR, 10, array1[i]);
syslog( LOG_INFO, "conn# %d - Decrypted-Biginteger = %s", cd->connection_num, STR );
size_t length;
void *ret;
char *decrypted;
decrypted=(char*)malloc(1000);
ret=mpz_export (decrypted, &length, 1,sizeof(data_buffer[0]), 0, 0, array1[i]);
//ret=mpz_export (decrypted, &length, 1,sizeof(data_buffer[0]), 0, 0, array1[i]);
strncpy(decrypted,ret,length);
*(decrypted+length)='\0';
syslog( LOG_INFO, "conn# %d - size decrypted = %d Decrypted = %s", cd->connection_num,length, (char *)ret );
fflush(stdout);
//free(STR);
//free(decSTR);
free(decrypted);
//mpz_clear(bigbody);
//mpz_clear(decbody);
fflush(stdin);
fflush(stdout);
//mpz_clear(array[i]);
//mpz_clear(array1[i]);
i++;
}
/*
mpz_t bigbody,encbody,decbody,n,d,e;
mpz_init(bigbody);
mpz_init_set_str (e, "5", 10);
mpz_init_set_str (n, "81072118814004638617775947138239917744589505176471539666269773100315781097546894455560658571445286325125766632676152452856383447352821337178984474781813475276075048299705214136395672502245955793627681061360075723595075874516950614187016991430293887968216015097675955399134514678660046996064181098182893072761", 10);
mpz_init_set_str (d, "32428847525601855447110378855295967097835802070588615866507909240126312439018757782224263428578114530050306653070460981142553378941128534871593789912725382636961637010791821646038659077539848411532121133465246631106852802485583932352673149866783600963924490576147444236696494852521901563664557493382382127469", 10);
char substring[400];
//substring = (char*)malloc(400);
int i=0,lower=0,upper=308;
//for(i=0;i<2;i++)
//{
strncpy(substring, data_buffer + lower, upper);
*(substring+308)='\0';
syslog( LOG_INFO, "conn# %d - substring = %s", cd->connection_num, substring );
lower=upper;
upper=upper+308;
i++;
//mpz_import (bigbody, len-2, 1, sizeof(data_buffer[0]), 0, 0, data_buffer);
mpz_set_str(bigbody,substring,10);
//size=len;
char *STR;
STR=(char*)malloc(1000);
mpz_get_str (STR, 10, bigbody);
strcat(STR,"\0");
syslog( LOG_INFO, "conn# %d - Encrypted-Biginteger = %s", cd->connection_num, STR );
mpz_powm (decbody, bigbody, d, n);
mpz_get_str (STR, 10, decbody);
syslog( LOG_INFO, "conn# %d - Decrypted-Biginteger = %s", cd->connection_num, STR );
size_t length;
void *ret;
char *decrypted;
decrypted=(char*)malloc(1000);
ret=mpz_export (decrypted, &length, 1,sizeof(data_buffer[0]), 0, 0, decbody);
strncpy(decrypted,ret,length);
*(decrypted+length)='\0';
syslog( LOG_INFO, "conn# %d - size decrypted = %d Decrypted = %s", cd->connection_num,length, (char *)ret );
fflush(stdout);
free(decrypted);
//}
/************************Retrieving the content-Type of the actual message***********************/
/*
// free the message //
g_object_unref (message);
// create the parts' content stream //
stream = g_mime_stream_mem_new_with_buffer (content, strlen(content));
// create a new parser object to parse the stream //
parser = g_mime_parser_new_with_stream (stream);
// unref the stream (parser owns a ref, so this object does not actually get free'd until we destroy the parser) //
g_object_unref (stream);
// parse the message from the stream //
message = g_mime_parser_construct_message (parser);
// free the parser (and the stream) //
g_object_unref (parser);
multipart = g_mime_message_get_mime_part ( message );
contentType = g_mime_object_get_content_type ((GMimeObject *)multipart);
content = g_mime_content_type_to_string (contentType);
contentTypeBuffer = (char *)malloc(10000000);
strcat(contentTypeBuffer, content);
strcat(contentTypeBuffer, "; \n\tboundary=\"");
content = g_mime_content_type_get_parameter (contentType , "boundary");
syslog( LOG_INFO, "conn# %d - boundary = %s", cd->connection_num, content );
strcat(contentTypeBuffer, content );
fflush(stdout);
strcat(contentTypeBuffer, "\" ");
//free(data_buffer);
/***************************REPLACING THE CONTENT-TYPE HEADER**********************************/
/*
char *name = "Content-Type";
if( smfi_chgheader( ctx, name, 1, contentTypeBuffer) == MI_FAILURE)
{
syslog( LOG_INFO, "MI_FAILURE");
}
/***************************REPLACING WITH DECRYPTED BODY*************************************/
/*
fflush(stdout);
if(smfi_replacebody(ctx, data_buffer, strlen(data_buffer) )== MI_FAILURE)
{
syslog( LOG_INFO, "MI_FAILURE");
}
free(data_buffer);
/*********************************************************************************************/
return SMFIS_CONTINUE;
}
/* sample_abort - handle the message being aborted
**
** May be called at any time during processing of a message, indicating
** that something went wrong. Any per-message data should be freed both
** here and in sample_eom().
*/
static sfsistat
sample_abort( SMFICTX* ctx )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_abort(), %d recipients, %d headers, %d bodyblocks with %d bytes", cd->connection_num, cd->recipients, cd->headers, cd->bodyblocks, (int) cd->bodybytes );
return SMFIS_CONTINUE;
}
/* sample_close - handle the connection being closed
**
** Called once at the end of a connection. Any per-connection data
** should be freed here.
*/
static sfsistat
sample_close( SMFICTX* ctx )
{
struct connection_data* cd = (struct connection_data*) smfi_getpriv( ctx );
syslog( LOG_INFO, "conn# %d - sample_close(), %d messages", cd->connection_num, cd->messages );
if ( cd != (struct connection_data*) 0 )
{
(void) smfi_setpriv( ctx, (void*) 0 );
free( (void*) cd );
}
return SMFIS_CONTINUE;
}
static void
thread_data_destructor( void* data )
{
struct thread_data* td = (struct thread_data*) data;
free( (void*) td );
}
The program is showing segmentaion fault at mpz_powm()
Last edited by LuciWiz : 09-May-2009 at 07:50.
Reason: Please insert your C code between [cpp] & [/cpp] tags
|