Commit c043def9 authored by Lukasz Marek's avatar Lukasz Marek

lavf/ftp: parse user and password once

Signed-off-by: 's avatarLukasz Marek <lukasz.m.luki2@gmail.com>
parent 3723a183
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#define CONTROL_BUFFER_SIZE 1024 #define CONTROL_BUFFER_SIZE 1024
#define CREDENTIALS_BUFFER_SIZE 128
typedef enum { typedef enum {
UNKNOWN, UNKNOWN,
...@@ -45,7 +44,8 @@ typedef struct { ...@@ -45,7 +44,8 @@ typedef struct {
int server_data_port; /**< Data connection port opened by server, -1 on error. */ int server_data_port; /**< Data connection port opened by server, -1 on error. */
int server_control_port; /**< Control connection port, default is 21 */ int server_control_port; /**< Control connection port, default is 21 */
char hostname[512]; /**< Server address. */ char hostname[512]; /**< Server address. */
char credencials[CREDENTIALS_BUFFER_SIZE]; /**< Authentication data */ char *user; /**< Server user */
char *password; /**< Server user's password */
char path[MAX_URL_SIZE]; /**< Path to resource on server. */ char path[MAX_URL_SIZE]; /**< Path to resource on server. */
int64_t filesize; /**< Size of file on server, -1 on error. */ int64_t filesize; /**< Size of file on server, -1 on error. */
int64_t position; /**< Current position, calculated. */ int64_t position; /**< Current position, calculated. */
...@@ -72,6 +72,8 @@ static const AVClass ftp_context_class = { ...@@ -72,6 +72,8 @@ static const AVClass ftp_context_class = {
.version = LIBAVUTIL_VERSION_INT, .version = LIBAVUTIL_VERSION_INT,
}; };
static int ftp_close(URLContext *h);
static int ftp_getc(FTPContext *s) static int ftp_getc(FTPContext *s)
{ {
int len; int len;
...@@ -213,28 +215,16 @@ static void ftp_close_both_connections(FTPContext *s) ...@@ -213,28 +215,16 @@ static void ftp_close_both_connections(FTPContext *s)
static int ftp_auth(FTPContext *s) static int ftp_auth(FTPContext *s)
{ {
const char *user = NULL, *pass = NULL; char buf[CONTROL_BUFFER_SIZE];
char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE];
int err; int err;
static const int user_codes[] = {331, 230, 0}; static const int user_codes[] = {331, 230, 0};
static const int pass_codes[] = {230, 0}; static const int pass_codes[] = {230, 0};
/* Authentication may be repeated, original string has to be saved */ snprintf(buf, sizeof(buf), "USER %s\r\n", s->user);
av_strlcpy(credencials, s->credencials, sizeof(credencials));
user = av_strtok(credencials, ":", &end);
pass = av_strtok(end, ":", &end);
if (!user) {
user = "anonymous";
pass = s->anonymous_password ? s->anonymous_password : "nopassword";
}
snprintf(buf, sizeof(buf), "USER %s\r\n", user);
err = ftp_send_command(s, buf, user_codes, NULL); err = ftp_send_command(s, buf, user_codes, NULL);
if (err == 331) { if (err == 331) {
if (pass) { if (s->password) {
snprintf(buf, sizeof(buf), "PASS %s\r\n", pass); snprintf(buf, sizeof(buf), "PASS %s\r\n", s->password);
err = ftp_send_command(s, buf, pass_codes, NULL); err = ftp_send_command(s, buf, pass_codes, NULL);
} else } else
return AVERROR(EACCES); return AVERROR(EACCES);
...@@ -579,7 +569,9 @@ static int ftp_abort(URLContext *h) ...@@ -579,7 +569,9 @@ static int ftp_abort(URLContext *h)
static int ftp_open(URLContext *h, const char *url, int flags) static int ftp_open(URLContext *h, const char *url, int flags)
{ {
char proto[10], path[MAX_URL_SIZE]; char proto[10], path[MAX_URL_SIZE], credencials[MAX_URL_SIZE];
const char *tok_user = NULL, *tok_pass = NULL;
char *end = NULL;
int err; int err;
FTPContext *s = h->priv_data; FTPContext *s = h->priv_data;
...@@ -590,12 +582,25 @@ static int ftp_open(URLContext *h, const char *url, int flags) ...@@ -590,12 +582,25 @@ static int ftp_open(URLContext *h, const char *url, int flags)
s->position = 0; s->position = 0;
av_url_split(proto, sizeof(proto), av_url_split(proto, sizeof(proto),
s->credencials, sizeof(s->credencials), credencials, sizeof(credencials),
s->hostname, sizeof(s->hostname), s->hostname, sizeof(s->hostname),
&s->server_control_port, &s->server_control_port,
path, sizeof(path), path, sizeof(path),
url); url);
tok_user = av_strtok(credencials, ":", &end);
tok_pass = av_strtok(end, ":", &end);
if (!tok_user) {
tok_user = "anonymous";
tok_pass = av_x_if_null(s->anonymous_password, "nopassword");
}
s->user = av_strdup(tok_user);
s->password = av_strdup(tok_pass);
if (!s->user || (tok_pass && !s->password)) {
err = AVERROR(ENOMEM);
goto fail;
}
if (s->server_control_port < 0 || s->server_control_port > 65535) if (s->server_control_port < 0 || s->server_control_port > 65535)
s->server_control_port = 21; s->server_control_port = 21;
...@@ -619,8 +624,7 @@ static int ftp_open(URLContext *h, const char *url, int flags) ...@@ -619,8 +624,7 @@ static int ftp_open(URLContext *h, const char *url, int flags)
fail: fail:
av_log(h, AV_LOG_ERROR, "FTP open failed\n"); av_log(h, AV_LOG_ERROR, "FTP open failed\n");
ffurl_closep(&s->conn_control); ftp_close(h);
ffurl_closep(&s->conn_data);
return err; return err;
} }
...@@ -755,9 +759,13 @@ static int ftp_write(URLContext *h, const unsigned char *buf, int size) ...@@ -755,9 +759,13 @@ static int ftp_write(URLContext *h, const unsigned char *buf, int size)
static int ftp_close(URLContext *h) static int ftp_close(URLContext *h)
{ {
FTPContext *s = h->priv_data;
av_dlog(h, "ftp protocol close\n"); av_dlog(h, "ftp protocol close\n");
ftp_close_both_connections(h->priv_data); ftp_close_both_connections(s);
av_freep(&s->user);
av_freep(&s->password);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment