urlencode all filenames, foldernames, username and password

This commit is contained in:
josch
2015-01-16 08:49:23 +01:00
parent 3bff628066
commit f0a55615ae
11 changed files with 117 additions and 27 deletions

2
TODO
View File

@@ -26,8 +26,6 @@
- add an option to only call device/get_status in configurable intervals - add an option to only call device/get_status in configurable intervals
- add an option to make file cache size configurable - add an option to make file cache size configurable
- write man pages - write man pages
- username and password must be urlencoded in
mfapi/apicalls/user_get_session_token.c
- implement truncate (problem: zero byte files are not allowed at the remote) - implement truncate (problem: zero byte files are not allowed at the remote)
- move uploading of files from release() to flush() because the return - move uploading of files from release() to flush() because the return
value of release is ignored and because the calling close() returns value of release is ignored and because the calling close() returns

View File

@@ -612,7 +612,8 @@ int mediafirefs_release(const char *path, struct fuse_file_info *file_info)
// hash exists, so use upload/instant // hash exists, so use upload/instant
retval = mfconn_api_upload_instant(ctx->conn, NULL, retval = mfconn_api_upload_instant(ctx->conn, NULL,
file_name, hash, size, folder_key); file_name, hash, size,
folder_key);
fclose(fh); fclose(fh);
free(temp1); free(temp1);
@@ -630,7 +631,7 @@ int mediafirefs_release(const char *path, struct fuse_file_info *file_info)
// hash does not exist, so do full upload // hash does not exist, so do full upload
upload_key = NULL; upload_key = NULL;
retval = mfconn_api_upload_simple(ctx->conn, folder_key, retval = mfconn_api_upload_simple(ctx->conn, folder_key,
fh, file_name, &upload_key); fh, file_name, &upload_key);
fclose(fh); fclose(fh);
free(temp1); free(temp1);

View File

@@ -145,11 +145,13 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
int mfconn_api_upload_check(mfconn * conn, const char *filename, int mfconn_api_upload_check(mfconn * conn, const char *filename,
const char *hash, const char *hash,
uint64_t size, const char *folder_key, uint64_t size, const char *folder_key,
struct mfconn_upload_check_result *result); struct mfconn_upload_check_result
*result);
int mfconn_api_upload_instant(mfconn * conn, const char *quick_key, int mfconn_api_upload_instant(mfconn * conn, const char *quick_key,
const char *filename, const char *hash, const char *filename,
uint64_t size, const char *folder_key); const char *hash, uint64_t size,
const char *folder_key);
int mfconn_api_upload_simple(mfconn * conn, const char *folderkey, int mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
FILE * fh, const char *file_name, FILE * fh, const char *file_name,

View File

@@ -32,6 +32,7 @@ int mfconn_api_file_update(mfconn * conn, const char *quickkey,
int retval; int retval;
mfhttp *http; mfhttp *http;
int i; int i;
char *filename_urlenc;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -49,11 +50,17 @@ int mfconn_api_file_update(mfconn * conn, const char *quickkey,
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
filename_urlenc = urlencode(filename);
if (filename_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
api_call = mfconn_create_signed_get(conn, 0, "file/update.php", api_call = mfconn_create_signed_get(conn, 0, "file/update.php",
"?quick_key=%s" "?quick_key=%s"
"&filename=%s" "&filename=%s"
"&response_format=json", quickkey, "&response_format=json", quickkey,
filename); filename_urlenc);
free(filename_urlenc);
if (api_call == NULL) { if (api_call == NULL) {
fprintf(stderr, "mfconn_create_signed_get failed\n"); fprintf(stderr, "mfconn_create_signed_get failed\n");
return -1; return -1;

View File

@@ -32,6 +32,7 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
int retval; int retval;
mfhttp *http; mfhttp *http;
int i; int i;
char *name_urlenc;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -47,18 +48,24 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
} }
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
name_urlenc = urlencode(name);
if (name_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
if (parent != NULL) { if (parent != NULL) {
api_call = api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php", mfconn_create_signed_get(conn, 0, "folder/create.php",
"?parent_key=%s&foldername=%s" "?parent_key=%s&foldername=%s"
"&response_format=json", parent, "&response_format=json", parent,
name); name_urlenc);
} else { } else {
api_call = api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php", mfconn_create_signed_get(conn, 0, "folder/create.php",
"?foldername=%s&response_format=json", "?foldername=%s&response_format=json",
name); name_urlenc);
} }
free(name_urlenc);
if (api_call == NULL) { if (api_call == NULL) {
fprintf(stderr, "mfconn_create_signed_get failed\n"); fprintf(stderr, "mfconn_create_signed_get failed\n");
return -1; return -1;

View File

@@ -32,6 +32,7 @@ int mfconn_api_folder_update(mfconn * conn, const char *folder_key,
int retval; int retval;
mfhttp *http; mfhttp *http;
int i; int i;
char *foldername_urlenc;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -49,11 +50,17 @@ int mfconn_api_folder_update(mfconn * conn, const char *folder_key,
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
foldername_urlenc = urlencode(foldername);
if (foldername_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
api_call = mfconn_create_signed_get(conn, 0, "folder/update.php", api_call = mfconn_create_signed_get(conn, 0, "folder/update.php",
"?folder_key=%s" "?folder_key=%s"
"&foldername=%s" "&foldername=%s"
"&response_format=json", "&response_format=json",
folder_key, foldername); folder_key, foldername_urlenc);
free(foldername_urlenc);
if (api_call == NULL) { if (api_call == NULL) {
fprintf(stderr, "mfconn_create_signed_get failed\n"); fprintf(stderr, "mfconn_create_signed_get failed\n");
return -1; return -1;

View File

@@ -22,22 +22,24 @@
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "../../utils/http.h" #include "../../utils/http.h"
#include "../mfconn.h" #include "../mfconn.h"
#include "../patch.h"
#include "../apicalls.h" // IWYU pragma: keep #include "../apicalls.h" // IWYU pragma: keep
static int _decode_upload_check(mfhttp * conn, void *data); static int _decode_upload_check(mfhttp * conn, void *data);
int mfconn_api_upload_check(mfconn * conn, const char *filename, const char *hash, int mfconn_api_upload_check(mfconn * conn, const char *filename,
uint64_t size, const char *folder_key, const char *hash, uint64_t size,
const char *folder_key,
struct mfconn_upload_check_result *result) struct mfconn_upload_check_result *result)
{ {
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i; int i;
char *filename_urlenc;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -58,13 +60,19 @@ int mfconn_api_upload_check(mfconn * conn, const char *filename, const char *has
} }
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
filename_urlenc = urlencode(filename);
if (filename_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
api_call = mfconn_create_signed_get(conn, 0, "upload/check.php", api_call = mfconn_create_signed_get(conn, 0, "upload/check.php",
"?response_format=json" "?response_format=json"
"&filename=%s" "&filename=%s"
"&size=%" PRIu64 "&size=%" PRIu64
"&hash=%s" "&hash=%s"
"&folder_key=%s", filename, "&folder_key=%s", filename_urlenc,
size, hash, folder_key); size, hash, folder_key);
free(filename_urlenc);
if (api_call == NULL) { if (api_call == NULL) {
fprintf(stderr, "mfconn_create_signed_get failed\n"); fprintf(stderr, "mfconn_create_signed_get failed\n");
return -1; return -1;
@@ -98,7 +106,7 @@ int mfconn_api_upload_check(mfconn * conn, const char *filename, const char *has
return retval; return retval;
} }
static int _decode_upload_check(mfhttp * conn, void *data) static int _decode_upload_check(mfhttp * conn, void *data)
{ {
json_error_t error; json_error_t error;
json_t *obj; json_t *obj;
@@ -160,7 +168,8 @@ static int _decode_upload_check(mfhttp * conn, void *data)
return -1; return -1;
} }
if (!json_is_string(obj)) { if (!json_is_string(obj)) {
fprintf(stderr, "response/in_account is not expected type string\n"); fprintf(stderr,
"response/in_account is not expected type string\n");
json_decref(root); json_decref(root);
return -1; return -1;
} }
@@ -206,7 +215,8 @@ static int _decode_upload_check(mfhttp * conn, void *data)
return -1; return -1;
} }
if (!json_is_string(obj)) { if (!json_is_string(obj)) {
fprintf(stderr, "response/different_hash is not expected type string\n"); fprintf(stderr,
"response/different_hash is not expected type string\n");
json_decref(root); json_decref(root);
return -1; return -1;
} }

View File

@@ -18,8 +18,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdint.h>
#include "../../utils/http.h" #include "../../utils/http.h"
#include "../mfconn.h" #include "../mfconn.h"
@@ -33,6 +33,7 @@ int mfconn_api_upload_instant(mfconn * conn, const char *quick_key,
int retval; int retval;
mfhttp *http; mfhttp *http;
int i; int i;
char *filename_urlenc;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -51,17 +52,22 @@ int mfconn_api_upload_instant(mfconn * conn, const char *quick_key,
"&hash=%s" "&hash=%s"
"&response_format=json", "&response_format=json",
quick_key, size, hash); quick_key, size, hash);
} else if (filename != NULL && filename[0] != '\0' } else if (filename != NULL && filename[0] != '\0' && folder_key != 0) {
&& folder_key != 0) {
// upload a new file // upload a new file
filename_urlenc = urlencode(filename);
if (filename_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
api_call = mfconn_create_signed_get(conn, 0, "upload/instant.php", api_call = mfconn_create_signed_get(conn, 0, "upload/instant.php",
"?folder_key=%s" "?folder_key=%s"
"&filename=%s" "&filename=%s"
"&size=%" PRIu64 "&size=%" PRIu64
"&hash=%s" "&hash=%s"
"&response_format=json", "&response_format=json",
folder_key, filename, size, folder_key, filename_urlenc,
hash); size, hash);
free(filename_urlenc);
} else { } else {
fprintf(stderr, "you must either pass a quick_key or a filename " fprintf(stderr, "you must either pass a quick_key or a filename "
"and folder_key\n"); "and folder_key\n");
@@ -75,7 +81,8 @@ int mfconn_api_upload_instant(mfconn * conn, const char *quick_key,
http = http_create(); http = http_create();
retval = retval =
http_get_buf(http, api_call, mfapi_decode_common, "upload/instant"); http_get_buf(http, api_call, mfapi_decode_common,
"upload/instant");
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);

View File

@@ -55,6 +55,8 @@ mfconn_api_user_get_session_token(mfconn * conn, const char *server,
struct user_get_session_token_response response; struct user_get_session_token_response response;
mfhttp *http; mfhttp *http;
int i; int i;
char *username_urlenc;
char *password_urlenc;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -81,15 +83,26 @@ mfconn_api_user_get_session_token(mfconn * conn, const char *server,
mfconn_create_user_signature(conn, username, password, app_id, mfconn_create_user_signature(conn, username, password, app_id,
app_key); app_key);
// FIXME: username and password have to be urlencoded (maybe using username_urlenc = urlencode(username);
// curl_easy_escape) if (username_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
password_urlenc = urlencode(password);
if (password_urlenc == NULL) {
fprintf(stderr, "urlencode failed\n");
return -1;
}
post_args = strdup_printf("email=%s" post_args = strdup_printf("email=%s"
"&password=%s" "&password=%s"
"&application_id=%d" "&application_id=%d"
"&signature=%s" "&signature=%s"
"&token_version=2" "&token_version=2"
"&response_format=json", "&response_format=json",
username, password, app_id, user_signature); username_urlenc, password_urlenc, app_id,
user_signature);
free(username_urlenc);
free(password_urlenc);
free((void *)user_signature); free((void *)user_signature);
http = http_create(); http = http_create();

View File

@@ -328,3 +328,39 @@ http_post_file(mfhttp * conn, const char *url, FILE * fh,
retval = data_handler(conn, data); retval = data_handler(conn, data);
return retval; return retval;
} }
// we roll our own urlencode function because curl_easy_escape requires a curl
// handle
char *urlencode(const char *inp)
{
char *buf;
char *bufp;
char hex[] = "0123456789abcdef";
// allocating three times the length of the input because in the worst
// case each character must be urlencoded and add a byte for the
// terminating zero
bufp = buf = (char *)malloc(strlen(inp) * 3 + 1);
if (buf == NULL) {
fprintf(stderr, "malloc failed\n");
return NULL;
}
while (*inp) {
if ((*inp >= '0' && *inp <= '9')
|| (*inp >= 'A' && *inp <= 'Z')
|| (*inp >= 'a' && *inp <= 'z')
|| *inp == '-' || *inp == '_' || *inp == '.' || *inp == '~') {
*bufp++ = *inp;
} else {
*bufp++ = '%';
*bufp++ = hex[(*inp >> 4) & 0xf];
*bufp++ = hex[*inp & 0xf];
}
inp++;
}
*bufp = '\0';
return buf;
}

View File

@@ -46,4 +46,6 @@ int http_post_file(mfhttp * conn, const char *url, FILE * fh,
int (*data_handler) (mfhttp * conn, void *data), int (*data_handler) (mfhttp * conn, void *data),
void *data); void *data);
char *urlencode(const char *input);
#endif #endif