📄 ftp.c
字号:
/* This file is part of sniffer, a packet capture utility and network moniter The author can be contacted at <mistral@stev.org> the lastest version is avilable from http://stev.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "config.h"#ifdef FTP /* do we want ftp ? */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <pthread.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include "list.h"#include "locks.h"#include "tcp.h"#include "ftp.h"#include "log.h"/* this is only to lock the output file so we dont get data from 2 different ftp connections in the file at the same time */pthread_mutex_t ftp_mutex = PTHREAD_MUTEX_INITIALIZER;void ftp_src(struct sniff_pkt *pkt, struct tcp_data *tcp, char *data, int length) { struct ftp_data *tmp; char *tdata; tmp = tcp->dat; if (length < 2) return; /* set a null at the end of the data prevents overruns */ /* we also strip the <CFLF> off the end */ data[length + 1] = (char ) NULL; data = strtok(data, "\r\n"); while (data && data[1]) { /* USER <SP> <username> <CRLF> */ if (strncmp("USER ", data, 5) == 0) { if (tmp->user) /* this should not happen */ free(tmp->user); tmp->user = malloc(strlen(data) - 4); if (!tmp->user) { log_errno("malloc"); goto skip; /* balls no ram */ } strcpy(tmp->user, data + 5); goto skip; } /* endof strcmp USER */ /* PASS <SP> <password> <CRLF> */ if (strncmp("PASS ", data, 5) == 0) { if (tmp->pass) /* this should not happen */ free(tmp->pass); tmp->pass = malloc(strlen(data) - 4); if (!tmp->pass) { log_errno("malloc"); goto skip; /* balls no ram */ } strcpy(tmp->pass, data + 5); goto skip; } /* strcmp PASS */ /* ACCT <SP> <account-information> <CRLF> */ if (strncmp("ACCT ", data, 5) == 0) { if (tmp->acct) /* this should not happen */ free(tmp->acct); tmp->acct = malloc(strlen(data) - 4); if (!tmp->acct) { log_errno("malloc"); goto skip; /* balls no ram */ } strcpy(tmp->acct, data + 5); goto skip; } /* end of strcmp ACCT */ /* CWD <SP> <pathname> <CRLF> */ if (strncmp("CWD " , data, 4) == 0) goto skip; /* CDUP <CRLF> */ if (strncmp("CDUP" , data, 4) == 0) goto skip; /* SMNT <SP> <pathname> <CRLF> */ if (strncmp("SMNT " , data, 5) == 0) goto skip; /* QUIT <CRLF> */ if (strncmp("QUIT" , data, 4) == 0) goto skip; /* REIN <CRLF> */ if (strncmp("REIN" , data, 4) == 0) goto skip; /* PORT <SP> <host-port> <CRLF> */ if (strncmp("PORT " , data, 5) == 0) goto skip; /* PASV <CRLF> */ if (strncmp("PASV" , data, 4) == 0) goto skip; /* TYPE <SP> <type-code> <CRLF> */ if (strncmp("TYPE " , data, 5) == 0) goto skip; /* STRU <SP> <structure-code> <CRLF> */ if (strncmp("STRU " , data, 5) == 0) goto skip; /* MODE <SP> <mode-code> <CRLF> */ if (strncmp("MODE " , data, 5) == 0) goto skip; /* RETR <SP> <pathname> <CRLF> */ if (strncmp("RETR ", data, 5) == 0) { tdata = malloc(strlen(data) - 3); if (!tdata) { log_errno("malloc"); goto skip; /* balls no ram */ } strcpy(tdata, data + 4); list_add(tmp->download, tdata); goto skip; } /* end RETR */ /* STOR <SP> <pathname> <CRLF> */ if (strncmp("STOR ", data, 5) == 0) { tdata = malloc(strlen(data) - 3); if (!tdata) { log_errno("malloc"); return; /* balls no ram */ } strcpy(tdata, data + 4); list_add(tmp->upload, tdata); goto skip; } /* STOU <CRLF> */ if (strncmp("STOU" , data, 4) == 0) goto skip; /* APPE <SP> <pathname> <CRLF> */ if (strncmp("APPE" , data, 4) == 0) goto skip; /* ALLO <SP> <decimal-interger> <CRLF> */ /* ALLO <SP> R <SP> <decimal-interger> <CRLF> */ if (strncmp("ALLO " , data, 5) == 0) goto skip; /* REST <SP> <marker> <CRLF> */ if (strncmp("REST " , data, 5) == 0) goto skip; /* RNFR <SP> <pathname> <CRLF> */ if (strncmp("RNFR " , data, 5) == 0) goto skip; /* RNTO <SP> <pathname> <CRLF> */ if (strncmp("RNTO " , data, 5) == 0) goto skip; /* ABOR <CRLF> */ if (strncmp("ABOR" , data, 4) == 0) goto skip; /* DELE <SP> <pathname> <CRLF> */ if (strncmp("DELE " , data, 5) == 0) goto skip; /* RMD <SP> <pathname> <CRLF> */ if (strncmp("RMD " , data, 4) == 0) goto skip; /* MKD <SP> <pathname> <CRLF> */ if (strncmp("MKD " , data, 4) == 0) goto skip; /* PWD <CRLF> */ if (strncmp("PWD" , data, 3) == 0) goto skip; /* LIST <SP> <pathname> <CRLF> */ /* LIST <CRLF> */ if (strncmp("LIST" , data, 4) == 0) goto skip; /* NLST <SP> <pathname> <CRLF> */ /* NLST <CRLF> */ if (strncmp("NLST" , data, 4) == 0) goto skip; /* SITE <SP> <string> <CRLF> */ if (strncmp("SITE " , data, 5) == 0) goto skip; /* SYST <CRLF> */ if (strncmp("SYST" , data, 4) == 0) goto skip; /* STAT <SP> <pathname> <CRLF> */ /* STAT <CRLF> */ if (strncmp("STAT" , data, 4) == 0) goto skip; /* HELP <SP> <string> <CRLF> */ /* HELP <CRLF> */ if (strncmp("HELP" , data, 4) == 0) goto skip; /* NOOP <CRLF> */ if (strncmp("NOOP" , data, 4) == 0) goto skip; /* when we get this far log an error because the ftp command does not exist */ /* print data here for debuging */ skip: /* we jump here when we handle something */ data = strtok(NULL, "\r\n"); }#ifdef DEBUG_FTP log_s(data);#endif return;}void ftp_dst(struct sniff_pkt *pkt, struct tcp_data *tcp, char *data, int length) { struct ftp_data *tmp; char cmd[4]; int c; char *tdata; /* temp data storage */ tmp = tcp->dat; if (length < 2) return; /* set a null at the end of the data prevents overruns */ /* we also strip the <CFLF> off the end */ data[length + 1] = (char ) NULL; data = strtok(data, "\r\n"); while(data && data[1]) { strncpy(&cmd[0], data, 3); c = atoi(cmd); switch (c) { case 110: /* Restart Marker Reply MARK yyyy = mmmm */ break; case 120: /* Service ready in nnn minutes */ break; case 125: /* Data connection already open */ break; case 150: /* Opening Connection */ break; case 200: /* command ok */ break; case 202: /* command not implemented */ break; case 211: /* System status or help reply */ break; case 212: /* Directory status */ break; case 213: /* file status */ break; case 214: /* help message */ break; case 215: /* reply from SYST command */ if (tmp->syst) /* this should not happen */ free(tmp->syst); tmp->syst = malloc(strlen(data) - 3); if (!tmp->syst) { log_errno("malloc"); return; /* balls no ram */ } strcpy(tmp->syst, data + 4); break; case 220: /* the server is ok */ tmp->state = FTP_OK; break; case 221: /* Goodbye */ break; case 225: /* data connection open no transfer in progress */ break; case 226: /* transfer complete */ break; case 227: /* entering passive mode */ break; case 230: /* User logged in proceed */ tdata = malloc(strlen(data) - 3); if (!tdata) { log_errno("malloc"); return; /* balls no ram */ } strcpy(tdata, data + 4); list_add(tmp->welcome, tdata); break; case 250: /* requested file action ok */ break; case 257: /* "PATHNAME" created */ break; case 331: /* user name ok need password */ break; case 332: /* need account for login */ break; case 350: /* requested file action pending futher info */ break; case 421: /* service not avilable */ break; case 425: /* cant open data connection */ break; case 426: /* connection closed transfere aborted */ break; case 450: /* requested file action aborted eg file busy */ break; case 451: /* requested file action aborted error in processing*/ break; case 452: /* requested action not taken no storage on system */ break; case 500: /* syntax error command not understood */ break; case 501: /* syntax error in parameters */ break; case 502: /* command not implemented */ break; case 503: /* bad sequence of commands */ break; case 504: /* command not implemented for that parm */ break; case 530: /* not logged in */ break; case 532: /* need account for storing files */ break; case 550: /* requested action not taken eg perm denied*/ break; case 551: /* requested action aborted page type unknown */ break; case 552: /* requested file action aborted exceeded storage */ break; case 553: /* requested action not taken file name not allowed */ break; default: /* print data here to debug */ break; } /* end of switch */ data = strtok(NULL, "\r\n"); } /* end of while(data) */}void ftp_clean(struct tcp_data *tcp) { struct ftp_data *tmp; int i, total; char *data; FILE *ftp_file = NULL; /* pointer to a file */ char *fname = NULL; /* malloc this */ tmp = tcp->dat; /* get the tcp->dat in */ if (!tmp) return;#ifdef DEBUG_FTP log_s("Deleted struct");#endif i = strlen("output/ftp/"); if (tmp->user) i += strlen(tmp->user); if (tcp->dest.ip_name) { i += strlen(tcp->dest.ip_name); } else { i += strlen(tcp->dest.ip_str); } i += 3; /* for the @ and null */ fname = malloc(i); if (!fname) { log_errno("malloc:"); goto free_up; /* jump on the bottom */ } /* build up a file name */ strcpy(fname, "output/ftp/"); if (tmp->user) strcat(fname, tmp->user); strcat(fname, "@"); /* we will just get @hostname if user did not work */ if (tcp->dest.ip_name) { strcat(fname, tcp->dest.ip_name); } else { strcat(fname, tcp->dest.ip_str); } SLOCK(&ftp_mutex); ftp_file = fopen(fname, "a"); if (!ftp_file) { log_errno("fopen:"); SUNLOCK(&ftp_mutex); goto free_up; /* jump out the bottom */ } /* print out some info about the host */ fprintf(ftp_file, "********************************************\n"); if (tcp->dest.ip_name) { fprintf(ftp_file, "HOSTNAME: %s\n", tcp->dest.ip_name); } else { fprintf(ftp_file, "HOSTNAME: %s\n", tcp->dest.ip_str); } if (tcp->src.ip_name) { fprintf(ftp_file, "CLIENT : %s\n", tcp->src.ip_name); } else { fprintf(ftp_file, "CLIENT : %s\n", tcp->src.ip_str); } if (tmp->user) fprintf(ftp_file, "USERNAME: %s\n", tmp->user); if (tmp->pass) fprintf(ftp_file, "PASSWORD: %s\n", tmp->pass); if (tmp->acct) fprintf(ftp_file, "ACCTNAME: %s\n", tmp->acct); if (tmp->syst) fprintf(ftp_file, "SYSTEM : %s\n", tmp->syst); /* print out the welcome message */ fprintf(ftp_file, "Welcome Message\n"); total = list_length(tmp->welcome); for(i=0;i<total;i++) { data = list_get(tmp->welcome, 0); list_del(tmp->welcome, 0); fprintf(ftp_file, " %s\n", data); /* free each line as we go */ free(data); } /* for each line in the welcome message */ fprintf(ftp_file, "End Of Welcome Message\n"); list_free(tmp->welcome); /* we wont need this again */ /* print out all the files downloaded */ fprintf(ftp_file, "Files Downloaded\n"); total = list_length(tmp->download); for(i=0;i<total;i++) { data = list_get(tmp->download, 0); list_del(tmp->download, 0); fprintf(ftp_file, " %s\n", data); free(data); /* free each as we go */ } list_free(tmp->download); /* kill the list pointers */ /* print all the file downloaded */ fprintf(ftp_file, "Files Uploaded\n"); total = list_length(tmp->upload); for(i=0;i<total;i++) { data = list_get(tmp->upload, 0); list_del(tmp->upload, 0); fprintf(ftp_file, " %s\n", data); free(data); /* free as we go */ } list_free(tmp->upload); /* kill list pointers */ /* the end and flush the file so you can read the new info */ fprintf(ftp_file, "End of FTP Session\n"); fclose(ftp_file); SUNLOCK(&ftp_mutex);free_up: /* just free up and exit */ if (tmp->user) free(tmp->user); if (tmp->pass) free(tmp->pass); if (tmp->acct) free(tmp->acct); if (tmp->pwd) free(tmp->pwd); if (fname) free(fname); free(tmp); /* if tmp was == NULL we would not get this far */ return;}void ftp_init(struct tcp_data *tcp) { struct ftp_data *tmp;#ifdef DEBUG_FTP log_s("Added struct");#endif tmp = malloc(sizeof(struct ftp_data)); if (!tmp) { log_errno("malloc"); goto get_out; } tmp->user = NULL; tmp->pass = NULL; tmp->acct = NULL; tmp->syst = NULL; tmp->pwd = NULL; tmp->state = FTP_START; tmp->welcome = list_init(); tmp->download = list_init(); tmp->upload = list_init(); tcp->func_src = ftp_src; tcp->func_dst = ftp_dst; tcp->func_lookup = NULL; tcp->func_cleanup = ftp_clean; tcp->dat = tmp; return;get_out: tcp->func_src = NULL; tcp->func_dst = NULL; tcp->func_cleanup = NULL; return;}void ftp_open() { SLOCK(&ftp_mutex); if (mkdir("output/ftp", S_IRWXU) < 0) if (errno != EEXIST) log_errno_nolock("mkdir: output/ftp "); SUNLOCK(&ftp_mutex); return;}#endif /* ifdef FTP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -