mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Removing no longer working OneDrive code
Source commit: 8a28dd98ba1cf2216dbd176900d23c8acf13685c
This commit is contained in:
@@ -200,13 +200,6 @@ typedef struct {
|
||||
char *h_a1;
|
||||
/* Part of the RHS of the response digest. */
|
||||
char *response_rhs;
|
||||
#ifdef WINSCP
|
||||
char * passport_auth_header;
|
||||
char * passport_cookies_header;
|
||||
/* In the current implementation, we actually possibly never reuse these two fields */
|
||||
ne_uri passport_login_uri;
|
||||
char * passport_cookies;
|
||||
#endif
|
||||
} auth_session;
|
||||
|
||||
struct auth_request {
|
||||
@@ -229,9 +222,6 @@ struct auth_request {
|
||||
#define AUTH_FLAG_VERIFY_NON40x (0x0002)
|
||||
/* Used for broken the connection-based auth schemes. */
|
||||
#define AUTH_FLAG_CONN_AUTH (0x0004)
|
||||
#ifdef WINSCP
|
||||
#define AUTH_FLAG_FULL_HEADER (0x0008)
|
||||
#endif
|
||||
|
||||
struct auth_protocol {
|
||||
unsigned id; /* public NE_AUTH_* id. */
|
||||
@@ -247,11 +237,7 @@ struct auth_protocol {
|
||||
* message to the error buffer 'errmsg'. */
|
||||
int (*challenge)(auth_session *sess, int attempt,
|
||||
struct auth_challenge *chall,
|
||||
const char *target, ne_buffer **errmsg
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
);
|
||||
const char *target, ne_buffer **errmsg);
|
||||
|
||||
/* Return the string to send in the -Authenticate request header:
|
||||
* (ne_malloc-allocated, NUL-terminated string) */
|
||||
@@ -320,24 +306,6 @@ static void clean_session(auth_session *sess)
|
||||
if (sess->ntlm_token) zero_and_free(sess->ntlm_token);
|
||||
if (sess->ntlm_password) zero_and_free(sess->ntlm_password);
|
||||
#endif
|
||||
#ifdef WINSCP
|
||||
ne_uri_free(&sess->passport_login_uri);
|
||||
if (sess->passport_auth_header)
|
||||
{
|
||||
ne_free(sess->passport_auth_header);
|
||||
sess->passport_auth_header = NULL;
|
||||
}
|
||||
if (sess->passport_cookies_header)
|
||||
{
|
||||
ne_free(sess->passport_cookies_header);
|
||||
sess->passport_cookies_header = NULL;
|
||||
}
|
||||
if (sess->passport_cookies)
|
||||
{
|
||||
ne_free(sess->passport_cookies);
|
||||
sess->passport_cookies = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
sess->protocol = NULL;
|
||||
}
|
||||
@@ -402,11 +370,7 @@ static char *get_scope_path(const char *uri)
|
||||
* Returns 0 if an valid challenge, else non-zero. */
|
||||
static int basic_challenge(auth_session *sess, int attempt,
|
||||
struct auth_challenge *parms,
|
||||
const char *target, ne_buffer **errmsg
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
)
|
||||
const char *target, ne_buffer **errmsg)
|
||||
{
|
||||
char *tmp, password[ABUFSIZE];
|
||||
|
||||
@@ -591,11 +555,7 @@ static int continue_negotiate(auth_session *sess, const char *token,
|
||||
* if challenge is accepted. */
|
||||
static int negotiate_challenge(auth_session *sess, int attempt,
|
||||
struct auth_challenge *chall,
|
||||
const char *target, ne_buffer **errmsg
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
)
|
||||
const char *target, ne_buffer **errmsg)
|
||||
{
|
||||
const char *token = chall->opaque;
|
||||
|
||||
@@ -694,11 +654,7 @@ static int continue_sspi(auth_session *sess, int ntlm, const char *hdr)
|
||||
|
||||
static int sspi_challenge(auth_session *sess, int attempt,
|
||||
struct auth_challenge *parms,
|
||||
const char *target, ne_buffer **errmsg
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
)
|
||||
const char *target, ne_buffer **errmsg)
|
||||
{
|
||||
int ntlm = ne_strcasecmp(parms->protocol->name, "NTLM") == 0;
|
||||
|
||||
@@ -825,11 +781,7 @@ static int parse_type2_message(tSmbNtlmAuthChallenge *challenge, const char *blo
|
||||
|
||||
static int ntlm_challenge(auth_session *sess, int attempt,
|
||||
struct auth_challenge *parms,
|
||||
const char *target, ne_buffer **errmsg
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
)
|
||||
const char *target, ne_buffer **errmsg)
|
||||
{
|
||||
NE_DEBUG_WINSCP_CONTEXT(sess->sess);
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "auth: NTLM challenge (state %d).\n",
|
||||
@@ -984,11 +936,7 @@ static char *get_digest_h_urp(auth_session *sess, ne_buffer **errmsg,
|
||||
* else non-zero. */
|
||||
static int digest_challenge(auth_session *sess, int attempt,
|
||||
struct auth_challenge *parms,
|
||||
const char *target, ne_buffer **errmsg
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
)
|
||||
const char *target, ne_buffer **errmsg)
|
||||
{
|
||||
NE_DEBUG_WINSCP_CONTEXT(sess->sess);
|
||||
char *p, *h_urp = NULL;
|
||||
@@ -1400,369 +1348,6 @@ static int verify_digest_response(struct auth_request *req, auth_session *sess,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WINSCP
|
||||
|
||||
#define PASSPORT_REQ_ID "http://www.webdav.org/neon/hooks/http-passport-req"
|
||||
#define PASSPORT_NAME "Passport1.4"
|
||||
|
||||
struct aux_request_init_data
|
||||
{
|
||||
ne_aux_request_init aux_request_init;
|
||||
void * userdata;
|
||||
};
|
||||
|
||||
static void free_aux_request_init(void * cookie)
|
||||
{
|
||||
ne_free(cookie);
|
||||
}
|
||||
|
||||
void ne_set_aux_request_init(ne_session * sess, ne_aux_request_init aux_request_init, void * userdata)
|
||||
{
|
||||
struct aux_request_init_data * data = ne_malloc(sizeof(*data));
|
||||
data->aux_request_init = aux_request_init;
|
||||
data->userdata = userdata;
|
||||
ne_set_session_private(sess, PASSPORT_REQ_ID, data);
|
||||
ne_hook_destroy_session(sess, free_aux_request_init, data);
|
||||
}
|
||||
|
||||
int is_passport_challenge(ne_request *req, const ne_status *status)
|
||||
{
|
||||
const char *auth = ne_get_response_header(req, "WWW-Authenticate");
|
||||
return
|
||||
(status->code == 302) &&
|
||||
(auth != NULL) &&
|
||||
(ne_strncasecmp(auth, PASSPORT_NAME, strlen(PASSPORT_NAME)) == 0);
|
||||
}
|
||||
|
||||
static int passport_challenge(auth_session *sess, int attempt,
|
||||
struct auth_challenge *parms,
|
||||
const char *uri, ne_buffer **errmsg,
|
||||
struct auth_request* areq)
|
||||
{
|
||||
char *tmp, password[NE_ABUFSIZ];
|
||||
char *tmp_username;
|
||||
char *tmp_password;
|
||||
const char *auth_hdr;
|
||||
ne_session * sign_session;
|
||||
ne_request * sign_request;
|
||||
int status;
|
||||
ne_session * session = ne_get_session(areq->request);
|
||||
ne_uri orig_uri = {0};
|
||||
char * org_url;
|
||||
int result;
|
||||
|
||||
if (sess->passport_auth_header == NULL)
|
||||
{
|
||||
struct aux_request_init_data * init_data = ne_get_session_private(session, PASSPORT_REQ_ID);
|
||||
|
||||
if (init_data == NULL)
|
||||
{
|
||||
challenge_error(errmsg, _("No init ptr"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
clean_session(sess);
|
||||
|
||||
if (sess->passport_login_uri.host == NULL)
|
||||
{
|
||||
ne_session * nexus_session;
|
||||
ne_request * nexus_request;
|
||||
int status;
|
||||
const char * host = "nexus.passport.com";
|
||||
const char * scheme = "https";
|
||||
int result = 0;
|
||||
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "Retrieving Passport Nexus URL");
|
||||
|
||||
nexus_session = ne_session_create(scheme, host, ne_uri_defaultport(scheme));
|
||||
nexus_request = ne_request_create(nexus_session, "GET", "/rdr/pprdr.asp");
|
||||
init_data->aux_request_init(nexus_session, nexus_request, init_data->userdata);
|
||||
status = ne_request_dispatch(nexus_request);
|
||||
|
||||
if (status != NE_OK)
|
||||
{
|
||||
challenge_error(errmsg, _("Error contacting %s: %s"), host, ne_get_error(nexus_session));
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * urls = ne_get_response_header(nexus_request, "PassportURLs");
|
||||
if (urls == NULL)
|
||||
{
|
||||
challenge_error(errmsg, _("Missing PassportURLs header"));
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char * buf, * pnt, * key, * val;
|
||||
pnt = buf = ne_strdup(urls);
|
||||
while ((sess->passport_login_uri.host == NULL) &&
|
||||
(tokenize(&pnt, &key, &val, NULL, 0) == 0))
|
||||
{
|
||||
if (ne_strcasecmp(key, "DALogin") == 0)
|
||||
{
|
||||
char * uri = ne_concat(scheme, "://", val, NULL);
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "Passport Nexus URL is %s", uri);
|
||||
ne_uri_parse(uri, &sess->passport_login_uri);
|
||||
if (sess->passport_login_uri.port == 0)
|
||||
{
|
||||
sess->passport_login_uri.port = ne_uri_defaultport(sess->passport_login_uri.scheme);
|
||||
}
|
||||
ne_free(uri);
|
||||
}
|
||||
}
|
||||
|
||||
ne_free(buf);
|
||||
|
||||
if (sess->passport_login_uri.host == NULL)
|
||||
{
|
||||
challenge_error(errmsg, _("Missing DALogin URL"));
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ne_request_destroy(nexus_request);
|
||||
ne_session_destroy(nexus_session);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
auth_hdr = ne_get_response_header(areq->request, "WWW-Authenticate");
|
||||
if (auth_hdr == NULL)
|
||||
{
|
||||
challenge_error(errmsg, _("missing WWW-Authenticate header"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (get_credentials(sess, errmsg, attempt, parms, password)) {
|
||||
/* Failed to get credentials */
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp_username = ne_path_escape(sess->username);
|
||||
tmp_password = ne_path_escape(password);
|
||||
|
||||
/* There must be some, othewise we won't be here */
|
||||
auth_hdr = strchr(auth_hdr, ' ');
|
||||
if (auth_hdr == NULL) {
|
||||
challenge_error(errmsg, _("missing space in WWW-Authenticate header"));
|
||||
return -1;
|
||||
}
|
||||
while (*auth_hdr == ' ') auth_hdr++;
|
||||
|
||||
ne_fill_server_uri(session, &orig_uri);
|
||||
orig_uri.path = ne_strdup(areq->target);
|
||||
org_url = ne_uri_unparse(&orig_uri);
|
||||
ne_uri_free(&orig_uri);
|
||||
|
||||
tmp =
|
||||
ne_concat(
|
||||
PASSPORT_NAME, " sign-in=", tmp_username, ",pwd=", tmp_password, ",OrgVerb=", areq->method,
|
||||
",OrgUrl=", org_url, ",", auth_hdr, NULL);
|
||||
ne_free(org_url);
|
||||
/* Paranoia. */
|
||||
memset(password, 0, sizeof password);
|
||||
memset(tmp_password, 0, strlen(tmp_password));
|
||||
ne_free(tmp_username);
|
||||
ne_free(tmp_password);
|
||||
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "Signing into Nexus");
|
||||
|
||||
sign_session = ne_session_create(sess->passport_login_uri.scheme, sess->passport_login_uri.host, sess->passport_login_uri.port);
|
||||
sign_request = ne_request_create(sign_session, "GET", sess->passport_login_uri.path);
|
||||
ne_add_request_header(sign_request, "Authorization", tmp);
|
||||
init_data->aux_request_init(sign_session, sign_request, init_data->userdata);
|
||||
status = ne_request_dispatch(sign_request);
|
||||
|
||||
memset(tmp, 0, strlen(tmp));
|
||||
ne_free(tmp);
|
||||
|
||||
result = 0;
|
||||
if (status != NE_OK)
|
||||
{
|
||||
challenge_error(errmsg, _("Error signing into Nexus: %s"), ne_get_error(sign_session));
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * auth_info = ne_get_response_header(sign_request, "Authentication-Info");
|
||||
if (auth_info == NULL)
|
||||
{
|
||||
challenge_error(errmsg, _("Missing Authentication-Info header"));
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int success = -1;
|
||||
|
||||
char * buf, * pnt, * key, * val;
|
||||
pnt = buf = ne_strdup(auth_info);
|
||||
while (((sess->passport_auth_header == NULL) || (success < 0)) &&
|
||||
(tokenize(&pnt, &key, &val, NULL, 1) == 0))
|
||||
{
|
||||
if (val == NULL)
|
||||
{
|
||||
if (ne_strcasecmp(key, PASSPORT_NAME) != 0)
|
||||
{
|
||||
challenge_error(errmsg, _("Wrong Authentication-Info header"));
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
else if (ne_strcasecmp(key, "da-status") == 0)
|
||||
{
|
||||
if (ne_strcasecmp(val, "success") == 0)
|
||||
{
|
||||
success = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
challenge_error(errmsg, _("Authentication failure"));
|
||||
result = -1;
|
||||
success = 0;
|
||||
}
|
||||
}
|
||||
else if (ne_strcasecmp(key, "from-PP") == 0)
|
||||
{
|
||||
sess->passport_auth_header = ne_concat("Authorization: ", PASSPORT_NAME, " ", key, "=", val, "\r\n", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ne_free(buf);
|
||||
|
||||
if ((sess->passport_auth_header == NULL) || (success < 0))
|
||||
{
|
||||
challenge_error(errmsg, _("Cannot parse Nexus response"));
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "Signed into Nexus");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ne_request_destroy(sign_request);
|
||||
ne_session_destroy(sign_session);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *request_passport(auth_session *sess, struct auth_request *req)
|
||||
{
|
||||
return ne_concat(sess->passport_auth_header, sess->passport_cookies_header, NULL);
|
||||
}
|
||||
|
||||
static void lower_case(char * s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < strlen(s); i++)
|
||||
{
|
||||
s[i] = ne_tolower(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int verify_passport_response(struct auth_request *req, auth_session *sess,
|
||||
const char *value)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
{
|
||||
ne_buffer * names = ne_buffer_create();
|
||||
char * buf, * pnt, * key, * val;
|
||||
/* We should really send all cookies, but for now, we send only those we know we have to.
|
||||
ClientCanary cookie is needed for the modify operations (PUT, DELETE, etc). */
|
||||
ne_buffer_zappend(names, "=clientcanary=");
|
||||
pnt = buf = ne_strdup(value);
|
||||
while (tokenize(&pnt, &key, &val, NULL, 1) == 0)
|
||||
{
|
||||
if (val == NULL)
|
||||
{
|
||||
if (ne_strcasecmp(key, PASSPORT_NAME) != 0)
|
||||
{
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "Wrong Authentication-Info header");
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
else if (ne_strcasecmp(key, "tname") == 0)
|
||||
{
|
||||
lower_case(val);
|
||||
ne_buffer_concat(names, val, "=", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ne_free(buf);
|
||||
|
||||
/* We should update cookies based on future responses, for what we preserve list of cookies to cache,
|
||||
but we do not do that atm, so this field is not used actually */
|
||||
sess->passport_cookies = ne_buffer_finish(names);
|
||||
}
|
||||
|
||||
{
|
||||
const char * set_cookies_header = ne_get_response_header(req->request, "Set-Cookie");
|
||||
if (set_cookies_header == NULL)
|
||||
{
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "No Cookies");
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ne_buffer * cookie_header = NULL;
|
||||
char * cookies = ne_strdup(set_cookies_header);
|
||||
char * p = cookies;
|
||||
while (p != NULL)
|
||||
{
|
||||
/* Far from perfect, as it does not distringuish a comma from merged Set-Cookie header [seeadd_response_header],
|
||||
and command e.g. in "expires=Thu, 30-Oct-1980 16:00:00 GMT".
|
||||
But it is good enough for now, when we need only name and value */
|
||||
char * cookie = ne_shave(ne_token(&p, ','), " \t");
|
||||
char * cookie_name = ne_token(&cookie, '=');
|
||||
char * s = ne_concat("=", cookie_name, "=", NULL);
|
||||
lower_case(s);
|
||||
|
||||
if (strstr(sess->passport_cookies, s) != NULL)
|
||||
{
|
||||
char * val = ne_token(&cookie, ';');
|
||||
|
||||
if (cookie_header == NULL)
|
||||
{
|
||||
cookie_header = ne_buffer_create();
|
||||
ne_buffer_zappend(cookie_header, "Cookie: ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ne_buffer_zappend(cookie_header, "; ");
|
||||
}
|
||||
|
||||
ne_buffer_concat(cookie_header, cookie_name, "=", val, NULL);
|
||||
}
|
||||
|
||||
ne_free(s);
|
||||
}
|
||||
|
||||
ne_free(cookies);
|
||||
|
||||
if (cookie_header != NULL)
|
||||
{
|
||||
if (sess->passport_cookies_header != NULL)
|
||||
{
|
||||
ne_free(sess->passport_cookies_header);
|
||||
}
|
||||
ne_buffer_zappend(cookie_header, "\r\n");
|
||||
sess->passport_cookies_header = ne_buffer_finish(cookie_header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const struct auth_protocol protocols[] = {
|
||||
{ NE_AUTH_BASIC, 10, "Basic",
|
||||
basic_challenge, request_basic, NULL,
|
||||
@@ -1787,11 +1372,6 @@ static const struct auth_protocol protocols[] = {
|
||||
{ NE_AUTH_NTLM, 30, "NTLM",
|
||||
ntlm_challenge, request_ntlm, NULL,
|
||||
AUTH_FLAG_OPAQUE_PARAM|AUTH_FLAG_VERIFY_NON40x|AUTH_FLAG_CONN_AUTH },
|
||||
#endif
|
||||
#ifdef WINSCP
|
||||
{ NE_AUTH_PASSPORT, 30, PASSPORT_NAME,
|
||||
passport_challenge, request_passport, verify_passport_response,
|
||||
AUTH_FLAG_FULL_HEADER|AUTH_FLAG_CONN_AUTH /* just a guess */ },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
@@ -1842,11 +1422,7 @@ static void challenge_error(ne_buffer **errbuf, const char *fmt, ...)
|
||||
* Returns 0 if valid challenge was accepted; non-zero if no valid
|
||||
* challenge was found. */
|
||||
static int auth_challenge(auth_session *sess, int attempt, const char *uri,
|
||||
const char *value
|
||||
#ifdef WINSCP
|
||||
, struct auth_request* areq
|
||||
#endif
|
||||
)
|
||||
const char *value)
|
||||
{
|
||||
NE_DEBUG_WINSCP_CONTEXT(sess->sess);
|
||||
char *pnt, *key, *val, *hdr, sep;
|
||||
@@ -1973,11 +1549,7 @@ static int auth_challenge(auth_session *sess, int attempt, const char *uri,
|
||||
for (chall = challenges; chall != NULL; chall = chall->next) {
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Trying %s challenge...\n",
|
||||
chall->protocol->name);
|
||||
if (chall->protocol->challenge(sess, attempt, chall, uri, &errmsg
|
||||
#ifdef WINSCP
|
||||
, areq
|
||||
#endif
|
||||
) == 0) {
|
||||
if (chall->protocol->challenge(sess, attempt, chall, uri, &errmsg) == 0) {
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Accepted %s challenge.\n",
|
||||
chall->protocol->name);
|
||||
sess->protocol = chall->protocol;
|
||||
@@ -2048,18 +1620,7 @@ static void ah_pre_send(ne_request *r, void *cookie, ne_buffer *request)
|
||||
value = sess->protocol->response(sess, req);
|
||||
|
||||
if (value != NULL) {
|
||||
#ifdef WINSCP
|
||||
if (sess->protocol->flags & AUTH_FLAG_FULL_HEADER)
|
||||
{
|
||||
ne_buffer_zappend(request, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
ne_buffer_concat(request, sess->spec->req_hdr, ": ", value, NULL);
|
||||
#ifdef WINSCP
|
||||
}
|
||||
#endif
|
||||
ne_free(value);
|
||||
}
|
||||
}
|
||||
@@ -2119,19 +1680,12 @@ static int ah_post_send(ne_request *req, void *cookie, const ne_status *status)
|
||||
ret = sess->protocol->verify(areq, sess, auth_hdr);
|
||||
}
|
||||
else if ((status->code == sess->spec->status_code ||
|
||||
#ifdef WINSCP
|
||||
is_passport_challenge(req, status) ||
|
||||
#endif
|
||||
(status->code == 401 && sess->context == AUTH_CONNECT)) &&
|
||||
auth_hdr) {
|
||||
/* note above: allow a 401 in response to a CONNECT request
|
||||
* from a proxy since some buggy proxies send that. */
|
||||
NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Got challenge (code %d).\n", status->code);
|
||||
if (!auth_challenge(sess, areq->attempt++, areq->target, auth_hdr
|
||||
#ifdef WINSCP
|
||||
, areq
|
||||
#endif
|
||||
)) {
|
||||
if (!auth_challenge(sess, areq->attempt++, areq->target, auth_hdr)) {
|
||||
ret = NE_RETRY;
|
||||
} else {
|
||||
clean_session(sess);
|
||||
|
||||
@@ -111,10 +111,6 @@ void ne_set_proxy_auth(ne_session *sess, ne_auth_creds creds, void *userdata);
|
||||
|
||||
/* 0x0080: legacy definition of NE_AUTH_DIGEST in 0.31 and earlier */
|
||||
|
||||
#ifdef WINSCP
|
||||
#define NE_AUTH_PASSPORT (0x0080)
|
||||
#endif
|
||||
|
||||
/* The default set of supported protocols, as deemed appropriate for
|
||||
* the given session scheme. The interpretation of this flag may
|
||||
* change across versions, for example with older, less secure
|
||||
@@ -157,12 +153,6 @@ void ne_add_proxy_auth(ne_session *sess, unsigned protocol,
|
||||
|
||||
#ifdef WINSCP
|
||||
void ne_remove_server_auth(ne_session *sess);
|
||||
|
||||
typedef void (*ne_aux_request_init)(ne_session * sess, ne_request * req, void * userdata);
|
||||
|
||||
void ne_set_aux_request_init(ne_session * sess, ne_aux_request_init aux_request_init, void * userdata);
|
||||
|
||||
int is_passport_challenge(ne_request *req, const ne_status *status);
|
||||
#endif
|
||||
|
||||
/* Alternative credentials provider callback, invoked when credentials
|
||||
|
||||
@@ -550,10 +550,6 @@ int ne_mkcol(ne_session *sess, const char *path)
|
||||
ne_lock_using_parent(req, real_path);
|
||||
#endif
|
||||
|
||||
#ifdef WINSCP
|
||||
// New OneDrive interface returns empty text/xml 207 MULTI-STATUS response, ignore it
|
||||
ne_set_request_flag(req, NE_REQFLAG_IGNOREEMPTYXML, 1);
|
||||
#endif
|
||||
ret = ne_simple_request(sess, req);
|
||||
|
||||
ne_free(real_path);
|
||||
|
||||
@@ -35,9 +35,6 @@
|
||||
#include "ne_redirect.h"
|
||||
#include "ne_internal.h"
|
||||
#include "ne_string.h"
|
||||
#ifdef WINSCP
|
||||
#include "ne_auth.h"
|
||||
#endif
|
||||
|
||||
#define REDIRECT_ID "http://www.webdav.org/neon/hooks/http-redirect"
|
||||
|
||||
@@ -63,11 +60,7 @@ static int post_send(ne_request *req, void *userdata, const ne_status *status)
|
||||
uri_free_clear(red);
|
||||
|
||||
if (status->klass == 3
|
||||
#ifdef WINSCP
|
||||
&& !is_passport_challenge(req, status)
|
||||
#endif
|
||||
&& (loc = ne_get_response_location(req, NULL)) != NULL
|
||||
) {
|
||||
&& (loc = ne_get_response_location(req, NULL)) != NULL) {
|
||||
red->uri = loc;
|
||||
return NE_REDIRECT;
|
||||
}
|
||||
|
||||
@@ -291,10 +291,6 @@ typedef enum ne_request_flag_e {
|
||||
* timeout when reading interim
|
||||
* responses. */
|
||||
|
||||
#ifdef WINSCP
|
||||
NE_REQFLAG_IGNOREEMPTYXML,
|
||||
#endif
|
||||
|
||||
NE_REQFLAG_LAST /* enum sentinel value */
|
||||
} ne_request_flag;
|
||||
|
||||
|
||||
@@ -48,14 +48,8 @@ int ne_xml_parse_response(ne_request *req, ne_xml_parser *parser)
|
||||
char buf[8000];
|
||||
ssize_t bytes;
|
||||
int ret = 0;
|
||||
#ifdef WINSCP
|
||||
int any = 0;
|
||||
#endif
|
||||
|
||||
while ((bytes = ne_read_response_block(req, buf, sizeof buf)) > 0) {
|
||||
#ifdef WINSCP
|
||||
any = 1;
|
||||
#endif
|
||||
ret = ne_xml_parse(parser, buf, bytes);
|
||||
if (ret)
|
||||
return parse_error(req, parser);
|
||||
@@ -63,11 +57,6 @@ int ne_xml_parse_response(ne_request *req, ne_xml_parser *parser)
|
||||
|
||||
if (bytes == 0) {
|
||||
/* Tell the parser that end of document was reached: */
|
||||
#ifdef WINSCP
|
||||
if (!any && ne_get_request_flag(req, NE_REQFLAG_IGNOREEMPTYXML))
|
||||
return NE_OK;
|
||||
else
|
||||
#endif
|
||||
if (ne_xml_parse(parser, NULL, 0) == 0)
|
||||
return NE_OK;
|
||||
else
|
||||
|
||||
@@ -195,13 +195,6 @@ void __fastcall TWebDAVFileSystem::Open()
|
||||
|
||||
UnicodeString HostName = Data->HostNameExpanded;
|
||||
|
||||
FOneDrive = SameText(HostName, L"d.docs.live.net");
|
||||
if (FOneDrive)
|
||||
{
|
||||
FTerminal->LogEvent(L"OneDrive host detected.");
|
||||
FOneDriveInterface = odiUnknown;
|
||||
}
|
||||
|
||||
size_t Port = Data->PortNumber;
|
||||
UnicodeString ProtocolName = (Data->Ftps == ftpsNone) ? HttpProtocol : HttpsProtocol;
|
||||
UnicodeString Path = Data->RemoteDirectory;
|
||||
@@ -312,8 +305,7 @@ void __fastcall TWebDAVFileSystem::InitSession(TSessionContext * SessionContext,
|
||||
|
||||
ne_set_session_private(Session, SESSION_CONTEXT_KEY, SessionContext);
|
||||
|
||||
// Allow ^-escaping in OneDrive
|
||||
ne_set_session_flag(Session, NE_SESSFLAG_LIBERAL_ESCAPING, Data->WebDavLiberalEscaping || FOneDrive);
|
||||
ne_set_session_flag(Session, NE_SESSFLAG_LIBERAL_ESCAPING, Data->WebDavLiberalEscaping);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
TWebDAVFileSystem::TSessionContext * TWebDAVFileSystem::NeonOpen(const UnicodeString & Url, UTF8String & Path, UTF8String & Query)
|
||||
@@ -332,7 +324,6 @@ TWebDAVFileSystem::TSessionContext * TWebDAVFileSystem::NeonOpen(const UnicodeSt
|
||||
Path = Uri.path;
|
||||
Query = Uri.query;
|
||||
bool Ssl = Uri.IsTls();
|
||||
ne_set_aux_request_init(Result->NeonSession, NeonAuxRequestInit, Result.get());
|
||||
|
||||
UpdateNeonDebugMask();
|
||||
|
||||
@@ -360,21 +351,9 @@ bool TWebDAVFileSystem::IsTlsSession(ne_session * Session)
|
||||
return Uri.IsTls();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void TWebDAVFileSystem::NeonAuxRequestInit(ne_session * Session, ne_request * /*Request*/, void * UserData)
|
||||
{
|
||||
TSessionContext * SessionContext = static_cast<TSessionContext *>(UserData);
|
||||
TWebDAVFileSystem * FileSystem = SessionContext->FileSystem;
|
||||
FileSystem->InitSession(SessionContext, Session);
|
||||
|
||||
if (FileSystem->IsTlsSession(Session))
|
||||
{
|
||||
FileSystem->SetSessionTls(SessionContext, Session, true);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TWebDAVFileSystem::NeonAddAuthentication(TSessionContext * SessionContext, bool UseNegotiate)
|
||||
{
|
||||
unsigned int NeonAuthTypes = NE_AUTH_BASIC | NE_AUTH_DIGEST | NE_AUTH_PASSPORT;
|
||||
unsigned int NeonAuthTypes = NE_AUTH_BASIC | NE_AUTH_DIGEST;
|
||||
if (UseNegotiate)
|
||||
{
|
||||
NeonAuthTypes |= NE_AUTH_NEGOTIATE;
|
||||
@@ -530,18 +509,6 @@ void __fastcall TWebDAVFileSystem::CollectUsage()
|
||||
}
|
||||
|
||||
UnicodeString RemoteSystem = FFileSystemInfo.RemoteSystem;
|
||||
if (FOneDrive)
|
||||
{
|
||||
FTerminal->Configuration->Usage->Inc(L"OpenedSessionsWebDAVOneDrive");
|
||||
if (FOneDriveInterface == odiUpperCase)
|
||||
{
|
||||
FTerminal->Configuration->Usage->Inc(L"OpenedSessionsWebDAVOneDriveUpperCase");
|
||||
}
|
||||
else if (FOneDriveInterface == odiLowerCase)
|
||||
{
|
||||
FTerminal->Configuration->Usage->Inc(L"OpenedSessionsWebDAVOneDriveLowerCase");
|
||||
}
|
||||
}
|
||||
if (ContainsText(RemoteSystem, L"Microsoft-IIS"))
|
||||
{
|
||||
FTerminal->Configuration->Usage->Inc(L"OpenedSessionsWebDAVIIS");
|
||||
@@ -905,43 +872,6 @@ void TWebDAVFileSystem::NeonPropsResult(
|
||||
FileSystem->ParsePropResultSet(File.get(), Path, Results);
|
||||
|
||||
UnicodeString FileListPath = UnixIncludeTrailingBackslash(FileSystem->AbsolutePath(Data.FileList->Directory, false));
|
||||
if (FileSystem->FOneDrive)
|
||||
{
|
||||
UnicodeString FullFileName = UnixIncludeTrailingBackslash(File->FullFileName);
|
||||
if (Configuration->Usage->Collect && (FileSystem->FOneDriveInterface == odiUnknown) && !IsUnixRootPath(FullFileName))
|
||||
{
|
||||
UnicodeString Cid = FullFileName;
|
||||
if (DebugAlwaysTrue(StartsStr(L"/", Cid)))
|
||||
{
|
||||
Cid.Delete(1, 1);
|
||||
int P = Cid.Pos(L"/");
|
||||
if (P > 0)
|
||||
{
|
||||
Cid.SetLength(P - 1);
|
||||
}
|
||||
UnicodeString CidUpper = UpperCase(Cid);
|
||||
UnicodeString CidLower = LowerCase(Cid);
|
||||
if (CidUpper != CidLower)
|
||||
{
|
||||
if (Cid == CidUpper)
|
||||
{
|
||||
FileSystem->FOneDriveInterface = odiUpperCase;
|
||||
Terminal->LogEvent(L"Detected upper-case OneDrive interface");
|
||||
}
|
||||
else if (Cid == CidLower)
|
||||
{
|
||||
FileSystem->FOneDriveInterface = odiLowerCase;
|
||||
Terminal->LogEvent(L"Detected lower-case OneDrive interface");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// OneDrive is case insensitive and when we enter the directory using a different case, it returns results with the actual case
|
||||
if (StartsText(FileListPath, FullFileName))
|
||||
{
|
||||
File->FullFileName = FileListPath + MidStr(FullFileName, FileListPath.Length() + 1);
|
||||
}
|
||||
}
|
||||
if (UnixSamePath(File->FullFileName, FileListPath))
|
||||
{
|
||||
File->FileName = PARENTDIRECTORY;
|
||||
@@ -949,25 +879,19 @@ void TWebDAVFileSystem::NeonPropsResult(
|
||||
}
|
||||
else
|
||||
{
|
||||
// Quick and dirty hack. The following tests do not work on OneDrive, as the directory path may be escaped,
|
||||
// and we do not correctly unescape full `Path`, only its filename (so path in FullFileName may not be not correct).
|
||||
// Until it's real problem somewhere else, we skip this test, as we otherwise trust OneDrive not to return nonsense contents.
|
||||
if (!FileSystem->FOneDrive)
|
||||
if (!StartsStr(FileListPath, File->FullFileName))
|
||||
{
|
||||
if (!StartsStr(FileListPath, File->FullFileName))
|
||||
Terminal->LogEvent(FORMAT(L"Discarding entry \"%s\" with absolute path \"%s\" because it is not descendant of directory \"%s\".", (Path, File->FullFileName, FileListPath)));
|
||||
File.reset(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnicodeString FileName = MidStr(File->FullFileName, FileListPath.Length() + 1);
|
||||
if (!UnixExtractFileDir(FileName).IsEmpty())
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"Discarding entry \"%s\" with absolute path \"%s\" because it is not descendant of directory \"%s\".", (Path, File->FullFileName, FileListPath)));
|
||||
Terminal->LogEvent(FORMAT(L"Discarding entry \"%s\" with absolute path \"%s\" because it is not direct child of directory \"%s\".", (Path, File->FullFileName, FileListPath)));
|
||||
File.reset(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnicodeString FileName = MidStr(File->FullFileName, FileListPath.Length() + 1);
|
||||
if (!UnixExtractFileDir(FileName).IsEmpty())
|
||||
{
|
||||
Terminal->LogEvent(FORMAT(L"Discarding entry \"%s\" with absolute path \"%s\" because it is not direct child of directory \"%s\".", (Path, File->FullFileName, FileListPath)));
|
||||
File.reset(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -996,7 +920,7 @@ void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
|
||||
{
|
||||
File->FullFileName = UnixExcludeTrailingBackslash(Path);
|
||||
// Some servers do not use DAV:collection tag, but indicate the folder by trailing slash only.
|
||||
// But not all, for example OneDrive does not (it did in the past).
|
||||
// It seems that all servers actually use the trailing slash, including IIS, mod_Dav, IT Hit, etc.
|
||||
bool Collection = (File->FullFileName != Path);
|
||||
File->FileName = UnixExtractFileName(File->FullFileName);
|
||||
const char * ContentLength = GetProp(Results, PROP_CONTENT_LENGTH);
|
||||
@@ -1072,21 +996,6 @@ void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
|
||||
if (DisplayName != NULL)
|
||||
{
|
||||
File->DisplayName = StrFromNeon(DisplayName);
|
||||
// OneDrive caret escaping (we could do this for all files, but let's limit the scope for now).
|
||||
// In *file* PROPFIND response, the # (and other symbols like comma or plus) is not escaped at all
|
||||
// (while in directory listing, they are caret-escaped),
|
||||
// so if we see one in the display name, take the name from there.
|
||||
// * and % won't help, as OneDrive seem to have bug with % at the end of the filename,
|
||||
// and the * (and others) is removed from file names.
|
||||
|
||||
// Filenames with commas (,) get as many additional characters at the end of the filename as there are commas
|
||||
// (not true anymore in the new interface).
|
||||
if (FOneDrive &&
|
||||
(ContainsText(File->FileName, L"^") || ContainsText(File->FileName, L",") || (wcspbrk(File->DisplayName.c_str(), L"&,+#[]%*") != NULL)))
|
||||
{
|
||||
File->FileName = File->DisplayName;
|
||||
File->FullFileName = UnixCombinePaths(UnixExtractFileDir(File->FullFileName), File->FileName);
|
||||
}
|
||||
}
|
||||
|
||||
const UnicodeString RightsDelimiter(L", ");
|
||||
@@ -1381,9 +1290,6 @@ void __fastcall TWebDAVFileSystem::SpaceAvailable(const UnicodeString Path,
|
||||
// WWW-Authenticate: Basic realm="Yandex.Disk"
|
||||
// Server: MochiWeb/1.0
|
||||
|
||||
// OneDrive:
|
||||
// it sends the properties unconditionally, even when not explicitly requested
|
||||
|
||||
UnicodeString APath = DirectoryPath(Path);
|
||||
|
||||
ne_propname QuotaProps[3];
|
||||
|
||||
@@ -180,8 +180,6 @@ private:
|
||||
UnicodeString FAuthorizationProtocol;
|
||||
UnicodeString FLastAuthorizationProtocol;
|
||||
bool FAuthenticationRetry;
|
||||
bool FOneDrive;
|
||||
enum { odiUnknown, odiUpperCase, odiLowerCase } FOneDriveInterface;
|
||||
|
||||
void __fastcall CustomReadFile(UnicodeString FileName,
|
||||
TRemoteFile *& File, TRemoteFile * ALinkedByFile);
|
||||
|
||||
Reference in New Issue
Block a user