1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
#include "ftp_decoder_inner.h"
#include "ftp_decoder.h"
#include "ftp_decoder_util.h"
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <libgen.h>
void fstring_dup(const fstring *src, fstring *dst)
{
dst->iov_base = (char *)malloc(src->iov_len);
assert(dst->iov_base);
memcpy((void *)dst->iov_base, src->iov_base, src->iov_len);
dst->iov_len = src->iov_len;
}
void fstring_safe_dup(const fstring *src, fstring *dst)
{
if (dst->iov_base)
{
free(dst->iov_base); // free it if exist
}
fstring_dup(src, dst);
}
void ftp_parse_result_free(struct ftp_parse_result *parse_result)
{
for (int i = 0; i < FTP_MSG_MAX; i++)
{
if (i != FTP_INVENTORY && i != FTP_FILE_CONTENT)
{
if (parse_result->result_array[i].iov_base)
{
free(parse_result->result_array[i].iov_base);
}
}
}
}
static void ftp_str_split(const char *payload, size_t len, fstring *left, fstring *rigth, int delim)
{
const char *p = (char *)memchr(payload, delim, len);
if (NULL == p)
{
left->iov_base = (char *)payload;
left->iov_len = len;
rigth->iov_base = NULL;
rigth->iov_len = 0;
}
else
{
left->iov_base = (char *)payload;
left->iov_len = p - payload;
rigth->iov_base = (char *)p + 1;
rigth->iov_len = len - left->iov_len - 1;
}
}
long ftp_skip_tail_crlf(const char *payload, long len)
{
long new_len = 0;
for (long i = 0; i < len; i++, new_len++)
{
if ((payload[i] == '\r' || payload[i] == '\n'))
{
break;
}
}
return new_len;
}
int ftp_cmd_readline(struct ftp_interact_line *line, const char *payload, size_t len)
{
memset(line, 0, sizeof(struct ftp_interact_line));
long skip_crlf_len = ftp_skip_tail_crlf(payload, len);
ftp_str_split(payload, skip_crlf_len, &line->cmd_refer, &line->arg_refer, ' ');
return 0;
}
void ftp_strtolower(char *str, size_t len)
{
for (size_t i = 0; i < len; i++)
{
str[i] = tolower(str[i]);
}
}
int ftp_mkdir_p(const char *path, mode_t mode)
{
struct stat st;
errno = 0;
/* Try to make the directory */
if (mkdir(path, mode) == 0)
return 0;
/* If it fails for any reason but EEXIST, fail */
if (errno != EEXIST)
return -1;
/* Check if the existing path is a directory */
if (stat(path, &st) != 0)
return -1;
/* If not, fail with ENOTDIR */
if (!S_ISDIR(st.st_mode))
{
errno = ENOTDIR;
return -1;
}
errno = 0;
return 0;
}
int ftp_session_get_pkt_dir(struct session *sess)
{
const struct packet *pkt = session_get0_current_packet(sess);
if (NULL == pkt)
{
return PACKET_DIRECTION_UNKNOWN;
}
return packet_get_direction(pkt);
}
struct ftp_context *ftp_decoder_context_deep_dup(const struct ftp_context *src)
{
struct ftp_context *new_ctx = (struct ftp_context *)calloc(1, sizeof(struct ftp_context));
for (int i = 0; i < FTP_MSG_MAX; i++)
{
if (i != FTP_INVENTORY && i != FTP_FILE_CONTENT)
{
fstring_safe_dup(&src->parse_result.result_array[i], &new_ctx->parse_result.result_array[i]);
}
}
return new_ctx;
}
const char *ftp_message_type_to_string(enum ftp_msg_type fmsg_type)
{
switch (fmsg_type)
{
case FTP_BANNER:
return "FTP_BANNER";
case FTP_ACCOUNT:
return "FTP_ACCOUNT";
case FTP_PASSWORD:
return "FTP_PASSWORD";
case FTP_URI:
return "FTP_URI";
case FTP_TRANS_MODE:
return "FTP_TRANS_MODE";
case FTP_TRANS_DIR:
return "FTP_TRANS_DIR";
case FTP_INVENTORY:
return "FTP_INVENTORY";
case FTP_FILE_CONTENT:
return "FTP_FILE_CONTENT";
case FTP_MSG_MAX:
return "UNKNOWN";
}
return "UNKNOWN";
}
|