/* Get a lock, store pointer in global 'getlock'. */ static int getlock(enum ne_lock_scope scope, int depth) { memset(&reslock, 0, sizeof(reslock)); ne_fill_server_uri(i_session, &reslock.uri); reslock.uri.path = res; reslock.depth = depth; reslock.scope = scope; reslock.type = ne_locktype_write; reslock.timeout = 3600; reslock.owner = ne_strdup("litmus test suite"); /* leave gotlock as NULL if the LOCK fails. */ gotlock = NULL; ONMREQ("LOCK", res, ne_lock(i_session, &reslock)); if (scope != reslock.scope) { t_context("requested lockscope not satisfied! got %s, wanted %s", scope == ne_lockscope_exclusive ? "exclusive" : "shared", reslock.scope == ne_lockscope_exclusive ? "exclusive" : "shared"); ne_unlock(i_session, &reslock); return FAIL; } /* Take a copy of the lock. */ gotlock = ne_lock_copy(&reslock); ne_lockstore_add(store, gotlock); return OK; }
/* Verifies an SSL server certificate. */ static int check_certificate(ne_session *sess, gnutls_session sock, ne_ssl_certificate *chain) { int ret, failures = 0; ne_uri server; unsigned int status; memset(&server, 0, sizeof server); ne_fill_server_uri(sess, &server); ret = check_identity(&server, chain->subject, NULL); ne_uri_free(&server); if (ret < 0) { ne_set_error(sess, _("Server certificate was missing commonName " "attribute in subject name")); return NE_ERROR; } else if (ret > 0) { failures |= NE_SSL_IDMISMATCH; } failures |= check_chain_expiry(chain); ret = gnutls_certificate_verify_peers2(sock, &status); NE_DEBUG(NE_DBG_SSL, "ssl: Verify peers returned %d, status=%u\n", ret, status); if (ret != GNUTLS_E_SUCCESS) { ne_set_error(sess, _("Could not verify server certificate: %s"), gnutls_strerror(ret)); return NE_ERROR; } failures |= map_verify_failures(&status); NE_DEBUG(NE_DBG_SSL, "ssl: Verification failures = %d (status = %u).\n", failures, status); if (status && status != GNUTLS_CERT_INVALID) { char *errstr = verify_error_string(status); ne_set_error(sess, _("Certificate verification error: %s"), errstr); ne_free(errstr); return NE_ERROR; } if (failures == 0) { ret = NE_OK; } else { ne__ssl_set_verify_err(sess, failures); ret = NE_ERROR; if (sess->ssl_verify_fn && sess->ssl_verify_fn(sess->ssl_verify_ud, failures, chain) == 0) ret = NE_OK; } return ret; }
static void *ld_create(void *userdata, const char *href) { struct discover_ctx *ctx = userdata; struct ne_lock *lk = ne_lock_create(); if (ne_uri_parse(href, &lk->uri) != 0) { ne_lock_destroy(lk); return NULL; } if (!lk->uri.host) ne_fill_server_uri(ctx->session, &lk->uri); return lk; }
void ne_lock_using_parent(ne_request *req, const char *path) { NE_DEBUG_WINSCP_CONTEXT(ne_get_session(req)); struct lh_req_cookie *lrc = ne_get_request_private(req, HOOK_ID); ne_uri u = {0}; struct lock_list *item; char *parent; if (lrc == NULL) return; parent = ne_path_parent(path); if (parent == NULL) return; ne_fill_server_uri(ne_get_session(req), &u); for (item = lrc->store->locks; item != NULL; item = item->next) { /* Only care about locks which are on this server. */ u.path = item->lock->uri.path; if (ne_uri_cmp(&u, &item->lock->uri)) continue; /* This lock is needed if it is an infinite depth lock which * covers the parent, or a lock on the parent itself. */ if ((item->lock->depth == NE_DEPTH_INFINITE && ne_path_childof(item->lock->uri.path, parent)) || ne_path_compare(item->lock->uri.path, parent) == 0) { NE_DEBUG(NE_DBG_LOCKS, "Locked parent, %s on %s\n", item->lock->token, item->lock->uri.path); submit_lock(lrc, item->lock); } } u.path = parent; /* handy: makes u.path valid and ne_free(parent). */ ne_uri_free(&u); }
/* Get a lock, store pointer in global 'getlock'. */ static int getlock(enum ne_lock_scope scope, int depth) { memset(&reslock, 0, sizeof(reslock)); ne_fill_server_uri(i_session, &reslock.uri); reslock.uri.path = res; reslock.depth = depth; reslock.scope = scope; reslock.type = ne_locktype_write; reslock.timeout = 3600; reslock.owner = ne_strdup("litmus test suite"); /* leave gotlock as NULL if the LOCK fails. */ gotlock = NULL; ONMREQ("LOCK", res, ne_lock(i_session, &reslock)); /* Take a copy of the lock. */ gotlock = ne_lock_copy(&reslock); ne_lockstore_add(store, gotlock); return OK; }
void ne_session_system_proxy(ne_session *sess, unsigned int flags) { #ifdef HAVE_LIBPROXY pxProxyFactory *pxf = px_proxy_factory_new(); struct host_info *hi, **lasthi; char *url, **proxies; ne_uri uri; unsigned n; free_proxies(sess); /* Create URI for session to pass off to libproxy */ memset(&uri, 0, sizeof uri); ne_fill_server_uri(sess, &uri); uri.path = "/"; /* make valid URI structure. */ url = ne_uri_unparse(&uri); uri.path = NULL; /* Get list of pseudo-URIs from libproxy: */ proxies = px_proxy_factory_get_proxies(pxf, url); for (n = 0, lasthi = &sess->proxies; proxies[n]; n++) { enum proxy_type ptype; ne_uri_free(&uri); NE_DEBUG(NE_DBG_HTTP, "sess: libproxy #%u=%s\n", n, proxies[n]); if (ne_uri_parse(proxies[n], &uri)) continue; if (!uri.scheme) continue; if (ne_strcasecmp(uri.scheme, "http") == 0) ptype = PROXY_HTTP; else if (ne_strcasecmp(uri.scheme, "socks") == 0) ptype = PROXY_SOCKS; else if (ne_strcasecmp(uri.scheme, "direct") == 0) ptype = PROXY_NONE; else continue; /* Hostname/port required for http/socks schemes. */ if (ptype != PROXY_NONE && !(uri.host && uri.port)) continue; /* Do nothing if libproxy returned only a single "direct://" * entry -- a single "direct" (noop) proxy is equivalent to * having none. */ if (n == 0 && proxies[1] == NULL && ptype == PROXY_NONE) break; NE_DEBUG(NE_DBG_HTTP, "sess: Got proxy %s://%s:%d\n", uri.scheme, uri.host ? uri.host : "(none)", uri.port); hi = *lasthi = ne_calloc(sizeof *hi); if (ptype == PROXY_NONE) { /* A "direct" URI requires an attempt to connect directly to * the origin server, so dup the server details. */ set_hostinfo(hi, ptype, sess->server.hostname, sess->server.port); } else { /* SOCKS/HTTP proxy. */ set_hostinfo(hi, ptype, uri.host, uri.port); if (ptype == PROXY_HTTP) sess->any_proxy_http = 1; else if (ptype == PROXY_SOCKS) sess->socks_ver = NE_SOCK_SOCKSV5; } lasthi = &hi->next; } /* Free up the proxies array: */ for (n = 0; proxies[n]; n++) free(proxies[n]); free(proxies[n]); ne_free(url); ne_uri_free(&uri); px_proxy_factory_free(pxf); #endif }
/* TODO: does this work under cygwin? mkstemp() may or may not open the file using O_BINARY, and then we *do* upload it using O_BINARY, so maybe this will screw things up. Maybe we should fcntl it and set O_BINARY, if that is allowed under cygwin? */ void execute_edit(const char *remote) { char *real_remote; unsigned int can_lock; /* can we LOCK it? */ struct ne_lock *lock = NULL; char fname[PATH_MAX] = "/tmp/cadaver-edit-XXXXXX"; const char *pnt; int fd; int is_checkout, is_checkin; real_remote = resolve_path(session.uri.path, remote, false); /* Don't let them edit a collection, since PUT to a collection is * bogus. Really we want to be able to fetch a "DefaultDocument" * property, and edit on that instead: IIS does expose such a * property. Would be a nice hack to add the support to mod_dav * too. */ if (getrestype(real_remote) == resr_collection) { printf(_("You cannot edit a collection resource (%s).\n"), real_remote); goto edit_bail; } can_lock = is_lockable(real_remote); /* Give the local temp file the same extension as the remote path, * so the editor can have a stab at the content-type. */ pnt = strrchr(real_remote, '.'); if (pnt != NULL && strchr(pnt, '/') == NULL) { strncat(fname, pnt, PATH_MAX); fname[PATH_MAX-1] = '\0'; } fd = cad_mkstemp(fname); if (fd == -1) { printf(_("Could not create temporary file %s:\n%s\n"), fname, strerror(errno)); goto edit_bail; } /* Sanity check on the file perms. */ #ifdef HAVE_FCHMOD if (fchmod(fd, 0600) == -1) { #else if (chmod(fname, 0600) == -1) { #endif printf(_("Could not set file permissions for %s:\n%s\n"), fname, strerror(errno)); goto edit_bail; } if (can_lock) { lock = ne_lock_create(); ne_fill_server_uri(session.sess, &lock->uri); lock->uri.path = ne_strdup(real_remote); lock->owner = getowner(); out_start("Locking", remote); if (out_handle(ne_lock(session.sess, lock))) { ne_lockstore_add(session.locks, lock); } else { ne_lock_destroy(lock); goto edit_close; } } else { /* TODO: HEAD and get the Etag/modtime */ } /* Return 1: Checkin, 2: Checkout, 0: otherwise */ is_checkin = is_vcr(real_remote); if (is_checkin==1) { execute_checkout(real_remote); } output(o_download, _("Downloading `%s' to %s"), real_remote, fname); /* Don't puke if get fails -- perhaps we are creating a new one? */ out_result(ne_get(session.sess, real_remote, fd)); if (close(fd)) { output(o_finish, _("Error writing to temporary file: %s\n"), strerror(errno)); } else if (!run_editor(fname)) { int upload_okay = 0; fd = open(fname, O_RDONLY | OPEN_BINARY_FLAGS); if (fd < 0) { output(o_finish, _("Could not re-open temporary file: %s\n"), strerror(errno)); } else { do { output(o_upload, _("Uploading changes to `%s'"), real_remote); /* FIXME: conditional PUT using fetched Etag/modtime if * !can_lock */ if (out_handle(ne_put(session.sess, real_remote, fd))) { upload_okay = 1; } else { /* TODO: offer to save locally instead */ printf(_("Try uploading again (y/n)? ")); if (!yesno()) { upload_okay = 1; } } } while (!upload_okay); close(fd); } } if (unlink(fname)) { printf(_("Could not delete temporary file %s:\n%s\n"), fname, strerror(errno)); } /* Return 1: Checkin, 2: Checkout, 0: otherwise */ is_checkout = is_vcr(real_remote); if (is_checkout==2) { execute_checkin(real_remote); } /* UNLOCK it again whether we succeed or failed in our mission */ if (can_lock) { output(o_start, "Unlocking `%s':", remote); out_result(ne_unlock(session.sess, lock)); ne_lockstore_remove(session.locks, lock); ne_lock_destroy(lock); } goto edit_bail; edit_close: close(fd); edit_bail: free(real_remote); return; }