| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/ftp/ftp_network_transaction.h" | 5 #include "net/ftp/ftp_network_transaction.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "net/base/address_list.h" | 16 #include "net/base/address_list.h" |
| 17 #include "net/base/escape.h" | 17 #include "net/base/escape.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 #include "net/base/parse_number.h" |
| 19 #include "net/base/port_util.h" | 20 #include "net/base/port_util.h" |
| 20 #include "net/base/url_util.h" | 21 #include "net/base/url_util.h" |
| 21 #include "net/ftp/ftp_request_info.h" | 22 #include "net/ftp/ftp_request_info.h" |
| 22 #include "net/ftp/ftp_util.h" | 23 #include "net/ftp/ftp_util.h" |
| 23 #include "net/log/net_log.h" | 24 #include "net/log/net_log.h" |
| 24 #include "net/log/net_log_event_type.h" | 25 #include "net/log/net_log_event_type.h" |
| 25 #include "net/log/net_log_source.h" | 26 #include "net/log/net_log_source.h" |
| 26 #include "net/socket/client_socket_factory.h" | 27 #include "net/socket/client_socket_factory.h" |
| 27 #include "net/socket/stream_socket.h" | 28 #include "net/socket/stream_socket.h" |
| 28 #include "url/url_constants.h" | 29 #include "url/url_constants.h" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 } | 117 } |
| 117 } | 118 } |
| 118 | 119 |
| 119 // From RFC 2428 Section 3: | 120 // From RFC 2428 Section 3: |
| 120 // The text returned in response to the EPSV command MUST be: | 121 // The text returned in response to the EPSV command MUST be: |
| 121 // <some text> (<d><d><d><tcp-port><d>) | 122 // <some text> (<d><d><d><tcp-port><d>) |
| 122 // <d> is a delimiter character, ideally to be | | 123 // <d> is a delimiter character, ideally to be | |
| 123 bool ExtractPortFromEPSVResponse(const FtpCtrlResponse& response, int* port) { | 124 bool ExtractPortFromEPSVResponse(const FtpCtrlResponse& response, int* port) { |
| 124 if (response.lines.size() != 1) | 125 if (response.lines.size() != 1) |
| 125 return false; | 126 return false; |
| 126 const char* ptr = response.lines[0].c_str(); | 127 |
| 127 while (*ptr && *ptr != '(') | 128 base::StringPiece epsv_line(response.lines[0]); |
| 128 ++ptr; | 129 size_t start = epsv_line.find('('); |
| 129 if (!*ptr) | 130 // If the line doesn't have a '(' or doesn't have enough characters after the |
| 130 return false; | 131 // first '(', fail. |
| 131 char sep = *(++ptr); | 132 if (start == base::StringPiece::npos || epsv_line.length() - start < 7) |
| 132 if (!sep || isdigit(sep) || *(++ptr) != sep || *(++ptr) != sep) | |
| 133 return false; | |
| 134 if (!isdigit(*(++ptr))) | |
| 135 return false; | |
| 136 *port = *ptr - '0'; | |
| 137 while (isdigit(*(++ptr))) { | |
| 138 *port *= 10; | |
| 139 *port += *ptr - '0'; | |
| 140 } | |
| 141 if (*ptr != sep) | |
| 142 return false; | 133 return false; |
| 143 | 134 |
| 144 return true; | 135 char separator = epsv_line[start + 1]; |
| 136 |
| 137 // Make sure we have "(<d><d><d>...", where <d> is not a number. |
| 138 if (isdigit(separator) || epsv_line[start + 2] != separator || |
| 139 epsv_line[start + 3] != separator) { |
| 140 return false; |
| 141 } |
| 142 |
| 143 // Skip over those characters. |
| 144 start += 4; |
| 145 |
| 146 // Make sure there's a terminal <d>. |
| 147 size_t end = epsv_line.find(separator, start); |
| 148 if (end == base::StringPiece::npos) |
| 149 return false; |
| 150 |
| 151 return ParseInt32(epsv_line.substr(start, end - start), |
| 152 ParseIntFormat::NON_NEGATIVE, port); |
| 145 } | 153 } |
| 146 | 154 |
| 147 // There are two way we can receive IP address and port. | 155 // There are two way we can receive IP address and port. |
| 148 // (127,0,0,1,23,21) IP address and port encapsulated in (). | 156 // (127,0,0,1,23,21) IP address and port encapsulated in (). |
| 149 // 127,0,0,1,23,21 IP address and port without (). | 157 // 127,0,0,1,23,21 IP address and port without (). |
| 150 // | 158 // |
| 151 // See RFC 959, Section 4.1.2 | 159 // See RFC 959, Section 4.1.2 |
| 152 bool ExtractPortFromPASVResponse(const FtpCtrlResponse& response, int* port) { | 160 bool ExtractPortFromPASVResponse(const FtpCtrlResponse& response, int* port) { |
| 153 if (response.lines.size() != 1) | 161 if (response.lines.size() != 1) |
| 154 return false; | 162 return false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 183 | 191 |
| 184 // Split the line into comma-separated pieces and extract | 192 // Split the line into comma-separated pieces and extract |
| 185 // the last two. | 193 // the last two. |
| 186 std::vector<base::StringPiece> pieces = base::SplitStringPiece( | 194 std::vector<base::StringPiece> pieces = base::SplitStringPiece( |
| 187 line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 195 line, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 188 if (pieces.size() != 6) | 196 if (pieces.size() != 6) |
| 189 return false; | 197 return false; |
| 190 | 198 |
| 191 // Ignore the IP address supplied in the response. We are always going | 199 // Ignore the IP address supplied in the response. We are always going |
| 192 // to connect back to the same server to prevent FTP PASV port scanning. | 200 // to connect back to the same server to prevent FTP PASV port scanning. |
| 193 int p0, p1; | 201 uint32_t p0, p1; |
| 194 if (!base::StringToInt(pieces[4], &p0)) | 202 if (!ParseUint32(pieces[4], &p0)) |
| 195 return false; | 203 return false; |
| 196 if (!base::StringToInt(pieces[5], &p1)) | 204 if (!ParseUint32(pieces[5], &p1)) |
| 197 return false; | 205 return false; |
| 206 if (p0 > 0xFF || p1 > 0xFF) |
| 207 return false; |
| 208 |
| 198 *port = (p0 << 8) + p1; | 209 *port = (p0 << 8) + p1; |
| 199 | |
| 200 return true; | 210 return true; |
| 201 } | 211 } |
| 202 | 212 |
| 203 } // namespace | 213 } // namespace |
| 204 | 214 |
| 205 FtpNetworkTransaction::FtpNetworkTransaction( | 215 FtpNetworkTransaction::FtpNetworkTransaction( |
| 206 HostResolver* resolver, | 216 HostResolver* resolver, |
| 207 ClientSocketFactory* socket_factory) | 217 ClientSocketFactory* socket_factory) |
| 208 : command_sent_(COMMAND_NONE), | 218 : command_sent_(COMMAND_NONE), |
| 209 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, | 219 io_callback_(base::Bind(&FtpNetworkTransaction::OnIOComplete, |
| (...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 if (!had_error_type[type]) { | 1353 if (!had_error_type[type]) { |
| 1344 had_error_type[type] = true; | 1354 had_error_type[type] = true; |
| 1345 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", | 1355 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorHappened", |
| 1346 type, NUM_OF_NET_ERROR_TYPES); | 1356 type, NUM_OF_NET_ERROR_TYPES); |
| 1347 } | 1357 } |
| 1348 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", | 1358 UMA_HISTOGRAM_ENUMERATION("Net.FtpDataConnectionErrorCount", |
| 1349 type, NUM_OF_NET_ERROR_TYPES); | 1359 type, NUM_OF_NET_ERROR_TYPES); |
| 1350 } | 1360 } |
| 1351 | 1361 |
| 1352 } // namespace net | 1362 } // namespace net |
| OLD | NEW |