bool CRemoteControl::ReadPacket(CIrssMessage &message) { try { char sizebuf[4]; int iRead = ReadN(&sizebuf[0], 4); if (iRead <= 0) return false; //nothing to read if (iRead != 4) { CLog::Log(LOGERROR, "IRServerSuite: failed to read packetsize."); return false; } uint32_t size = 0; memcpy(&size, &sizebuf[0], 4); size = ntohl(size); char* messagebytes = new char[size]; if (ReadN(messagebytes, size) != size) { CLog::Log(LOGERROR, "IRServerSuite: failed to read packet."); return false; } if (!CIrssMessage::FromBytes(messagebytes, size, message)) { CLog::Log(LOGERROR, "IRServerSuite: invalid packet received (size: %u).", size); return false; } delete[] messagebytes; return true; } catch(...) { CLog::Log(LOGERROR, "IRServerSuite: exception while processing packet."); return false; } }
char *ReadAll(const WCHAR *filePath, size_t *fileSizeOut, Allocator *allocator) { int64 size64 = GetSize(filePath); if (size64 < 0) return NULL; size_t size = (size_t)size64; #ifdef _WIN64 CrashIf(size != (size_t)size64); #else if (size != size64) return NULL; #endif // overflow check if (size + sizeof(WCHAR) < sizeof(WCHAR)) return NULL; /* allocate one character more and zero-terminate just in case it's a text file we'll want to treat as C string. Doesn't hurt for binary files (note: two byte terminator for UTF-16 files) */ char *data = (char *)Allocator::Alloc(allocator, size + sizeof(WCHAR)); if (!data) return NULL; if (!ReadN(filePath, data, size)) { Allocator::Free(allocator, data); return NULL; } // zero-terminate for convenience data[size] = data[size + 1] = '\0'; if (fileSizeOut) *fileSizeOut = size; return data; }
// return true if a file starts with string s of size len bool StartsWithN(const WCHAR *filePath, const char *s, size_t len) { ScopedMem<char> buf(AllocArray<char>(len)); if (!buf) return false; if (!ReadN(filePath, buf, len)) return false; return memeq(buf, s, len); }
void RobotGame::messageArrived (int) { int length, result = ReadN(pipeEnd, (char*)&length, sizeof(int)); if (result <= 0) { QObject::disconnect(socketNotifier, SIGNAL(activated(int)), this, SLOT(messageArrived(int))); if (tick % updateSpeed != 0) updateWithMessage(); }
/* *功能: 收数据(一直收满nBytes字节为止,或者出错为止,或者超时为止) *输入参数: unsigned int &nBytes:缓冲区的长度 int timeout: 超时的毫秒数(1秒=1000毫秒) -1表阻塞式接收 0:不可收时立即返回,不等待 >0:不可收时等待至超时 int flags:标志 *输出参数: char *chBuffer:缓冲区中包含已收到的数据 *返回值: -2:timeout -1:失败,具体错误可以通过GetLastError()获取 0:对方已关闭 >0:收完了所有数据 */ int CBaseSocket::RecvN(unsigned int &nread, void *pBuffer, unsigned int nBytes,int timeout /*= -1*/, int flags /*= 0*/) { if(m_iSocket < 0) { return -1; } nread = 0; if( timeout < 0) { return ReadN(nread, pBuffer, nBytes); } struct timeval start; struct timezone tz; gettimeofday(&start, &tz); unsigned int left = nBytes; int n = 0; char *ptr = (char *)pBuffer; while(1) { n = WaitRead(timeout); if(n < 0) //error { //if(errno == ETIMEO) return n; //timeout } n = recv(m_iSocket, ptr, left, flags); if( n < 0) { if(errno == EINTR) { continue; } return -1; //error } if(n == 0) { return 0; //closed by peer } left -= n; ptr += n; nread += n; if(left <= 0) { break; //ok } timeout -= DiffMillSec(start); if(timeout <= 0) //timeout { return -2; } } if(nread == nBytes) { return nread; } return -2; //timeout }
int DoWorkMultiplexed(int tapfd, int netfd) { int maxfd = 0; register int i = 0; unsigned char buffer[BUFSIZ]; char ip4[INET_ADDRSTRLEN]; size_t len = 0; fd_set rd_set; struct sockaddr_in from; ClientConf *Client; maxfd = (tapfd > netfd) ? tapfd : netfd; while (1) { Client = NULL; FD_ZERO(&rd_set); FD_SET(tapfd, &rd_set); FD_SET(netfd, &rd_set); if (select(maxfd + 1, &rd_set, NULL, NULL, NULL) < 0) { if (errno == EINTR) continue; else { fprintf(stderr, "DoWorkMultiplexed : select : %s\n", strerror(errno)); return -1; } } if (FD_ISSET(tapfd, &rd_set)) { if ((len = read(tapfd, buffer, BUFSIZ)) < 0) { fprintf(stderr, "DoWorkMultiplexed : read : %s\n", strerror(errno)); return -1; } printf("read from the tuntap [%d]\n", (int)len); SendToDestination(netfd, tapfd, buffer, len, NULL); } else if (FD_ISSET(netfd, &rd_set)) { printf("read from the network\n"); if ((len = ReadN(netfd, (struct sockaddr *)&from, buffer, BUFSIZ)) < 0) { fprintf(stderr, "DoWorkMultiplexed : ReadN : %s\n", strerror(errno)); return -1; } /* Get the source client's information */ for (i = 0; i < CurrentClients; i++) if (from.sin_addr.s_addr == Clients[i].ns.data.sin_addr.s_addr) { Client = Clients + i; printf("found: %s\n", Client->ns.ip); } /* If we have no client information, then try to authenticate it */ if (!Client) { if (!(Client = DoAuthenticateServer(netfd, &from))) { inet_ntop(AF_INET, &(from.sin_addr), ip4, INET_ADDRSTRLEN); fprintf(stdout, "Client [%s] rejected. Wrong credentials\n", ip4); } continue; } SendToDestination(netfd, tapfd, buffer, len, Client); } } return 0; }
ClientConf *DoAuthenticateServer(int net_fd, struct sockaddr_in *from) { ClientConf *Client = NULL; int dcr_size = 0, cr_size = 0, i = 0; char ConnectionID[MED_BUF]; unsigned char cr_buffer[BUFSIZ], dcr_buffer[BUFSIZ], orig_buffer[BUFSIZ], signature[MED_BUF]; unsigned int siglen = 0; memset(dcr_buffer, 0, sizeof(dcr_buffer)); memset(orig_buffer, 0, sizeof(orig_buffer)); /* Get the connection ID */ if ((i = ReadN(net_fd, (struct sockaddr *)from, (unsigned char *)ConnectionID, MED_BUF)) <= 0) { fprintf(stderr, "DoAuthenticateServer : ReadN\n"); return NULL; } ConnectionID[i] = '\0'; /* Load the client setup */ if ((Client = ReadClientConf(SrvSetup.cfgfile, ConnectionID)) == NULL) { fprintf(stderr, "DoAuthenticateServer : ReadClientConf\n"); return NULL; } if (LoadPublicKeyFromFile(Client->fpubkey, &(Client->pub), CLIENT_LOAD_SERVER_PUBLIC_KEYFILE_ERR)) { fprintf(stderr, "DoAuthenticateServer : LoadPublicKeyFromFile\n"); return NULL; } /* Create a random message, sign it, encrypt it and send it with its signature */ if (CreateRandomMessage(orig_buffer, MIN_BUF) < 0) { fprintf(stderr, "DoAuthenticateServer : CreateRandomMessage\n"); return NULL; } if (SignMessage(SrvSetup.priv, orig_buffer, MIN_BUF, signature, &siglen) < 0) { fprintf(stderr, "DoAuthenticateServer : SignMesage\n"); return NULL; } if (EncryptMessageWithPublicKey(Client->pub, orig_buffer, MIN_BUF, cr_buffer, &cr_size) < 0) { fprintf(stderr, "DoAuthenticateServer : EncryptMessageWithPublicKey\n"); return NULL; } if (WriteH(net_fd, (struct sockaddr *)from, cr_buffer, cr_size) < 0) { fprintf(stderr, "DoAuthenticateServer : WriteH\n"); return NULL; } if (WriteH(net_fd, (struct sockaddr *)from, signature, siglen) <= 0) { fprintf(stderr, "DoAuthenticateServer : WriteH\n"); return NULL; } /* Read the answer and decrypt it */ if ((cr_size = ReadN(net_fd, (struct sockaddr *)from, cr_buffer, BUFSIZ)) < 0) { fprintf(stderr, "DoAuthenticateServer : ReadN\n"); return NULL; } else if (cr_size == 0) { fprintf(stderr, "Authentication failed. Access denied!\n"); fprintf(stderr, "Disconnecting client\n"); return NULL; } if (DecryptMessageWithPrivateKey(SrvSetup.priv, cr_buffer, cr_size, dcr_buffer, &dcr_size)) { fprintf(stderr, "DoAuthenticateServer : DecryptMessageWithPrivateKey\n"); return NULL; } /* Check if the message is ok */ if (memcmp(orig_buffer, dcr_buffer, MIN_BUF)) { fprintf(stderr, "Access denied!\n"); return NULL; } /* Save the origin information in the client's structure */ memcpy(&(Client->ns.data), from, sizeof(struct sockaddr_in)); inet_aton(Client->ns.ip, &Client->ns.data.sin_addr); /* Create a key, arrange a network setup for the client and send it over */ if (CreateRandomKey(Client->PrivKey, KEYSIZE)) { fprintf(stderr, "DoAuthenticateServer : CreateRandomKey\n"); return NULL; } /*sprintf((char *)dcr_buffer, "key=%s,ip=%s,netmask=%s,broadcast=%s,mtu=%s", Client->PrivKey, Client->ns.ip, Client->ns.msk, Client->ns.brd, Client->ns.mtu);*/ memset(dcr_buffer, '\0', sizeof(dcr_buffer)); memcpy(dcr_buffer, "key=", 4); memcpy(dcr_buffer + 4, Client->PrivKey, KEYSIZE); sprintf((char *)dcr_buffer + 4 + KEYSIZE, ",ip=%s,netmask=%s,broadcast=%s", Client->ns.ip, Client->ns.msk, Client->ns.brd); dcr_size = 4 + KEYSIZE + strlen(((char *)dcr_buffer) + 4 + KEYSIZE); if (EncryptMessageWithPublicKey(Client->pub, dcr_buffer, dcr_size, cr_buffer, &cr_size) < 0) { fprintf(stderr, "DoAuthenticateServer : EncryptMessageWithPublicKey\n"); return NULL; } if (WriteH(net_fd, (struct sockaddr *)from, cr_buffer, cr_size) < 0) { fprintf(stderr, "DoAuthenticateServer : WriteH\n"); return NULL; } CryptoInit(&(Client->ctx), Client->PrivKey, &(Client->IV)); return Client; }