static int owner_modify(void) { char *tmp; ne_propname pname = { "http://webdav.org/neon/litmus/", "random" }; ne_proppatch_operation pops[] = { { NULL, ne_propset, "foobar" }, { NULL } }; PRECOND(gotlock); ONV(ne_put(i_session, res, i_foo_fd), ("PUT on locked resource failed: %s", ne_get_error(i_session))); tmp = ne_concat(i_path, "whocares", NULL); ONN("COPY of locked resource", ne_copy(i_session, 1, NE_DEPTH_ZERO, res, tmp) == NE_ERROR); if (STATUS(201)) t_warning("COPY failed with %d not 201", GETSTATUS); ONN("DELETE of locked resource by owner", ne_delete(i_session, tmp) == NE_ERROR); if (STATUS(204)) t_warning("DELETE of %s failed with %d not 200", tmp, GETSTATUS); free(tmp); ONN("PROPPATCH of locked resource", ne_proppatch(i_session, res, pops) == NE_ERROR); if (STATUS(207)) t_warning("PROPPATCH failed with %d", GETSTATUS); return OK; }
static int copy_overwrite(void) { PRECOND(copy_ok); /* Do it again with Overwrite: F to check that fails. */ ONN("COPY on existing resource with Overwrite: F should fail (RFC2518:S8.8.4)", ne_copy(i_session, 0, NE_DEPTH_INFINITE, src, dest) != NE_ERROR); if (STATUS(412)) { t_warning("COPY-on-existing fails with 412"); } ONV(ne_copy(i_session, 1, NE_DEPTH_INFINITE, src, dest), ("COPY-on-existing with 'Overwrite: T' should succeed (RFC2518:S8.8.4): %s", ne_get_error(i_session))); /* tricky one this, I didn't think it should work, but the spec * makes it look like it should. */ ONV(ne_copy(i_session, 1, NE_DEPTH_INFINITE, src, coll), ("COPY overwrites collection: %s", ne_get_error(i_session))); if (STATUS(204)) { t_warning("COPY to existing resource didn't give 204 (RFC2518:S8.8.5)"); } return OK; }
static int move(void) { char *src2; src = ne_concat(i_path, "move", NULL); src2 = ne_concat(i_path, "move2", NULL); dest = ne_concat(i_path, "movedest", NULL); coll = ne_concat(i_path, "movecoll/", NULL); ncoll = ne_concat(i_path, "movecoll", NULL); /* Upload it twice. */ CALL(upload_foo("move")); CALL(upload_foo("move2")); ONMREQ("MKCOL", coll, ne_mkcol(i_session, coll)); /* Now move it */ ONM2REQ("MOVE", src, dest, ne_move(i_session, 0, src, dest)); if (STATUS(201)) { t_warning("MOVE to new resource didn't give 201"); } /* Try a move with Overwrite: F to check that fails. */ ONM2REQ("MOVE on existing resource with Overwrite: F succeeded", src2, dest, ne_move(i_session, 0, src2, dest) != NE_ERROR); if (STATUS(412)) { t_warning("MOVE-on-existing should fail with 412"); } ONM2REQ("MOVE onto existing resource with Overwrite: T", src2, dest, ne_move(i_session, 1, src2, dest)); ONM2REQ("MOVE overwrites collection", coll, dest, ne_move(i_session, 1, dest, coll)); if (STATUS(204)) { t_warning("MOVE to existing collection resource didn't give 204"); } if (ne_delete(i_session, ncoll)) { t_warning("Could not clean up `%s'", ncoll); } return OK; }
static int notowner_lock(void) { struct ne_lock dummy; PRECOND(gotlock); memcpy(&dummy, &reslock, sizeof(reslock)); dummy.token = ne_strdup("opaquelocktoken:foobar"); dummy.scope = ne_lockscope_exclusive; dummy.owner = ne_strdup("notowner lock"); ONN("UNLOCK with bogus lock token", ne_unlock(i_session2, &dummy) != NE_ERROR); /* 2518 doesn't really say what status code that UNLOCK should * fail with. mod_dav gives a 400 as the locktoken is bogus. */ ONN("LOCK on locked resource", ne_lock(i_session2, &dummy) != NE_ERROR); if (dummy.token) ne_free(dummy.token); if (STATUS2(423)) t_warning("LOCK failed with %d not 423", GETSTATUS2); return OK; }
static int notowner_modify(void) { char *tmp; ne_propname pname = { "http://webdav.org/neon/litmus/", "random" }; ne_proppatch_operation pops[] = { { NULL, ne_propset, "foobar" }, { NULL } }; PRECOND(gotlock); pops[0].name = &pname; ONN("DELETE of locked resource should fail", ne_delete(i_session2, res) != NE_ERROR); if (STATUS2(423)) t_warning("DELETE failed with %d not 423", GETSTATUS2); tmp = ne_concat(i_path, "whocares", NULL); ONN("MOVE of locked resource should fail", ne_move(i_session2, 0, res, tmp) != NE_ERROR); free(tmp); if (STATUS2(423)) t_warning("MOVE failed with %d not 423", GETSTATUS2); ONN("COPY onto locked resource should fail", ne_copy(i_session2, 1, NE_DEPTH_ZERO, res2, res) != NE_ERROR); if (STATUS2(423)) t_warning("COPY failed with %d not 423", GETSTATUS2); ONN("PROPPATCH of locked resource should fail", ne_proppatch(i_session2, res, pops) != NE_ERROR); if (STATUS2(423)) t_warning("PROPPATCH failed with %d not 423", GETSTATUS2); ONN("PUT on locked resource should fail", ne_put(i_session2, res, i_foo_fd) != NE_ERROR); if (STATUS2(423)) t_warning("PUT failed with %d not 423", GETSTATUS2); return OK; }
static int copy_shallow(void) { char *csrc, *cdest, *res; csrc = ne_concat(i_path, "ccsrc/", NULL); cdest = ne_concat(i_path, "ccdest/", NULL); /* Set up the ccsrc collection with one member */ ONMREQ("MKCOL", csrc, ne_mkcol(i_session, csrc)); CALL(upload_foo("ccsrc/foo")); /* Clean up to make some fresh copies. */ ne_delete(i_session, cdest); /* Now copy with Depth 0 */ ONV(ne_copy(i_session, 0, NE_DEPTH_ZERO, csrc, cdest), ("collection COPY `%s' to `%s': %s", csrc, cdest, ne_get_error(i_session))); /* Remove the source, to be paranoid. */ if (ne_delete(i_session, csrc)) { t_warning("Could not delete csrc"); } /* Now make sure the child resource hasn't been copied along with * the collection. */ res = ne_concat(i_path, "foo", NULL); ne_delete(i_session, res); ONV(STATUS(404), ("DELETE on `%s' should fail with 404: got %d", res, GETSTATUS)); ne_free(res); if (ne_delete(i_session, cdest)) { t_warning("Could not clean up cdest"); } return OK; }
static int copy_simple(void) { PRECOND(copy_ok); /* Now copy it once */ ONNREQ("simple resource COPY", ne_copy(i_session, 0, NE_DEPTH_INFINITE, src, dest)); if (STATUS(201)) { t_warning("COPY to new resource should give 201 (RFC2518:S8.8.5)"); } return OK; }
/* PUT conditional on bogus lock-token and valid etag, should fail. */ static int fail_cond_put_unlocked(void) { int klass, code; CALL(conditional_put("(<DAV:no-lock>)", &klass, &code)); ONV(klass == 2, ("conditional PUT with invalid lock-token should fail: %s", ne_get_error(i_session))); ONN("conditional PUT with invalid lock-token code got 400", code == 400); if (code != 412) t_warning("PUT failed with %d not 412", code); return OK; }
/* lock on unmapped url should return 201 */ static int unmapped_lock(void) { if (gotlock) { ne_lock_destroy(gotlock); gotlock = NULL; } ne_free(res); res = ne_concat(i_path, "unmapped_url", NULL); ONV(getlock(ne_lockscope_exclusive, NE_DEPTH_ZERO), ("LOCK on %s via %s: %s", coll, res, ne_get_error(i_session))); if (STATUS(201)) t_warning("LOCK on unmapped url returned %d not 201 (RFC4918:S7.3)", GETSTATUS); return OK; }
static int write_reset(void) { ne_socket *sock; int ret; CALL(begin(&sock, serve_reset, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_fullwrite(sock, "a", 1); if (ret == 0) { ne_sock_close(sock); return SKIP; } if (ret == NE_SOCK_CLOSED) { t_warning("got EOF, failed to elicit TCP RST"); } else { ONV(ret != NE_SOCK_RESET, ("write got %d not reset: %s", ret, ne_sock_error(sock))); } return good_close(sock); }
static int copy_nodestcoll(void) { char *nodest = ne_concat(i_path, "nonesuch/foo", NULL); int ret; PRECOND(copy_ok); ret = ne_copy(i_session, 0, NE_DEPTH_ZERO, src, nodest); ONV(ret == NE_OK, ("COPY into non-existant collection '%snonesuch' succeeded", i_path)); if (STATUS(409)) { t_warning("COPY to non-existant collection '%snonesuch' gave '%s' not 409" " (RFC2518:S8.8.5)", i_path, ne_get_error(i_session)); } ne_free(nodest); return OK; }
/* PUT conditional on corruption of real lock-token and not(bogus * lock-token) , should fail. */ static int cond_put_corrupt_token(void) { int class, code; char hdr[200]; PRECOND(gotlock); ne_snprintf(hdr, sizeof hdr, "(<%sx>) (Not <DAV:no-lock>)", gotlock->token); CALL(conditional_put(hdr, &class, &code)); ONV(class == 2, ("conditional PUT with invalid lock-token should fail: %s", ne_get_error(i_session))); if (code != 423) t_warning("PUT failed with %d not 423", code); return OK; }
static int addr_reverse(void) { ne_inet_addr *ia = ne_iaddr_make(ne_iaddr_ipv4, raw_127); char buf[128], *syshost = NULL; int match; #ifdef HAVE_GETHOSTNAME char host[128]; if (gethostname(host, sizeof host) == 0) { syshost = host; } #endif ONN("ne_iaddr_make returned NULL", ia == NULL); ONN("reverse lookup for 127.0.0.1 failed", ne_iaddr_reverse(ia, buf, sizeof buf) != 0); NE_DEBUG(NE_DBG_SOCKET, "Reverse lookup for 127.0.0.1 => %s\n", buf); match = strcmp(buf, "localhost.localdomain") == 0 || strcmp(buf, "localhost") == 0; if (!match && syshost) /* If the returned name has the system hostname as a prefix, that's * good enough. */ match = strncmp(buf, syshost, strlen(syshost)) == 0; if (!match) t_warning("reverse lookup for 127.0.0.1 got '%s'", buf); ONN("reverse lookup for 127.0.0.1 got empty string", strlen(buf) == 0); ne_iaddr_free(ia); return OK; }
/* PUT conditional on bogus lock-token and valid etag, should fail. */ static int fail_cond_put(void) { int klass, code; char *etag = get_etag(res); char hdr[200]; PRECOND(etag && gotlock); ne_snprintf(hdr, sizeof hdr, "(<DAV:no-lock> [%s])", etag); CALL(conditional_put(hdr, &klass, &code)); ONV(klass == 2, ("conditional PUT with invalid lock-token should fail: %s", ne_get_error(i_session))); ONN("conditional PUT with invalid lock-token code got 400", code == 400); if (code != 412) t_warning("PUT failed with %d not 412", code); return OK; }
static int lock_on_no_file(void) { char *tmp; res = ne_concat(i_path, "locknullfile", NULL); tmp = ne_concat(i_path, "whocares", NULL); getlock(ne_lockscope_exclusive, NE_DEPTH_ZERO); if (STATUS(200)) t_warning("Lock Null failed with %d not 200", GETSTATUS); //FIXME: After Lock Null is created, Do Unlock it to maintain integrity of tests //ONNREQ2("unlock of second shared lock",ne_unlock(i_session, &gotlock)); // Copy of nulllock resource ONN("COPY null locked resource should ", ne_copy(i_session, 1, NE_DEPTH_ZERO, res, tmp) == NE_ERROR); // Delete of nulllockresource ONN("DELETE of locknull resource by owner", ne_delete(i_session, tmp) == NE_ERROR); free(tmp); // Move of nulllockresource tmp = ne_concat(i_path, "who-cares", NULL); ONN("MOVE of null-locked resource", ne_move(i_session, 0, res, tmp) == NE_ERROR); ONN("DELETE of locknull resource by owner after a MOVE with overwrite (F)", ne_delete(i_session, tmp) == NE_ERROR); /* Delete the locktoken from store */ ne_lockstore_remove(store, gotlock); getlock(ne_lockscope_exclusive, NE_DEPTH_ZERO); if (STATUS(200)) t_warning("Lock Null failed with %d not 200", GETSTATUS); /* Lot of code duplication, but want to test each case individually. * Locknull resource. How it behaves when it is copied * moved (with overwrite T/F) * PUT request on locknullresource should succeed. */ /*MOVE of null-locked resource with overwrite=T */ ONN("MOVE of null-locked resource with overwrite=T (1)", ne_move(i_session, 1, res, tmp) == NE_ERROR); ne_lockstore_remove(store, gotlock); getlock(ne_lockscope_exclusive, NE_DEPTH_ZERO); if (STATUS(200)) t_warning("Lock Null failed with %d not 200", GETSTATUS); ONN("MOVE of null-locked resource with overwrite=T (2)", ne_move(i_session, 1, res, tmp) == NE_ERROR); ne_lockstore_remove(store, gotlock); getlock(ne_lockscope_shared, NE_DEPTH_ZERO); if (STATUS(200)) t_warning("Lock Null failed with %d not 200", GETSTATUS); ONN("COPY on null-locked resource with overwrite=T", ne_copy(i_session, 1, NE_DEPTH_ZERO, tmp, res) == NE_ERROR); ONN("DELETE of locknull resource by owner after a MOVE (T) ", ne_delete(i_session, tmp) == NE_ERROR); free(tmp); // Put on nulllockresource ONV(ne_put(i_session,res, i_foo_fd), ("PUT on locknullfile resource failed: %s", ne_get_error(i_session))); return OK; }
static int copy_coll(void) { int n; char *csrc, *cdest, *rsrc, *rdest, *subsrc, *subdest, *cdest2; char res[512]; csrc = ne_concat(i_path, "ccsrc/", NULL); cdest = ne_concat(i_path, "ccdest/", NULL); cdest2 = ne_concat(i_path, "ccdest2/", NULL); rsrc = ne_concat(i_path, "ccsrc/foo", NULL); rdest = ne_concat(i_path, "ccdest/foo", NULL); subsrc = ne_concat(i_path, "ccsrc/subcoll/", NULL); subdest = ne_concat(i_path, "ccdest/subcoll/", NULL); /* Set up the ccsrc collection. */ ONMREQ("MKCOL", csrc, ne_mkcol(i_session, csrc)); for (n = 0; n < 10; n++) { sprintf(res, "ccsrc/foo.%d", n); CALL(upload_foo(res)); } ONMREQ("MKCOL", subsrc, ne_mkcol(i_session, subsrc)); /* Clean up to make some fresh copies. */ ne_delete(i_session, cdest); ne_delete(i_session, cdest2); /* Now copy the collection a couple of times */ ONV(ne_copy(i_session, 0, NE_DEPTH_INFINITE, csrc, cdest), ("collection COPY `%s' to `%s': %s", csrc, cdest, ne_get_error(i_session))); ONV(ne_copy(i_session, 0, NE_DEPTH_INFINITE, csrc, cdest2), ("collection COPY `%s' to `%s': %s", csrc, cdest, ne_get_error(i_session))); ONN("COPY-on-existing-coll should fail", ne_copy(i_session, 0, NE_DEPTH_INFINITE, cdest, cdest2) != NE_ERROR); ONV(ne_copy(i_session, 1, NE_DEPTH_INFINITE, cdest2, cdest), ("COPY-on-existing-coll with overwrite: %s", ne_get_error(i_session))); /* Remove the source, to be paranoid. */ if (ne_delete(i_session, csrc)) { t_warning("Could not delete csrc"); } /* Now delete things out of the destination collection to check if * they are there. */ for (n = 0; n < 10; n++) { sprintf(res, "%s%s.%d", i_path, "ccdest/foo", n); ONV(ne_delete(i_session, res), ("COPY destination coll missing %s? %s", res, ne_get_error(i_session))); } ONV(ne_delete(i_session, subdest), ("COPY destination missing sub-coll %s? %s", subdest, ne_get_error(i_session))); /* Now nuke the whole of the second copy. */ ONV(ne_delete(i_session, cdest2), ("COPY destination %s missing? %s", cdest2, ne_get_error(i_session))); if (ne_delete(i_session, cdest)) { t_warning("Could not clean up cdest"); } return OK; }
static int fail_socks(void) { static const struct { enum ne_sock_sversion version; enum socks_failure failure; const char *expect; const char *username, *password; } ts[] = { { NE_SOCK_SOCKSV5, fail_init_vers, "Invalid version in proxy response", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_init_trunc, "Could not read initial response from proxy: Connection closed", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_init_close, "Could not read initial response from proxy: Connection closed", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_no_auth, "No acceptable authentication method", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_bogus_auth, "Unexpected authentication method chosen", NULL, NULL }, { NE_SOCK_SOCKSV5, fail_auth_close, "Could not read login reply: Connection closed", "foo", "bar" }, { NE_SOCK_SOCKSV5, fail_auth_denied, "Authentication failed", "foo", "bar" } }; unsigned n; for (n = 0; n < sizeof(ts)/sizeof(ts[n]); n++) { ne_socket *sock; struct socks_server arg = {0}; int ret; arg.version = ts[n].version; arg.failure = ts[n].failure; arg.expect_port = 5555; arg.expect_addr = ne_iaddr_make(ne_iaddr_ipv4, raw_127); arg.username = ts[n].username; arg.password = ts[n].password; CALL(begin_socks(&sock, &arg, echo_server, NULL)); ret = ne_sock_proxy(sock, ts[n].version, arg.expect_addr, NULL, arg.expect_port, ts[n].username, ts[n].password); ONV(ret == 0, ("proxy connect #%u succeeded, expected failure '%s'", n, ts[n].expect)); if (ret != 0 && strstr(ne_sock_error(sock), ts[n].expect) == NULL) { t_warning("proxy connect #%u got unexpected failure '%s', wanted '%s'", n, ne_sock_error(sock), ts[n].expect); } ne_iaddr_free(arg.expect_addr); CALL(finish(sock, 0)); } return OK; }