Browse code

lavf/ftp: parse user and password once

Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>

Lukasz Marek authored on 2015/04/03 02:22:00
Showing 1 changed files
... ...
@@ -26,7 +26,6 @@
26 26
 #include "libavutil/bprint.h"
27 27
 
28 28
 #define CONTROL_BUFFER_SIZE 1024
29
-#define CREDENTIALS_BUFFER_SIZE 128
30 29
 
31 30
 typedef enum {
32 31
     UNKNOWN,
... ...
@@ -45,7 +44,8 @@ typedef struct {
45 45
     int server_data_port;                        /**< Data connection port opened by server, -1 on error. */
46 46
     int server_control_port;                     /**< Control connection port, default is 21 */
47 47
     char hostname[512];                          /**< Server address. */
48
-    char credencials[CREDENTIALS_BUFFER_SIZE];   /**< Authentication data */
48
+    char *user;                                  /**< Server user */
49
+    char *password;                              /**< Server user's password */
49 50
     char path[MAX_URL_SIZE];                     /**< Path to resource on server. */
50 51
     int64_t filesize;                            /**< Size of file on server, -1 on error. */
51 52
     int64_t position;                            /**< Current position, calculated. */
... ...
@@ -72,6 +72,8 @@ static const AVClass ftp_context_class = {
72 72
     .version        = LIBAVUTIL_VERSION_INT,
73 73
 };
74 74
 
75
+static int ftp_close(URLContext *h);
76
+
75 77
 static int ftp_getc(FTPContext *s)
76 78
 {
77 79
     int len;
... ...
@@ -213,28 +215,16 @@ static void ftp_close_both_connections(FTPContext *s)
213 213
 
214 214
 static int ftp_auth(FTPContext *s)
215 215
 {
216
-    const char *user = NULL, *pass = NULL;
217
-    char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE];
216
+    char buf[CONTROL_BUFFER_SIZE];
218 217
     int err;
219 218
     static const int user_codes[] = {331, 230, 0};
220 219
     static const int pass_codes[] = {230, 0};
221 220
 
222
-    /* Authentication may be repeated, original string has to be saved */
223
-    av_strlcpy(credencials, s->credencials, sizeof(credencials));
224
-
225
-    user = av_strtok(credencials, ":", &end);
226
-    pass = av_strtok(end, ":", &end);
227
-
228
-    if (!user) {
229
-        user = "anonymous";
230
-        pass = s->anonymous_password ? s->anonymous_password : "nopassword";
231
-    }
232
-
233
-    snprintf(buf, sizeof(buf), "USER %s\r\n", user);
221
+    snprintf(buf, sizeof(buf), "USER %s\r\n", s->user);
234 222
     err = ftp_send_command(s, buf, user_codes, NULL);
235 223
     if (err == 331) {
236
-        if (pass) {
237
-            snprintf(buf, sizeof(buf), "PASS %s\r\n", pass);
224
+        if (s->password) {
225
+            snprintf(buf, sizeof(buf), "PASS %s\r\n", s->password);
238 226
             err = ftp_send_command(s, buf, pass_codes, NULL);
239 227
         } else
240 228
             return AVERROR(EACCES);
... ...
@@ -579,7 +569,9 @@ static int ftp_abort(URLContext *h)
579 579
 
580 580
 static int ftp_open(URLContext *h, const char *url, int flags)
581 581
 {
582
-    char proto[10], path[MAX_URL_SIZE];
582
+    char proto[10], path[MAX_URL_SIZE], credencials[MAX_URL_SIZE];
583
+    const char *tok_user = NULL, *tok_pass = NULL;
584
+    char *end = NULL;
583 585
     int err;
584 586
     FTPContext *s = h->priv_data;
585 587
 
... ...
@@ -590,12 +582,25 @@ static int ftp_open(URLContext *h, const char *url, int flags)
590 590
     s->position = 0;
591 591
 
592 592
     av_url_split(proto, sizeof(proto),
593
-                 s->credencials, sizeof(s->credencials),
593
+                 credencials, sizeof(credencials),
594 594
                  s->hostname, sizeof(s->hostname),
595 595
                  &s->server_control_port,
596 596
                  path, sizeof(path),
597 597
                  url);
598 598
 
599
+    tok_user = av_strtok(credencials, ":", &end);
600
+    tok_pass = av_strtok(end, ":", &end);
601
+    if (!tok_user) {
602
+        tok_user = "anonymous";
603
+        tok_pass = av_x_if_null(s->anonymous_password, "nopassword");
604
+    }
605
+    s->user = av_strdup(tok_user);
606
+    s->password = av_strdup(tok_pass);
607
+    if (!s->user || (tok_pass && !s->password)) {
608
+        err = AVERROR(ENOMEM);
609
+        goto fail;
610
+    }
611
+
599 612
     if (s->server_control_port < 0 || s->server_control_port > 65535)
600 613
         s->server_control_port = 21;
601 614
 
... ...
@@ -619,8 +624,7 @@ static int ftp_open(URLContext *h, const char *url, int flags)
619 619
 
620 620
   fail:
621 621
     av_log(h, AV_LOG_ERROR, "FTP open failed\n");
622
-    ffurl_closep(&s->conn_control);
623
-    ffurl_closep(&s->conn_data);
622
+    ftp_close(h);
624 623
     return err;
625 624
 }
626 625
 
... ...
@@ -755,9 +759,13 @@ static int ftp_write(URLContext *h, const unsigned char *buf, int size)
755 755
 
756 756
 static int ftp_close(URLContext *h)
757 757
 {
758
+    FTPContext *s = h->priv_data;
759
+
758 760
     av_dlog(h, "ftp protocol close\n");
759 761
 
760
-    ftp_close_both_connections(h->priv_data);
762
+    ftp_close_both_connections(s);
763
+    av_freep(&s->user);
764
+    av_freep(&s->password);
761 765
 
762 766
     return 0;
763 767
 }