int tcp_setup_client(int family,const char *ipaddr,int port,tcp_con_t *con){ int rc; int sock=-1; struct sockaddr_in server; struct hostent *host; struct addrinfo *info=NULL; if ( (!ipaddr) || (!con) ) return -EINVAL; rc=setup_addr_info(&info, ipaddr,port,SOCK_STREAM,family); if (rc<0) return rc; sock=socket(info->ai_family, info->ai_socktype,info->ai_protocol); if (sock<0) { err_out("Can not create socket: %s(errno:%d)\n",strerror(errno),errno); rc=-errno; goto error_out; } #ifdef IPV6_V6ONLY if (info->ai_family == AF_INET6) { int v6only=1; rc=setsockopt(sock,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&v6only,sizeof(v6only)); if (rc) { goto error_out; } } #endif /* IPV6_V6ONLY */ if (connect(sock, info->ai_addr, info->ai_addrlen)<0){ err_out("Can not connect addr:%s port:%d %s (errno:%d)\n", ipaddr, port, strerror(errno), errno); rc=-errno; goto error_out; } rc = sock_set_buffer(sock, _TCP_BUF_MIN_SIZE, _TCP_BUF_SIZE); if (rc<0) { err_out("Can not set socket buffer: %s (%d)\n",strerror(errno),errno); return -errno; } /* 受信時はタイムアウト待ちを行うのでここでは, ノンブロックにしないこと */ con->soc=sock; con->family=info->ai_family; con->peer_info=info; return 0; error_out: if (info) freeaddrinfo(info); return rc; }
int main_deux(char **arr, int *list_a, int i, int j) { if (ft_validate(arr[i]) == 0) return (err_out(list_a)); list_a[j] = ft_atoi(arr[i]); if (ft_max_int(list_a[j], arr[i]) == 0) return (err_out(list_a)); return (1); }
static int send_header(tcp_con_t *con,const char *response){ int rc; size_t soc_remains; ssize_t send_len; char *wp; int buff_len; const char *peer_addr=NULL; struct sigaction saved_act; gchar *send_buffer = NULL; if ( (!con) || (!response) ) return -EINVAL; peer_addr = tcp_get_peeraddr(con); rc = ipmsg_convert_string_external(peer_addr, response, (const char **)&send_buffer); if (rc != 0) { ipmsg_err_dialog("%s\n", _("Can not convert header into external representation")); goto no_free_out; } soc_remains = strlen(send_buffer); if (wait_socket(con->soc, WAIT_FOR_WRITE, TCP_SELECT_SEC) < 0) { err_out("Can not send socket\n"); goto error_out; } wp=(char *)send_buffer; dbg_out("Send:%s(%d, %x)\n",wp,soc_remains,soc_remains); while(soc_remains>0) { disable_pipe_signal(&saved_act); send_len=send(con->soc,wp,soc_remains,0); enable_pipe_signal(&saved_act); if (send_len<0) { if (errno == EINTR) continue; rc=-errno; err_out("Error:%s (%d)\n",strerror(errno),errno); goto error_out; } wp += send_len; soc_remains -= send_len; dbg_out("soc remains:%d\n",soc_remains); } rc=0; error_out: if (send_buffer != NULL) g_free(send_buffer); no_free_out: return rc; }
/** 16進->10進変換を行う * @param[in] ch 16進数文字(0-9a-fA-F) * @param[out] index chの10進変換結果返却領域 * @retval 0 正常終了 * @retval -EINVAL 引数異常(indexがNULL, chが16進数文字でない) * @retval -ESRCH 変換できなかった(変換テーブル内に当該の文字がなかった) * @attention 内部リンケージ */ static int get_hexstr_index(const char ch, char *index){ int rc = 0; char ind = 0; int search_ch = 0; char *found = NULL; if ( (index == NULL) || ( !isxdigit(ch) ) ) { rc = -EINVAL; goto error_out; } search_ch = tolower((int)ch); found = strchr(hexstr, (int)search_ch); if (found == NULL) { err_out("Character %c(%c in original message) can not be found.\n", search_ch, ch); rc = -ESRCH; goto error_out; } ind = (char)(found - hexstr); /* 16進->10進変換 */ *index = ind; /* 値返却 */ rc = 0; /* 正常終了 */ error_out: return rc; }
VMS_MSG (int status) /* Routine to put out the VMS operating system error (if one occurs). */ { #include <descrip.h> char errstr[81], buf[120]; $DESCRIPTOR(errdesc, errstr); short length; #define err_out(msg) fprintf (stderr,msg) /* Check for no error or standard error */ if (~status & 1) { status = status & 0x8000 ? status & 0xFFFFFFF : status & 0xFFFF; if (SYS$GETMSG(status, &length, &errdesc, 1, 0) == SS$_NORMAL) { errstr[length] = '\0'; (void) sprintf(buf, "<0x%x> %s", status, errdesc.dsc$a_pointer); err_out(buf); } else err_out("System error"); } }
// ================================================================== void hatch::OnImportDiz() // ================================================================== { FILE *fp; CString desc; CString fname; char buf[1000]; char path[MAX_PATH]; char fpath[MAX_PATH]; int ret=0; m_filename.GetWindowText(fname); trim_all(fname); if (fname.GetLength()<2) ERR_MSG_RET("W_NOFFFD"); make_path(path,gc.BasePath,"_TMP"); make_path(fpath,path,"file_id.diz"); _mkdir(path); if (!extract_file(fname,path)) { err_out("E_EXTFAD",fname); ret=0; goto exit; } fp=fopen(fpath,"rt"); if (fp) { while (fgets(buf,999,fp)) desc+=buf; ret=1; fclose(fp); } exit: SafeFileDelete(path,FALSE); if (!ret) ERR_MSG_RET("W_NOFIDDF"); trim_all(desc); desc.Replace("\n"," "); desc.OemToAnsi(); m_description.SetWindowText(desc); }
int tcp_enable_keepalive(const tcp_con_t *con){ int rc; int flag; if (!con) return -EINVAL; flag=1; rc=setsockopt(con->soc, SOL_SOCKET, SO_KEEPALIVE, (void*)&flag, sizeof(int)); if (rc<0) { err_out("Can not set keepalive:%s(%d)\n",strerror(errno),errno); return -errno; } return 0; }
static int finalize_send_directory(tcp_con_t *con,const char *top_dir,GnomeVFSFileInfo *info){ int rc; char *res_message; if ( (!top_dir) || (!info) ) return -EINVAL; dbg_out("Here\n",res_message,top_dir); rc=create_response(IPMSG_FILE_RETPARENT,info->name,info->size,top_dir,&res_message); if (rc<0) { err_out("finalizesend directory fail %s (%d)\n", strerror(-rc),rc); return rc; } dbg_out("Send return to top dir:%s (%s)\n",res_message,top_dir); rc=send_header(con,res_message); g_free(res_message); return rc; }
static int tcp_transfer_dir(tcp_con_t *con,const char *path){ int rc; char *basename; GnomeVFSFileInfo *info; GnomeVFSResult res; gchar *dir_uri; if ( (!con) || (!path) ) return -EINVAL; info=gnome_vfs_file_info_new(); dir_uri=gnome_vfs_get_uri_from_local_path(path); rc=-ENOMEM; if (!dir_uri) goto free_info_out; res=gnome_vfs_get_file_info(dir_uri,info,GNOME_VFS_FILE_INFO_FOLLOW_LINKS); if (res != GNOME_VFS_OK) { rc=-res; goto free_info_out; } basename=g_path_get_basename(path); rc=-ENOMEM; if (!basename) goto free_info_out; rc=send_directory(con,path,basename,info); g_free(basename); if (!rc) rc=finalize_send_directory(con,path,info); else err_out("Send directory fail %s (%d)\n", strerror(-rc),rc); free_info_out: gnome_vfs_file_info_unref(info); return rc; }
static int send_directory(tcp_con_t *con,const char *top_dir,const char *basename,GnomeVFSFileInfo *info){ int rc; char *uri; GnomeVFSResult res; GnomeVFSDirectoryHandle *handle; char *next_dir; char *res_message; if ( (!top_dir) || (!info) || (!basename) ) return -EINVAL; rc=create_response(IPMSG_FILE_DIR,info->name,info->size,top_dir,&res_message); if (rc<0) return rc; dbg_out("Send dir:%s (%s)\n",res_message,top_dir); rc=send_header(con,res_message); g_free(res_message); if (rc<0) return rc; uri=gnome_vfs_get_uri_from_local_path(top_dir); if (!uri) return -ENOMEM; /* *ファイルを送付 */ res=gnome_vfs_directory_open(&handle,uri,GNOME_VFS_FILE_INFO_FOLLOW_LINKS); res=gnome_vfs_directory_read_next(handle,info); while (res==GNOME_VFS_OK) { read_directory_files(con,top_dir,info); res=gnome_vfs_directory_read_next(handle,info); } gnome_vfs_directory_close(handle); /* *ディレクトリを送付 */ res=gnome_vfs_directory_open(&handle,uri,GNOME_VFS_FILE_INFO_FOLLOW_LINKS); if (res!=GNOME_VFS_OK) { err_out("Can not open dir:%s %s (%d)\n", top_dir, gnome_vfs_result_to_string(res), res); goto error_out; } res=gnome_vfs_directory_read_next(handle,info); if (res!=GNOME_VFS_OK) { if (res != GNOME_VFS_ERROR_EOF) err_out("Can not read next dir:%s %s (%d)\n", top_dir, gnome_vfs_result_to_string(res), res); goto error_out; } while (res==GNOME_VFS_OK) { if ( (info->type==GNOME_VFS_FILE_TYPE_DIRECTORY) && ( (strcmp(info->name,"..")) && (strcmp(info->name,"."))) ){ dbg_out("dir:%s\n",info->name); next_dir=g_build_filename(top_dir,info->name,NULL); if (!next_dir) goto error_out; rc=send_directory(con,next_dir,info->name,info); g_free(next_dir); if (rc<0) return rc; rc=create_response(IPMSG_FILE_RETPARENT,info->name,info->size,top_dir,&res_message); if (rc<0) return rc; dbg_out("Send ret parent:%s\n",res_message); rc=send_header(con,res_message); g_free(res_message); if (rc<0) return rc; } res=gnome_vfs_directory_read_next(handle,info); if (res!=GNOME_VFS_OK) { if (res != GNOME_VFS_ERROR_EOF) err_out("Can not read next dir:%s %s (%d)\n", top_dir, gnome_vfs_result_to_string(res), res); goto error_out; } } error_out: gnome_vfs_directory_close(handle); g_free(uri); return rc; }
static int create_response(unsigned long type,const char *name,const size_t size,const char *dir,char **response){ int rc=0; char *buff=NULL; size_t act_len; gchar *res; size_t local_size; int msg_fid; char *local_name_p; dbg_out("here:\n"); if ( ( (!name) && (type != IPMSG_FILE_RETPARENT) ) || (!dir) || (!response) ) return -EINVAL; if (type != IPMSG_FILE_RETPARENT) dbg_out("file:%s size:%d(%x)\n", name,size,size); else dbg_out("Return to parent.\n"); switch(type) { case IPMSG_FILE_REGULAR: msg_fid=1; local_size=size; local_name_p=(char *)name; break; case IPMSG_FILE_DIR: msg_fid=2; local_size=0; local_name_p=(char *)name; break; case IPMSG_FILE_RETPARENT: msg_fid=3; local_size=0; local_name_p="."; break; default: dbg_out("Invalid type:%d\n",type); return -EINVAL; break; } /* *メッセージ形成 */ buff=g_malloc(IPMSG_BUFSIZ); if (!buff) return -ENOMEM; snprintf(buff,IPMSG_BUFSIZ-1,"xxxx:%s:%x:%d:", local_name_p,local_size,msg_fid); /* 仮の長さを算出 */ buff[IPMSG_BUFSIZ-1]='\0'; act_len=strlen(buff); snprintf(buff,IPMSG_BUFSIZ-1,"%04x:%s:%x:%d:", act_len,local_name_p,local_size,msg_fid); /* メッセージ作成 */ buff[IPMSG_BUFSIZ-1]='\0'; rc=-ENOSPC; if (act_len != strlen(buff)) { err_out("Message too long:%s\n",buff); goto error_out; } *response = buff; rc=0; goto no_free_out; error_out: if (buff) g_free(buff); no_free_out: return rc; }
gpointer ipmsg_tcp_recv_thread(gpointer data){ ssize_t recv_len; size_t addr_len; int rc; tcp_con_t *con; char *recv_buf=NULL; int count=200; struct addrinfo *info; con=(tcp_con_t *)data; if (!con) { err_out("No connection recived\n"); g_assert(con); return NULL; } if (!(con->peer_info)) { err_out("Invalid connection recived\n"); g_assert(con->peer_info); return NULL; } rc=tcp_enable_keepalive(con); if (rc<0) return NULL; recv_buf=g_malloc(_MSG_BUF_SIZE); if (!recv_buf) return NULL; memset(recv_buf,0,_MSG_BUF_SIZE); while(1) { if (wait_socket(con->soc,WAIT_FOR_READ,TCP_SELECT_SEC)<0) { err_out("Can not send socket\n"); destroy_tcp_connection(con); goto error_out; }else{ read_retry: errno=0; memset(recv_buf, 0, sizeof(recv_buf)); info=con->peer_info; recv_len=recv(con->soc, recv_buf, _MSG_BUF_SIZE, MSG_PEEK); if (recv_len<=0) { if (errno==EINTR) goto read_retry; if (errno) err_out("Can not peek message %s(errno:%d)\n",strerror(errno),errno); destroy_tcp_connection(con); goto error_out; } dbg_out("tcp peek read:%d %s\n",recv_len,recv_buf); recv_len=recv(con->soc, recv_buf, recv_len, MSG_PEEK); dbg_out("tcp read:%d %s\n",recv_len,recv_buf); if (recv_len>0) { msg_data_t msg; request_msg_t req; char *path; off_t size; unsigned long ipmsg_fattr; recv_buf[recv_len-1]='\0'; memset(&req,0,sizeof(request_msg_t)); init_message_data(&msg); parse_message(NULL,&msg,recv_buf,recv_len); parse_request(&req,msg.message); rc=refer_attach_file(req.pkt_no,req.fileid,&ipmsg_fattr,(const char **)&path,&size); if (rc<0) { err_out("Can not find message:pktno %ld id : %d\n", req.pkt_no, req.fileid); close(con->soc); /* エラーとしてクローズする */ }else{ dbg_out("transfer:%s (%d)\n",path,size); switch(ipmsg_fattr) { case IPMSG_FILE_REGULAR: if (!tcp_transfer_file(con,path,size,0)) { tcp_ipmsg_finalize_connection(con); download_monitor_release_file(req.pkt_no,req.fileid); } break; case IPMSG_FILE_DIR: if (!tcp_transfer_dir(con,path)){ download_monitor_release_file(req.pkt_no,req.fileid); tcp_ipmsg_finalize_connection(con); } break; default: break; } release_message_data(&msg); g_free(path); break; } release_message_data(&msg); break; } } --count; if (!count) break; } if (con->peer_info) /* closeは相手側で行うので, destroy_tcp_connectionは呼び出せない * (Win版ipmsgの仕様). */ freeaddrinfo(con->peer_info); error_out: g_free(con); if (recv_buf) g_free(recv_buf); return NULL; }
/** 暗号化されたメッセージを解析し, 以下の情報を取り出す. * - 通信に使用した暗号種別を表す暗号ケイパビリティ * - 本文の暗号化に使用した鍵(hex形式) * - 暗号化された本文(hex形式) * - 署名(hex形式) * @param[in] message 暗号化されたメッセージ * @param[out] this_cap_p 通信に使用した暗号種別を表す暗号ケイパビリティ返却領域 * @param[out] hex_skey_p 本文の暗号化に使用した鍵を指すポインタ変数のアドレス * @param[out] enc_message_p 暗号化された本文を指すポインタ変数のアドレス * @param[out] hex_sign_p 署名を指すポインタ変数のアドレス * @retval 0 正常終了 * @retval -EINVAL 引数異常(buffがNULL) * * @attention 内部リンケージ */ static int parse_encrypted_message(const unsigned char *message, unsigned long *this_cap_p, unsigned char **hex_skey_p, unsigned char **enc_message_p, unsigned char **hex_sign_p){ int rc = 0; char *sp = 0; char *ep = 0; unsigned long this_cap = 0; unsigned char *hex_skey = NULL; unsigned char *enc_message = NULL; unsigned char *hex_sign = NULL; char *buff = NULL; if ( (message == NULL) || (this_cap_p == NULL) || (hex_skey_p == NULL) || (enc_message_p == NULL) ) { rc = -EINVAL; goto error_out; } rc = -ENOMEM; buff = g_strdup(message); if (buff == NULL) goto error_out; /* * 鍵情報 */ sp = buff; ep = strchr(sp, ':'); if (ep == NULL) { rc = -EINVAL; err_out("Error : No cap\n"); goto free_buff_out; } *ep = '\0'; ++ep; errno = 0; this_cap = strtoul(sp, (char **)NULL, 16); dbg_out("Cap:0x%x\n", this_cap); /* *暗号鍵 */ sp = ep; ep = strchr(sp, ':'); if (ep == NULL) { rc = -EINVAL; err_out("Error : crypt key\n"); goto free_buff_out; } *ep = '\0'; ++ep; rc = -ENOMEM; hex_skey = g_strdup(sp); if (hex_skey == NULL) goto free_buff_out; dbg_out("hex secret key:%s\n", hex_skey); /* * 暗号化本文 */ sp = ep; ep = strchr(sp, ':'); if (ep != NULL) { /* これで最後の可能性もある */ *ep = '\0'; ++ep; } rc = -ENOMEM; enc_message = g_strdup(sp); if (enc_message == NULL) goto free_hex_skey_out; dbg_out("hex secret body:%s\n", enc_message); /* * 署名 */ if (ep != NULL) { sp = ep; rc = -ENOMEM; hex_sign = g_strdup(sp); if (hex_sign == NULL) goto free_enc_message_out; dbg_out("hex sign:%s\n", hex_sign); } /* * 返却 */ *this_cap_p = this_cap; *hex_skey_p = hex_skey; *enc_message_p = enc_message; *hex_sign_p = hex_sign; if (buff != NULL) g_free(buff); return 0; free_enc_message_out: if (enc_message != NULL) g_free(enc_message); free_hex_skey_out: if (hex_skey != NULL) g_free(hex_skey); free_buff_out: if (buff != NULL) g_free(buff); error_out: return rc; }
WMAlphaBitmap::WMAlphaBitmap(IImage* img) { #if defined(_WIN32_WCE) IImagingFactory *pImgFactory = NULL; mWidth = 0; mHeight = 0; mImgBuf = NULL; HRESULT co_init_result = CoInitializeEx(NULL, 0/*COINIT_APARTMENTTHREADED*/); if ( (co_init_result == S_OK) || (co_init_result == S_FALSE) ) { msg_out("CoInitializeEx OK"); if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&pImgFactory))) { ImageInfo imgInfo; img->GetImageInfo(&imgInfo); mWidth = imgInfo.Width; mHeight = imgInfo.Height; IBitmapImage* pBitmap = 0; if ( SUCCEEDED(pImgFactory->CreateBitmapFromImage( img, mWidth, mHeight, PixelFormat32bppARGB, InterpolationHintDefault, &pBitmap) )) { msg_out("Create Bitmap OK"); RECT rc = { 0, 0, mWidth, mHeight}; BitmapData bitmap_data; if ( SUCCEEDED(pBitmap->LockBits( &rc, ImageLockModeRead, PixelFormatDontCare, &bitmap_data))) { // msg_out("Lock Bits OK"); void* src_buf = bitmap_data.Scan0; int stride = bitmap_data.Stride; int w = bitmap_data.Width; int h = bitmap_data.Height; mImgBuf = new unsigned int[w*h]; if (mImgBuf != 0) { msg_out("Img buffer allocated OK"); // start convert { unsigned int* dst = mImgBuf; unsigned int* src; int x; int y; for (y = 0 ; y < h; y++) { if (stride < 0) { src = (unsigned int*)(((unsigned char*)src_buf) + (h-1-y)*(-stride)); } else { src = (unsigned int*)(((unsigned char*)src_buf) + y*(stride)); } for (x = w; x > 0; x--) { *dst++ = *src++; } } } msg_out("Convert to img buffer finished OK"); // finish convert } else { err_out("Image Buffer not allocated !"); } pBitmap->UnlockBits(&bitmap_data); } else { err_out("Bitmap bits not locked !"); } pBitmap->Release(); } pImgFactory->Release(); } CoUninitialize(); } else { err_out("CoInitializeEx not initialized !"); } #endif //#if defined(_WIN32_WCE) }
void DrawingImageImpl::init(const char* path, void const *p, int size, WMBitmap* bitmap, bool useAlpha) { mID = ++ourDrawingImageID; RHO_MAP_TRACE1("DrawingImage create with ID = %d", mID); #if defined(_WIN32_WCE) IImagingFactory *pImgFactory = NULL; IImage *pImage = NULL; mWidth = 0; mHeight = 0; mBitmap = NULL; if (bitmap != NULL) { mBitmap = bitmap; mBitmap->addRef(); mWidth = bitmap->width(); mHeight = bitmap->height(); return; } HRESULT co_init_result = CoInitializeEx(NULL, 0/*COINIT_APARTMENTTHREADED*/); if ( (co_init_result == S_OK) || (co_init_result == S_FALSE) ) { msg_out("CoInitializeEx OK"); if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&pImgFactory))) { HRESULT res = 0; if (p != NULL) { // from buf res = pImgFactory->CreateImageFromBuffer( p, size, BufferDisposalFlagNone, &pImage); } else { // from file msg_out("Create Image Factory OK"); wchar_t wc_filename[2048]; mbstowcs(wc_filename, path, 2048); res = pImgFactory->CreateImageFromFile( wc_filename, &pImage); } if (SUCCEEDED(res)) { IImage* mimage = pImage; ImageInfo imgInfo; mimage->GetImageInfo(&imgInfo); mWidth = imgInfo.Width; mHeight = imgInfo.Height; RHO_MAP_TRACE2("Drawing Image was created with WIDTH = %d, HEIGHT = %d", mWidth, mHeight); mBitmap = new WMBitmap(mimage, useAlpha); mimage->Release(); } else { err_out("Image not created !"); } pImgFactory->Release(); } else { err_out("ImageFactory not created !"); } CoUninitialize(); } else { err_out("CoInitializeEx not initialized !"); } #endif //#if defined(_WIN32_WCE) }
// ================================================================== void hatch::OnOK() // ================================================================== { CString str,areapath,filepath,magic,echotag,upl,desc; int zone,net,node,point,myzone,mynet,mynode,mypoint,sel,ret; char fpath[MAX_PATH],fname[MAX_PATH]; sel=m_list.GetCurSel(); if (sel==LB_ERR) ERR_MSG_RET("E_ETMBSEC"); str=tics.GetString(sel); get_token(str,0,echotag); get_token(str,1,upl); trim_all(upl); get_token(str,3,areapath); m_description.GetWindowText(desc); trim_all(desc); desc.Replace("\r\n",". "); // if (strchr(desc,'\r') && err_out("DN_MULLDES")==IDNO) return; m_filename.GetWindowText(filepath); if (filepath.GetLength()<2) ERR_MSG_RET("E_NOFILEGIVEN"); m_edit_magic.GetWindowText(magic); get_filename(filepath,fname); make_path(fpath,areapath,fname); if (access(fpath,0) && err_out("DY_STFBCTDA",fpath)==IDYES) { if (!CopyFile(filepath,fpath,0)) { err_out("E_CTFF",filepath,fpath); return; } } if (parse_address(upl,&zone,&net,&node,&point)<3) ERR_MSG2_RET("E_INVALUPL",upl); CFido fid=upl; char phone[300],psw[300],aka[300],ffixpsw[300],replace_buf[100]; CString repl; memset(replace_buf,0,sizeof(replace_buf)); fid.GetPhoneAndPwd(phone,psw,aka,ffixpsw); if (parse_address(aka,&myzone,&mynet,&mynode,&mypoint)<3) ERR_MSG2_RET("E_INVALUPO",upl); m_replace.GetWindowText(repl); trim_all(repl); if (repl.GetLength()>0) strcpy(replace_buf,repl); ret=make_tic_file(zone,net,node, point,myzone,mynet,mynode, mypoint, filepath,ffixpsw,desc,echotag,m_deleteafter.GetCheck(), replace_buf,magic); show_msg(ret ? L("S_176") : L("S_237"),200); // Done/Error CDialog::OnOK(); }
/** 暗号化されたメッセージを複号する * @param[in] peer_addr 送信先IPアドレス * @param[in] message 暗号化するメッセージ * @param[out] ret_str 暗号化したメッセージを指すポインタ変数のアドレス * @param[out] len 暗号化メッセージ長返却領域 * @retval 0 正常終了 * @retval -EINVAL 引数異常 * @retval -EAGAIN 署名異常 */ int ipmsg_decrypt_message(const char *peer_addr, const char *message, unsigned char **ret_str, size_t *len) { int rc = 0; unsigned long this_cap = 0; unsigned char *hex_skey = NULL; char *skey = NULL; unsigned char *signed_message = NULL; unsigned char *end_message_body_p = NULL; unsigned char *enc_message = NULL; unsigned char *hex_sign = NULL; unsigned long skey_type = 0, akey_type = 0; unsigned long sign_type = 0; unsigned char *enc_bin_body = NULL; unsigned char *peer_key_e = NULL; unsigned char *peer_key_n = NULL; unsigned long tmp_cap = 0; unsigned long new_flags = 0; char *plain = NULL; size_t plain_len = 0; size_t skey_len = 0; size_t enc_bin_len = 0; if ( (message == NULL) || (ret_str == NULL) || (len == NULL) ) { rc = -EINVAL; goto error_out; } /* * 暗号化されたメッセージから鍵情報を獲得する. */ rc = parse_encrypted_message(message, &this_cap, &hex_skey, &enc_message, &hex_sign); if (rc != 0) { err_out("Can not parse message\n"); goto error_out; } /* * 暗号化に使用した鍵種別をケイパビリティから算出する */ skey_type = get_symkey_part(this_cap); /* 共通鍵 */ akey_type = get_asymkey_part(this_cap); /* 公開鍵 */ sign_type = get_sign_part(this_cap); /* 署名 */ dbg_out("Cap:%x Skey:%x AKey:%x Sign:%x\n", this_cap, skey_type, akey_type, sign_type); /* * 署名がある場合は署名を検証 */ g_assert(peer_addr); /* udpからの呼出しの場合はかならずいれる */ if ( (hostinfo_get_ipmsg_crypt_capability() & sign_type) && (hex_sign != NULL) ) { dbg_out("This message is signed by peer.\n"); /* * 相手の公開鍵を取得 */ rc = userdb_get_public_key_by_addr(peer_addr, &tmp_cap, (char **)&peer_key_e, (char **)&peer_key_n); if (rc != 0) { goto free_parsed_datas; } /* 編集用にコピー */ signed_message = g_strdup(message); rc = -ENOMEM; if (signed_message == NULL) goto free_parsed_datas; end_message_body_p = strrchr(signed_message, ':'); if (end_message_body_p == NULL) /* 異常データ */ goto free_parsed_datas; *end_message_body_p = '\0'; /* 本文だけを参照 */ dbg_out("Verify:%s with %s\n", signed_message, hex_sign); rc = pcrypt_verify_sign(this_cap, sign_type, signed_message, hex_sign, peer_key_e, peer_key_n); /* 失敗した場合でも, 不要なデータを開放してからぬける */ if (rc != 0) { err_out("Verify failed: libcrypt rc=%d\n", rc); rc = -EAGAIN; goto free_parsed_datas; } dbg_out("Verify OK\n"); } /* * 共通鍵をデコード */ /* FIXME 鍵のバリデーション(RSAが2つ以上設定されていないか) */ rc = pcrypt_decrypt_message(akey_type, hex_skey, &skey, &skey_len); if (rc != 0) { goto free_parsed_datas; } dbg_out("Decrypt key len:%d\n", skey_len); /* * 暗号化された本文のバイナリ化 */ rc = string_hex2bin(enc_message, &enc_bin_len, &enc_bin_body); if (rc != 0) { goto free_skey; } #if 0 print_hex(skey, skey_len); #endif /* * 本文を復号化する */ rc = symcrypt_decrypt_message(skey_type, enc_bin_body, enc_bin_len, skey, &plain, &plain_len); if (rc != 0) { goto free_enc_bin_body; } dbg_out("Decoded:%s len=%d\n", plain, plain_len); *ret_str = plain; *len = plain_len; rc = 0; free_enc_bin_body: if (enc_bin_body != NULL) g_free(enc_bin_body); free_skey: if (skey != NULL) g_free(skey); free_parsed_datas: if (hex_skey != NULL) g_free(hex_skey); if (enc_message != NULL) g_free(enc_message); if (hex_sign != NULL) g_free(hex_sign); if (peer_key_e != NULL) g_free(peer_key_e); if (peer_key_n != NULL) g_free(peer_key_n); if (signed_message != NULL) g_free(signed_message); error_out: if ( (rc != 0) && (rc != -EAGAIN) ){ /* 署名検証に失敗した場合を除く */ ipmsg_err_dialog("%s: %s = %s, rc = %d", _("Can not decode message"), _("peer"), peer_addr, rc); } return rc; }
static int tcp_transfer_file(tcp_con_t *con,const char *path,const off_t size, off_t offset){ int fd; int rc; char *buff = NULL; off_t read_len; off_t file_remains; off_t soc_remains; off_t write_len; off_t total_write; char *wp; struct sigaction saved_act; if ( (!con) || (!path) ) return -EINVAL; buff = g_malloc(TCP_FILE_BUFSIZ); if (buff == NULL) return -ENOMEM; fd=open(path,O_RDONLY); if (fd<0) return -errno; rc=lseek(fd, offset, SEEK_SET); if (rc<0) { rc=-errno; goto close_out; } total_write=0; file_remains=size; while(file_remains>0) { read_len=read(fd,buff,TCP_FILE_BUFSIZ); if (read_len<0) { rc=-errno; err_out("Can not read file %s %d\n",strerror(errno),errno); goto close_out; } file_remains -= read_len; soc_remains = read_len; wp = buff; if (wait_socket(con->soc,WAIT_FOR_WRITE,TCP_SELECT_SEC)<0) { err_out("Can not send socket\n"); goto close_out; } dbg_out("sock remains:%d\n",soc_remains); disable_pipe_signal(&saved_act); while(soc_remains > 0) { write_len = write(con->soc, wp, soc_remains); if (write_len<0) { if (errno==EINTR) continue; err_out("Can not send %s %d\n",strerror(errno),errno); enable_pipe_signal(&saved_act); goto close_out; } dbg_out("write len :%d\n",write_len); wp += write_len; total_write += write_len; soc_remains -= write_len; } enable_pipe_signal(&saved_act); dbg_out("transfer %s %d/%d(%d)\n",path,total_write,size,file_remains); } rc=0; close_out: close(fd); if (rc<0) dbg_out("Can not send file:%s %s %d\n",path,strerror(errno),errno); if (buff != NULL) g_free(buff); return rc; }
gpointer ipmsg_tcp_server_thread(gpointer data){ int rc; size_t len; int sock; int tcp_socket; int port; int reuse; int family; tcp_con_t *client_con=NULL; struct addrinfo *info=NULL; family=(int)data; rc=setup_addr_info(&info, NULL, hostinfo_refer_ipmsg_port(), SOCK_STREAM,family); if (rc<0) return NULL; tcp_socket = socket(info->ai_family, info->ai_socktype, info->ai_protocol); if (tcp_socket < 0) { err_out("Can not create socket:%s (%d)\n",strerror(errno),errno); goto error_out; } reuse=1; if (setsockopt(tcp_socket,SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse, sizeof(reuse))<0) { err_out("Can not set sock opt:%s (%d)\n",strerror(errno),errno); goto error_out; } #ifdef IPV6_V6ONLY if (info->ai_family == AF_INET6) { int v6only=1; rc=setsockopt(tcp_socket,IPPROTO_IPV6,IPV6_V6ONLY,(void *)&v6only,sizeof(v6only)); if (rc) { goto error_out; } } #endif /* IPV6_V6ONLY */ if (bind(tcp_socket, info->ai_addr, info->ai_addrlen) != 0) { err_out("Can not bind socket:%s (%d)\n",strerror(errno),errno); goto error_out; } if (sock_set_buffer(tcp_socket, _TCP_BUF_MIN_SIZE, _TCP_BUF_SIZE)<0) { err_out("Can not set socket buffer:%s (%d)\n",strerror(errno),errno); goto error_out; } if (listen(tcp_socket, TCP_LISTEN_LEN) != 0) { err_out("Can not listen socket:%s (%d)\n",strerror(errno),errno); goto error_out; } while (1) { GThread *handler; struct addrinfo *client_info=NULL; client_con=g_malloc(sizeof(tcp_con_t)); g_assert(client_con); dbg_out("accept\n"); rc=setup_addr_info(&client_info, NULL, hostinfo_refer_ipmsg_port(), SOCK_STREAM,family); if (rc<0) goto free_client_out; sock = accept(tcp_socket, client_info->ai_addr,&(client_info->ai_addrlen)); if (sock < 0) { err_out("Can not accept:%s (%d)\n",strerror(errno),errno); goto free_client_out; } if (sock_set_buffer(sock, _TCP_BUF_MIN_SIZE, _TCP_BUF_SIZE)<0) { err_out("Can not set socket buffer:%s (%d)\n",strerror(errno),errno); goto free_client_out; } client_con->soc=sock; client_con->peer_info=client_info; handler=g_thread_create(ipmsg_tcp_recv_thread, client_con, FALSE, NULL); if (!handler) { err_out("Can not create handler thread.\n"); goto free_client_out; } } /* ここには, 来ないはずだが, 念のため */ if (info) freeaddrinfo(info); return NULL; free_client_out: destroy_tcp_connection(client_con); error_out: if (info) freeaddrinfo(info); exit(0); /* 多重起動のため 終了 */ return NULL; }
// ===================================================================== void handle_mm_stuff(char *mailbuf,int fromwhere) // ===================================================================== { static int preflen=strlen(MM_PREFIX); char *p,*t; char name[300]; char mmcod[MAX_PATH],mmbase[MAX_PATH]; if (GetKeyState(VK_CONTROL) & 0x80000000) return; // WAVES // Format: MM_PREFIX|mmtype|whentoplay|name p=mailbuf; handle_wav: if ((gc.sound_enabled && !gc.sound_already_done) || fromwhere==3) { find_ag1: p=strstr(p,MM_PREFIX); if (p) { p+=preflen; switch (*p) { case 'W': case 'w': break; case 'B': case 'b': if ((gc.bmps_enabled && !gc.bmps_already_done) || fromwhere==3) { p-=preflen; goto handle_bmp; } goto find_ag1; case '\0': return; default: goto find_ag1; } p++; if (fromwhere!=3) { switch (*p) // 1-Play on display , 2-Play on income { case '1': if (fromwhere!=1) goto handle_bmp; break; case '2': if (fromwhere!=2) goto handle_bmp; break; default: goto handle_bmp; } } p++; name[0]=0; sscanf(p,"%s",name); if (!name[0] || strlen(name)>8) goto handle_bmp; t=name; while (*t) { if (!isxdigit(*t)) goto handle_bmp; t++; } strcpy(mmcod,"00000000"); memcpy(mmcod+(8-strlen(name)),name,strlen(name)); // strcpy(mmcod,name); strcat(mmcod,".WAV"); make_path(mmbase,gc.MultimedPath,mmcod); if (access(mmbase,0)) { if (gc.no_error) err_out("W_CNFMMXF",mmbase); goto handle_bmp; } gc.sound_already_done=1; test_sound(mmbase); } else return; } // BITMAPS // Format: MM_PREFIX|mmtype|whentoplay|name with ending NULL handle_bmp: if ((gc.bmps_enabled && !gc.bmps_already_done) || fromwhere==3) { find_ag2: p=strstr(p,MM_PREFIX); if (p) { p+=preflen; switch (*p) { case 'W': case 'w': if ((gc.sound_enabled && !gc.sound_already_done) || fromwhere==3) { p-=preflen; goto handle_wav; } goto find_ag2; case 'B': case 'b': break; case '\0': return; default: goto find_ag2; } p++; if (fromwhere!=3) { switch (*p) // 1=Play on display , 2=Play on income { case '1': if (fromwhere!=1) goto handle_wav; break; case '2': if (fromwhere!=2) goto handle_wav; break; default: goto handle_wav; } } p++; name[0]=0; sscanf(p,"%s",name); if (!name[0] || strlen(name)>8) goto handle_wav; t=name; while (*t) { if (!isxdigit(*t)) goto handle_wav; t++; } strcpy(mmcod,"00000000"); memcpy(mmcod+(8-strlen(name)),name,strlen(name)); strcpy(mmcod,name); strcat(mmcod,".BMP"); make_path(mmbase,gc.MultimedPath,mmcod); if (access(mmbase,0)) { if (gc.no_error) err_out("W_CNFMMXF",mmbase); goto handle_wav; } gc.bmps_already_done=1; display_bitmap(mmbase); } else return; goto handle_wav; } }