Reputation: 1085
When I just run my program:ns-server everytime, it will show me that it decrypts message fail, but when I use valgrind try to find why this error happens, it works fine. Every time when I use valgrind to debug it, it works fine. the valgrind result is :
valgrind --leak-check=yes ./ns-server
==44887== Memcheck, a memory error detector
==44887== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==44887== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==44887== Command: ./ns-server
==44887==
first get nextlen 564
nextlen is 564
==44887== Thread 2:
==44887== Invalid read of size 1
==44887== at 0x6C49: strlen (vg_replace_strmem.c:427)
==44887== by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887== by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887== by 0x100025396: CkRsa::DecryptStringENC(char const*, bool, CkString&) (in ./ns-server)
==44887== by 0x1000130EA: My_RSA::MyDecryption(char*, CkString&) (RSAsample.cpp:52)
==44887== by 0x1000021C1: Server::Register(char*, int, char*) (Server.cpp:164)
==44887== by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887== by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== Address 0x100b3f150 is 0 bytes after a block of size 128 alloc'd
==44887== at 0x47E1: malloc (vg_replace_malloc.c:300)
==44887== by 0x1000020F4: Server::Register(char*, int, char*) (Server.cpp:154)
==44887== by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887== by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==
This is part of the result. In this result, it mentions:
by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887== by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887== by 0x100025396: CkRsa::DecryptStringENC(char const*, bool, CkString&) (in ./ns-server)
But these 3 functions come from static library which I download them from http://www.chilkatsoft.com/refdoc/vcCkRsaRef.html does this mean the error actually happen in these functions? Why when I run with valgrind, my project can output the right result?When I run it without any debugging tool, it will output "decrypt fail". Valgrind will change something related to my program?
My code is as follows:
int main(int argc, const char * argv[])
{
Server myServer(SERVER_PORT);//initialize server's port num,set up socket
myServer.Start();
return 0;
}
int Server::Start()
{
send_public_key server_pub_key;
server_pub_key.heads.random=random()%10;
server_pub_key.heads.request_type=PUBLICKEY;
server_pub_key.heads.length=sizeof(send_public_key);
strcpy(server_pub_key.pubkey,server_rsa.publickey);
TCPServer.SetupListen(PortListen,Evaluate_MSG,"",0,PUBLICKEY,(char *)&server_pub_key,server_pub_key.heads.length);
return 0;
}
int TCPConnect::SetupListen(int port, void * trifunc(void *),char * refuseMSG,int refuseLen,int pub,char *msg,int length)
{
if((mi_SocketToListen=socket(AF_INET,SOCK_STREAM,0))==-1)
{
printf("create socket failed\n");
return errno;
}
struct sockaddr_in ts_SocketAddrToListen;
ts_SocketAddrToListen.sin_addr.s_addr=INADDR_ANY;
SetupSocketAddrToTarget(NULL, port, ts_SocketAddrToListen,1);
if( bind(mi_SocketToListen,(struct sockaddr *)&ts_SocketAddrToListen,sizeof(struct sockaddr)) == -1)
{
printf("establish socket failed!\n");
return errno;
}
if(listen(mi_SocketToListen,99)==-1)
{
printf("listen failed\n");
return errno;
}
while (1)
{
int ti_sockfd;
struct sockaddr_in ts_sockaddr;
socklen_t ti_size = sizeof(struct sockaddr_in);
if((ti_sockfd=accept(mi_SocketToListen,(struct sockaddr *)&ts_sockaddr,&ti_size))==-1)
{
printf("accept user failed\n");
return errno;
}
if (threadlist.size() < mi_MaxConnection)
{
if(pub==80)//if this needs me to send a public key immediately afther i accept it
{
SendMsg(ti_sockfd, msg,length);
}
mm_clients.insert(std::pair<int,struct sockaddr_in>(ti_sockfd,ts_sockaddr));
pthread_t tp_threadfd;
pthread_create(&tp_threadfd,NULL,trifunc,(void *)&ti_sockfd);
threadlist.push_back(tp_threadfd);
}
else
{
SendMsg(ti_sockfd, refuseMSG, refuseLen);
CloseConnect(ti_sockfd,NULL);
}
}
return 0;
};
void * Server::Evaluate_MSG(void *arg)
{
int socketfd = *((int *) arg);
header checkheader;
int err;
while (true)
{
err = 0;
char * msg;
char *ip;
ip=(char *)malloc(sizeof(char)*INET_ADDRSTRLEN);
memset(ip,0,sizeof(char)*INET_ADDRSTRLEN);
int nextlen=Server::TCPServer.GetNextlen(socketfd);
msg=(char *)malloc(sizeof(char)*nextlen);
memset(msg,0,sizeof(char)*nextlen);
msg=Server::TCPServer.Receive(socketfd, nextlen);
//Server::TCPServer.Receive(socketfd,msg);
struct sockaddr_in sender_ip;
memset(&sender_ip,0,sizeof(struct sockaddr_in));
sender_ip=Server::TCPServer.GetInfoBySocket(socketfd);
inet_ntop(AF_INET,&sender_ip.sin_addr,ip,INET_ADDRSTRLEN);
memset(&checkheader,0,sizeof(header));
memcpy(&checkheader,msg,sizeof(header));
switch(checkheader.request_type)
{
case REGISTER:
err = Register(msg, socketfd,ip);
break;
case LOGIN:
err=Login(msg, socketfd,ip);
break;
default:
break;
}
free(ip);
free(msg);
if (err<0)
{
cout<<"error!"<<endl;
pthread_exit(0);
}
}
}
int Server::Register(char *msg,int sockfd,char *ip)
{
request_register reg;
memset(®,0,sizeof(request_register));
memcpy(®,msg,sizeof(request_register));
if(reg.real_pass!=REAL_PASS)
{
//ignore
}
else
{
send_user_success success_err;
success_err.heads.random=random()%10;
success_err.heads.length=sizeof(success_err);
CkString user_name_outData;
char *recv_username;
recv_username=(char *)malloc(sizeof(char)*LENGTH_CIPHERTEXT);
memset(recv_username,0,sizeof(char)*LENGTH_CIPHERTEXT);
memcpy(recv_username,reg.username,sizeof(char)*LENGTH_CIPHERTEXT);
server_rsa.MyDecryption(recv_username,user_name_outData);
//it decrypt fails
cout<<"after returning:"<<user_name_outData.getString()<<endl;
-------------------Above is part of function of Register(), it is too long, I just post part of it----------------
bool My_RSA::MyDecryption(char *ciphertext,CkString &outData)
{
rsaDecryptor.put_EncodingMode("hex");
rsaDecryptor.ImportPrivateKey(privatekey);
bool userPrivateKey;
userPrivateKey=true;
const char *cipher;
cipher=ciphertext;
const char * decryptedStr ;
decryptedStr= new char[SAY_MAX];
memset((char *)decryptedStr,0,sizeof(char)*SAY_MAX);
bool test=(char *) rsaDecryptor.DecryptStringENC(ciphertext, userPrivateKey, outData);//(decryptedStr, userPrivateKey);
if (!test) {
cout<<"decrypt failed"<<endl;
return false;
}
return true;
}
The error is: it will shows "decrypt failed" when I run without any debug tool, but it will decrypt definitely with valgrind. This is header(part):
static std::map <string,struct user_info> user_info_map;//string is user's name
static My_RSA server_rsa;
class Server
{
public:
Server(int p);
protected:
static TCPConnect TCPServer;
public:
int PortListen;
protected:
static int Register(char *msg,int sockfd,char *ip);
static int Login(char *msg,int sockfd,char *ip);
static int Lock_Un_Out(char *msg,int sockfd,int lock_unlock);
static int Check_User(int sockfd);
static int Send_User(char *msg,int sockfd);
static int Update(char *msg,int sockfd);
public:
int Start();
static void * Evaluate_MSG(void *arg);
};
The error is part is that it decrypts fail, but I don't think it is related to the function of DecryptStringENC
because when I run it with valgrind or Xcode, it works fine frequently.
Upvotes: 0
Views: 135
Reputation: 1085
Now I see why an error happens. When I pass ciphertext into MyDecryption(char *ciphertext,CkString &outData)
I set the size of it is 128bytes(Because when I use strlen to see the ciphertext's size, it shows 128). But I sudden think about that maybe I should malloc ciphertext with size of 129 bytes because '/0' will be attached to a string. Then, problem solves!!!!!!!
Upvotes: 2