1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-02-09 14:14:39 +02:00

ftp: credentials moved into FTPContext

FTP server may disconnect client.

This commit stores credentials for future reconnect.
This commit is contained in:
Lukasz Marek 2013-05-30 04:11:21 +02:00
parent 80cce899f6
commit e46e49e31d

View File

@ -20,7 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/avassert.h"
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "network.h" #include "network.h"
@ -29,6 +28,7 @@
#include "libavutil/opt.h" #include "libavutil/opt.h"
#define CONTROL_BUFFER_SIZE 1024 #define CONTROL_BUFFER_SIZE 1024
#define CREDENTIALS_BUFFER_SIZE 128
typedef enum { typedef enum {
UNKNOWN, UNKNOWN,
@ -49,6 +49,7 @@ typedef struct {
uint8_t *control_buf_ptr, *control_buf_end; uint8_t *control_buf_ptr, *control_buf_end;
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. */
char hostname[512]; /**< Server address. */ char hostname[512]; /**< Server address. */
char credencials[CREDENTIALS_BUFFER_SIZE]; /**< Authentication data */
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. */
@ -187,50 +188,38 @@ static int ftp_status(FTPContext *s, int *major, int *minor, int *extra, char **
return result; return result;
} }
static int ftp_auth(FTPContext *s, char *auth) static int ftp_auth(FTPContext *s)
{ {
const char *user = NULL, *pass = NULL; const char *user = NULL, *pass = NULL;
char *end = NULL, buf[CONTROL_BUFFER_SIZE]; char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE];
int err; int err;
av_assert2(auth);
user = av_strtok(auth, ":", &end); /* Authentication may be repeated, original string has to be saved */
av_strlcpy(credencials, s->credencials, sizeof(credencials));
user = av_strtok(credencials, ":", &end);
pass = av_strtok(end, ":", &end); pass = av_strtok(end, ":", &end);
if (user) { if (!user) {
snprintf(buf, sizeof(buf), "USER %s\r\n", user); user = "anonymous";
if ((err = ffurl_write(s->conn_control, buf, strlen(buf))) < 0) pass = s->anonymous_password ? s->anonymous_password : "nopassword";
return err; }
ftp_status(s, &err, NULL, NULL, NULL, -1);
if (err == 3) { snprintf(buf, sizeof(buf), "USER %s\r\n", user);
if (pass) { if ((err = ffurl_write(s->conn_control, buf, strlen(buf))) < 0)
snprintf(buf, sizeof(buf), "PASS %s\r\n", pass); return err;
if ((err = ffurl_write(s->conn_control, buf, strlen(buf))) < 0) ftp_status(s, &err, NULL, NULL, NULL, -1);
return err; if (err == 3) {
ftp_status(s, &err, NULL, NULL, NULL, -1); if (pass) {
} else snprintf(buf, sizeof(buf), "PASS %s\r\n", pass);
return AVERROR(EACCES);
}
if (err != 2) {
return AVERROR(EACCES);
}
} else {
const char* command = "USER anonymous\r\n";
if ((err = ffurl_write(s->conn_control, command, strlen(command))) < 0)
return err;
ftp_status(s, &err, NULL, NULL, NULL, -1);
if (err == 3) {
if (s->anonymous_password) {
snprintf(buf, sizeof(buf), "PASS %s\r\n", s->anonymous_password);
} else
snprintf(buf, sizeof(buf), "PASS nopassword\r\n");
if ((err = ffurl_write(s->conn_control, buf, strlen(buf))) < 0) if ((err = ffurl_write(s->conn_control, buf, strlen(buf))) < 0)
return err; return err;
ftp_status(s, &err, NULL, NULL, NULL, -1); ftp_status(s, &err, NULL, NULL, NULL, -1);
} } else
if (err != 2) {
return AVERROR(EACCES); return AVERROR(EACCES);
} }
if (err != 2) {
return AVERROR(EACCES);
} }
return 0; return 0;
@ -415,7 +404,7 @@ static int ftp_reconnect_data_connection(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], auth[1024], path[MAX_URL_SIZE], buf[CONTROL_BUFFER_SIZE], opts_format[20]; char proto[10], path[MAX_URL_SIZE], buf[CONTROL_BUFFER_SIZE], opts_format[20];
AVDictionary *opts = NULL; AVDictionary *opts = NULL;
int port, err; int port, err;
FTPContext *s = h->priv_data; FTPContext *s = h->priv_data;
@ -428,7 +417,7 @@ static int ftp_open(URLContext *h, const char *url, int flags)
s->conn_control_interrupt_cb.callback = ftp_conn_control_block_control; s->conn_control_interrupt_cb.callback = ftp_conn_control_block_control;
av_url_split(proto, sizeof(proto), av_url_split(proto, sizeof(proto),
auth, sizeof(auth), s->credencials, sizeof(s->credencials),
s->hostname, sizeof(s->hostname), s->hostname, sizeof(s->hostname),
&port, &port,
path, sizeof(path), path, sizeof(path),
@ -456,7 +445,7 @@ static int ftp_open(URLContext *h, const char *url, int flags)
goto fail; goto fail;
} }
if ((err = ftp_auth(s, auth)) < 0) if ((err = ftp_auth(s)) < 0)
goto fail; goto fail;
if ((err = ftp_type(s)) < 0) if ((err = ftp_type(s)) < 0)