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 void connect_server() { ne_session *sess; ne_server_capabilities caps; int ret; /* set up the connection */ ne_sock_init(); memset(&session, 0, sizeof session); session.uri.scheme = ne_strdup("http"); session.uri.host = hc_host; session.uri.port = port; session.uri.path = ne_strdup("/webdav/"); /* always '/'-terminate */ session.sess = sess = ne_session_create(session.uri.scheme, session.uri.host, session.uri.port); /* make the connection */ ne_set_useragent(sess, "hctest/"); /* needed? */ /* not needed to connect ne_lockstore_register(session.locks, sess); ne_redirect_register(sess); */ /* convenient status */ ne_set_status(sess, connection_status, NULL); ne_set_progress(sess, transfer_progress, NULL); /* execute connect */ ret = ne_options(sess, session.uri.path, &caps); switch (ret) { case NE_OK: session.connected = true; /* if (set_path(session.uri.path)) { close_connection(); } */ break; case NE_CONNECT: printf("got NE_CONNECT\n"); quit(1); break; case NE_LOOKUP: puts(ne_get_error(sess)); quit(1); break; default: printf("Could not open collection (default connect err):\n%s\n", ne_get_error(sess)); quit(1); break; } }
ne_uri *ne_uri_copy(ne_uri *dest, const ne_uri *src) { memset(dest, 0, sizeof *dest); if (src->scheme) dest->scheme = ne_strdup(src->scheme); copy_authority(dest, src); if (src->path) dest->path = ne_strdup(src->path); if (src->query) dest->query = ne_strdup(src->query); if (src->fragment) dest->fragment = ne_strdup(src->fragment); return dest; }
static void set_cookie_hdl(void *userdata, const char *value) { char **pairs = pair_string(value, ';', '=', "\"'", " \r\n\t"); ne_cookie *cook; ne_cookie_cache *cache = userdata; int n; /* Check sanity */ if (pairs[0] == NULL || pairs[1] == NULL) { /* yagaboo */ return; } NE_DEBUG(NE_DBG_HTTP, "Got cookie name=%s\n", pairs[0]); /* Search for a cookie of this name */ NE_DEBUG(NE_DBG_HTTP, "Searching for existing cookie...\n"); for (cook = cache->cookies; cook != NULL; cook = cook->next) { if (strcasecmp(cook->name, pairs[0]) == 0) { break; } } if (cook == NULL) { NE_DEBUG(NE_DBG_HTTP, "New cookie.\n"); cook = ne_malloc(sizeof *cook); memset(cook, 0, sizeof *cook); cook->name = ne_strdup(pairs[0]); cook->next = cache->cookies; cache->cookies = cook; } else { /* Free the old value */ ne_free(cook->value); } cook->value = ne_strdup(pairs[1]); for (n = 2; pairs[n] != NULL; n+=2) { NE_DEBUG(NE_DBG_HTTP, "Cookie parm %s=%s\n", pairs[n], pairs[n+1]); if (strcasecmp(pairs[n], "path") == 0) { cook->path = ne_strdup(pairs[n+1]); } else if (strcasecmp(pairs[n], "max-age") == 0) { int t = atoi(pairs[n+1]); cook->expiry = time(NULL) + (time_t)t; } else if (strcasecmp(pairs[n], "domain") == 0) { cook->domain = ne_strdup(pairs[n+1]); } } NE_DEBUG(NE_DBG_HTTP, "End of parms.\n"); pair_string_free(pairs); }
struct ne_lock *ne_lock_copy(const struct ne_lock *lock) { struct ne_lock *ret = ne_calloc(sizeof *ret); ne_uri_copy(&ret->uri, &lock->uri); ret->token = ne_strdup(lock->token); ret->depth = lock->depth; ret->type = lock->type; ret->scope = lock->scope; if (lock->owner) ret->owner = ne_strdup(lock->owner); ret->timeout = lock->timeout; return ret; }
void ne_session_socks_proxy(ne_session *sess, enum ne_sock_sversion vers, const char *hostname, unsigned int port, const char *username, const char *password) { free_proxies(sess); sess->proxies = ne_calloc(sizeof *sess->proxies); set_hostinfo(sess->proxies, PROXY_SOCKS, hostname, port); sess->socks_ver = vers; if (username) sess->socks_user = ne_strdup(username); if (password) sess->socks_password = ne_strdup(password); }
/* 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; }
ne_session *ne_session_create(const char *scheme, const char *hostname, unsigned int port) { ne_session *sess = ne_calloc(sizeof *sess); NE_DEBUG(NE_DBG_HTTP, "HTTP session to %s://%s:%d begins.\n", scheme, hostname, port); strcpy(sess->error, "Unknown error."); /* use SSL if scheme is https */ sess->use_ssl = !strcmp(scheme, "https"); /* set the hostname/port */ set_hostinfo(&sess->server, hostname, port); set_hostport(&sess->server, sess->use_ssl?443:80); #ifdef NE_HAVE_SSL if (sess->use_ssl) { sess->ssl_context = ne_ssl_context_create(0); sess->flags[NE_SESSFLAG_SSLv2] = 1; } #endif sess->scheme = ne_strdup(scheme); /* Set flags which default to on: */ sess->flags[NE_SESSFLAG_PERSIST] = 1; return sess; }
/* Duplicate a client certificate, which must be in the decrypted state. */ static ne_ssl_client_cert *dup_client_cert(const ne_ssl_client_cert *cc) { int ret; ne_ssl_client_cert *newcc = ne_calloc(sizeof *newcc); newcc->decrypted = 1; if (cc->keyless) { newcc->keyless = 1; } else { ret = gnutls_x509_privkey_init(&newcc->pkey); if (ret != 0) goto dup_error; ret = gnutls_x509_privkey_cpy(newcc->pkey, cc->pkey); if (ret != 0) goto dup_error; } newcc->cert.subject = x509_crt_copy(cc->cert.subject); if (!newcc->cert.subject) goto dup_error; if (cc->friendly_name) newcc->friendly_name = ne_strdup(cc->friendly_name); populate_cert(&newcc->cert, newcc->cert.subject); return newcc; dup_error: if (newcc->pkey) gnutls_x509_privkey_deinit(newcc->pkey); if (newcc->cert.subject) gnutls_x509_crt_deinit(newcc->cert.subject); ne_free(newcc); return NULL; }
/* * Create a context to authenticate to specified server, using either * ntlm or negotiate. */ int ne_sspi_create_context(void **context, char *serverName, int ntlm) { SSPIContext *sspiContext; if (initialized <= 0) { return -1; } sspiContext = ne_calloc(sizeof(SSPIContext)); sspiContext->continueNeeded = 0; if (ntlm) { sspiContext->mechanism = "NTLM"; sspiContext->serverName = ne_strdup(serverName); sspiContext->maxTokenSize = ntlmMaxTokenSize; } else { sspiContext->mechanism = "Negotiate"; sspiContext->serverName = ne_concat("HTTP/", serverName, NULL); sspiContext->maxTokenSize = negotiateMaxTokenSize; } sspiContext->ntlm = ntlm; sspiContext->authfinished = 0; *context = sspiContext; return 0; }
static void init_options(void) { char *lockowner, *tmp; char *user = getenv("USER"), *hostname = getenv("HOSTNAME"); if (user && hostname) { /* set this here so they can override it */ lockowner = ne_concat("mailto:", user, "@", hostname, NULL); set_option(opt_lockowner, lockowner); } else { set_option(opt_lockowner, NULL); } set_option(opt_editor, NULL); set_option(opt_namespace, ne_strdup(DEFAULT_NAMESPACE)); set_bool_option(opt_overwrite, 1); set_bool_option(opt_quiet, 1); set_bool_option(opt_searchall, 1); lockdepth = NE_DEPTH_INFINITE; lockscope = ne_lockscope_exclusive; searchdepth = NE_DEPTH_INFINITE; /* This is what Markus Kahn says we should do. */ if ((tmp = getenv("LC_ALL")) || (tmp = getenv("LC_CTYPE")) || (tmp = getenv("LANG"))) { if (strstr(tmp, "UTF-8")) { int val = 1; set_option(opt_utf8, &val); } } }
static int init_ssl(void) { char *server_key; ne_ssl_certificate *cert; /* take srcdir as argv[1]. */ if (test_argc > 1) { server_key = ne_concat(test_argv[1], "/server.key", NULL); } else { server_key = ne_strdup("server.key"); } ONN("sock_init failed", ne_sock_init()); server_ctx = ne_ssl_context_create(1); ONN("SSL_CTX_new failed", server_ctx == NULL); ne_ssl_context_keypair(server_ctx, "server.cert", server_key); client_ctx = ne_ssl_context_create(0); ONN("SSL_CTX_new failed for client", client_ctx == NULL); cert = ne_ssl_cert_read("ca/cert.pem"); ONN("could not load ca/cert.pem", cert == NULL); ne_ssl_context_trustcert(client_ctx, cert); ne_free(server_key); return OK; }
/* Escapes the abspath segment of a URI. * Returns ne_malloc-allocated string. */ char *uri_abspath_escape(const char *abs_path) { const char *pnt; char *ret, *retpos; int count = 0; for (pnt = abs_path; *pnt != '\0'; pnt++) { if (ESCAPE(*pnt)) { count++; } } if (count == 0) { return ne_strdup(abs_path); } /* An escaped character is "%xx", i.e., two MORE * characters than the original string */ retpos = ret = ne_malloc(strlen(abs_path) + 2*count + 1); for (pnt = abs_path; *pnt != '\0'; pnt++) { if (ESCAPE(*pnt)) { /* Escape it - %<hex><hex> */ sprintf(retpos, "%%%02x", (unsigned char) *pnt); retpos += 3; } else { /* It's cool */ *retpos++ = *pnt; } } *retpos = '\0'; return ret; }
int ne_mkcol(ne_session *sess, const char *uri) { ne_request *req; char *real_uri; int ret; if (ne_path_has_trailing_slash(uri)) { real_uri = ne_strdup(uri); } else { real_uri = ne_concat(uri, "/", NULL); } req = ne_request_create(sess, "MKCOL", real_uri); #ifdef NE_HAVE_DAV ne_lock_using_resource(req, real_uri, 0); ne_lock_using_parent(req, real_uri); #endif ret = ne_simple_request(sess, req); ne_free(real_uri); return ret; }
/* * Create a context to authenticate to specified server, using either * ntlm or negotiate. */ int ne_sspi_create_context(void **context, char *serverName, int ntlm) { SSPIContext *sspiContext; char *canonicalName; if (initialized <= 0) { return -1; } sspiContext = ne_calloc(sizeof(SSPIContext)); sspiContext->continueNeeded = 0; if (ntlm) { sspiContext->mechanism = "NTLM"; sspiContext->serverName = ne_strdup(serverName); sspiContext->maxTokenSize = ntlmMaxTokenSize; } else { sspiContext->mechanism = "Negotiate"; /* Canonicalize to conform to GSSAPI behavior */ canonicalName = canonical_hostname(serverName); sspiContext->serverName = ne_concat("HTTP/", canonicalName, NULL); ne_free(canonicalName); NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: Created context with SPN '%s'\n", sspiContext->serverName); sspiContext->maxTokenSize = negotiateMaxTokenSize; } sspiContext->ntlm = ntlm; sspiContext->authfinished = 0; *context = sspiContext; return 0; }
/* Stores the hostname/port in *info, setting up the "hostport" * segment correctly. */ static void set_hostinfo(struct host_info *hi, enum proxy_type type, const char *hostname, unsigned int port) { hi->hostname = ne_strdup(hostname); hi->port = port; hi->proxy = type; }
static int cleaner(void) { static const char *strings[] = { "alpha", "alpha", "pretty\033[41mcolours", "pretty [41mcolours", "beta\n", "beta ", "del\rt\na", "del t a", FOX_STRING, FOX_STRING, "0123456789", "0123456789", PUNC_STRING, PUNC_STRING, "\01blah blee\05bloo", " blah blee bloo", NULL, }; unsigned int n; for (n = 0; strings[n]; n+=2) { char *act = ne_strclean(ne_strdup(strings[n])); ONV(strcmp(act, strings[n+1]), ("cleansed to `%s' not `%s'", act, strings[n+1])); ne_free(act); } return OK; }
char *ne_path_escape(const char *path) { const unsigned char *pnt; char *ret, *p; size_t count = 0; for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { count += path_escape_ch(*pnt); } if (count == 0) { return ne_strdup(path); } p = ret = ne_malloc(strlen(path) + 2 * count + 1); for (pnt = (const unsigned char *)path; *pnt != '\0'; pnt++) { if (path_escape_ch(*pnt)) { /* Escape it - %<hex><hex> */ sprintf(p, "%%%02x", (unsigned char) *pnt); p += 3; } else { *p++ = *pnt; } } *p = '\0'; return ret; }
/* Examine a Basic auth challenge. * Returns 0 if an valid challenge, else non-zero. */ static int basic_challenge(auth_session *sess, struct auth_challenge *parms) { char *tmp, password[NE_ABUFSIZ]; /* Verify challenge... must have a realm */ if (parms->realm == NULL) { return -1; } NE_DEBUG(NE_DBG_HTTPAUTH, "Got Basic challenge with realm [%s]\n", parms->realm); clean_session(sess); sess->realm = ne_strdup(parms->realm); if (get_credentials(sess, password)) { /* Failed to get credentials */ return -1; } sess->scheme = auth_scheme_basic; tmp = ne_concat(sess->username, ":", password, NULL); sess->basic = ne_base64((unsigned char *)tmp, strlen(tmp)); ne_free(tmp); /* Paranoia. */ memset(password, 0, sizeof password); return 0; }
void ne_fill_proxy_uri(ne_session *sess, ne_uri *uri) { if (sess->use_proxy) { uri->host = ne_strdup(sess->proxy.hostname); uri->port = sess->proxy.port; } }
/* TODO: not a proper URI parser */ int uri_parse(const char *uri, struct uri *parsed, const struct uri *defaults) { const char *pnt, *slash, *colon; parsed->port = -1; parsed->host = NULL; parsed->path = NULL; parsed->scheme = NULL; pnt = strstr(uri, "://"); if (pnt) { parsed->scheme = ne_strndup(uri, pnt - uri); pnt += 3; /* start of hostport segment */ } else { pnt = uri; if (defaults && defaults->scheme != NULL) { parsed->scheme = ne_strdup(defaults->scheme); } } slash = strchr(pnt, '/'); colon = strchr(pnt, ':'); if (slash == NULL) { parsed->path = ne_strdup("/"); if (colon == NULL) { if (defaults) parsed->port = defaults->port; parsed->host = ne_strdup(pnt); } else { parsed->port = atoi(colon+1); parsed->host = ne_strndup(pnt, colon - pnt); } } else { if (colon == NULL || colon > slash) { /* No port segment */ if (defaults) parsed->port = defaults->port; parsed->host = ne_strndup(pnt, slash - pnt); } else { /* Port segment */ parsed->port = atoi(colon + 1); parsed->host = ne_strndup(pnt, colon - pnt); } parsed->path = ne_strdup(slash); } return 0; }
static int nulls(void) { char *str = ne_strdup("alpha,,gamma"), *pnt = str; TEST("alpha"); TEST(""); LASTTEST("gamma"); ne_free(str); pnt = str = ne_strdup(",,,wooo"); TEST(""); TEST(""); TEST(""); LASTTEST("wooo"); ne_free(str); pnt = str = ne_strdup("wooo,,,"); TEST("wooo"); TEST(""); TEST(""); LASTTEST(""); ne_free(str); return OK; }
struct ne_lock *ne_lock_copy(const struct ne_lock *lock) { struct ne_lock *ret = ne_calloc(sizeof *ret); ret->uri.path = ne_strdup(lock->uri.path); ret->uri.host = ne_strdup(lock->uri.host); ret->uri.scheme = ne_strdup(lock->uri.scheme); ret->uri.port = lock->uri.port; ret->token = ne_strdup(lock->token); ret->depth = lock->depth; ret->type = lock->type; ret->scope = lock->scope; if (lock->owner) ret->owner = ne_strdup(lock->owner); ret->timeout = lock->timeout; return ret; }
char *ne_sock_cipher(ne_socket *sock) { #ifdef NE_HAVE_SSL if (sock->ssl) { #ifdef HAVE_OPENSSL const char *name = SSL_get_cipher(sock->ssl); return ne_strdup(name); #elif defined(HAVE_GNUTLS) const char *name = gnutls_cipher_get_name(gnutls_cipher_get(sock->ssl)); return ne_strdup(name); #endif } else #endif /* NE_HAVE_SSL */ { return NULL; } }
static int empty(void) { char *str = ne_strdup(""), *pnt = str; LASTTEST(""); ne_free(str); return OK; }
static int token1(void) { char *str = ne_strdup("a,b,c,d"), *pnt = str; TEST("a"); TEST("b"); TEST("c"); LASTTEST("d"); ne_free(str); return OK; }
static int token2(void) { char *str = ne_strdup("norman,fishing, elsewhere"), *pnt = str; TEST("norman"); TEST("fishing"); LASTTEST(" elsewhere"); ne_free(str); return OK; }
/* This implemementation does not attempt to support IPv6 using * gethostbyname2 et al. */ ne_sock_addr *ne_addr_resolve(const char *hostname, int flags) { ne_sock_addr *addr = ne_calloc(sizeof *addr); #ifdef USE_GETADDRINFO struct addrinfo hints = {0}; char *pnt; hints.ai_socktype = SOCK_STREAM; if (hostname[0] == '[' && ((pnt = strchr(hostname, ']')) != NULL)) { char *hn = ne_strdup(hostname + 1); hn[pnt - hostname - 1] = '\0'; #ifdef AI_NUMERICHOST /* this was missing from the RFC2133 API */ hints.ai_flags = AI_NUMERICHOST; #endif hints.ai_family = AF_INET6; addr->errnum = getaddrinfo(hn, NULL, &hints, &addr->result); ne_free(hn); } else { hints.ai_family = ipv6_disabled ? AF_INET : AF_UNSPEC; addr->errnum = getaddrinfo(hostname, NULL, &hints, &addr->result); } #else /* Use gethostbyname() */ unsigned long laddr; struct hostent *hp; laddr = inet_addr(hostname); if (laddr == INADDR_NONE) { hp = gethostbyname(hostname); if (hp == NULL) { #ifdef WIN32 addr->errnum = WSAGetLastError(); #else addr->errnum = h_errno; #endif } else if (hp->h_length != sizeof(struct in_addr)) { /* fail gracefully if somebody set RES_USE_INET6 */ addr->errnum = NO_RECOVERY; } else { size_t n; /* count addresses */ for (n = 0; hp->h_addr_list[n] != NULL; n++) /* noop */; addr->count = n; addr->addrs = ne_malloc(n * sizeof *addr->addrs); for (n = 0; n < addr->count; n++) memcpy(&addr->addrs[n], hp->h_addr_list[n], hp->h_length); } } else { addr->addrs = ne_malloc(sizeof *addr->addrs); addr->count = 1; memcpy(addr->addrs, &laddr, sizeof *addr->addrs); } #endif return addr; }
static int badquotes(void) { char *str = ne_strdup("alpha,'blah"), *pnt = str; QTEST("alpha"); ON(ne_qtoken(&pnt, ',', QUOTES) != NULL); ne_free(str); return OK; }
/* traditional use of ne_token/ne_shave. */ static int combo(void) { char *str = ne_strdup(" fred , mary, jim , alice, david"), *pnt = str; TEST("fred"); TEST("mary"); TEST("jim"); TEST("alice"); LASTTEST("david"); ne_free(str); return 0; }