static void auth_register(ne_session *sess, int isproxy, const struct auth_class *ahc, const char *id, ne_auth_creds creds, void *userdata) { auth_session *ahs = ne_calloc(sizeof *ahs); ahs->creds = creds; ahs->userdata = userdata; ahs->sess = sess; ahs->spec = ahc; if (strcmp(ne_get_scheme(sess), "https") == 0) { ahs->context = isproxy ? AUTH_CONNECT : AUTH_NOTCONNECT; #ifdef HAVE_GSSAPI { get_gss_name(&ahs->gssname, (isproxy ? sess->proxy.hostname : sess->server.hostname)); ahs->gssctx = GSS_C_NO_CONTEXT; ahs->gssmech = GSS_C_NO_OID; } #endif } else { ahs->context = AUTH_ANY; } /* Register hooks */ ne_hook_create_request(sess, ah_create, ahs); ne_hook_pre_send(sess, ah_pre_send, ahs); ne_hook_post_send(sess, ah_post_send, ahs); ne_hook_destroy_request(sess, ah_destroy, ahs); ne_hook_destroy_session(sess, free_auth, ahs); ne_set_session_private(sess, id, ahs); }
static int copy_or_move(ne_session *sess, int is_move, int overwrite, int depth, const char *src, const char *dest) { ne_request *req = ne_request_create( sess, is_move?"MOVE":"COPY", src ); /* 2518 S8.9.2 says only use Depth: infinity with MOVE. */ if (!is_move) { ne_add_depth_header(req, depth); } #ifdef NE_HAVE_DAV if (is_move) { ne_lock_using_resource(req, src, NE_DEPTH_INFINITE); } ne_lock_using_resource(req, dest, NE_DEPTH_INFINITE); /* And we need to be able to add members to the destination's parent */ ne_lock_using_parent(req, dest); #endif ne_print_request_header(req, "Destination", "%s://%s%s", ne_get_scheme(sess), ne_get_server_hostport(sess), dest); ne_add_request_header(req, "Overwrite", overwrite?"T":"F"); return ne_simple_request(sess, req); }
static int expect100(void) { ne_socket *sock = ne_sock_create(); char req[BUFSIZ], buf[BUFSIZ]; ne_status status = {0}; const ne_inet_addr *ia; int success = 0; if (strcmp(ne_get_scheme(i_session), "https") == 0) { t_context("skipping for SSL server"); return SKIP; } for (ia = ne_addr_first(i_address); ia && !success; ia = ne_addr_next(i_address)) success = ne_sock_connect(sock, ia, i_port) == 0; ONN("could not connect to server", !success); sprintf(req, "PUT %sexpect100 HTTP/1.1" EOL "Host: %s" EOL "Content-Length: 100" EOL "Expect: 100-continue" EOL EOL, i_path, ne_get_server_hostport(i_session)); NE_DEBUG(NE_DBG_SOCKET, "Request:\n%s", req); ONS("sending request", ne_sock_fullwrite(sock, req, strlen(req))); switch (ne_sock_block(sock, 30)) { case NE_SOCK_TIMEOUT: ONN("timeout waiting for interim response", FAIL); break; case 0: /* no error. */ break; default: ONN("error reading from socket", FAIL); break; } ONS("reading status line", ne_sock_readline(sock, buf, BUFSIZ)); NE_DEBUG(NE_DBG_HTTP, "[status] %s", buf); ONN("parse status line", ne_parse_statusline(buf, &status)); if (status.code == 100) { char rbuf[100] = {0}; ONN("write request body", ne_sock_fullwrite(sock, rbuf, 100)); } ne_sock_close(sock); return OK; }
svn_error_t * svn_ra_neon__copy(svn_ra_neon__session_t *ras, svn_boolean_t overwrite, int depth, const char *src, const char *dst, apr_pool_t *pool) { const char *abs_dst; apr_hash_t *extra_headers = apr_hash_make(pool); abs_dst = apr_psprintf(pool, "%s://%s%s", ne_get_scheme(ras->ne_sess), ne_get_server_hostport(ras->ne_sess), dst); apr_hash_set(extra_headers, "Destination", APR_HASH_KEY_STRING, abs_dst); apr_hash_set(extra_headers, "Overwrite", APR_HASH_KEY_STRING, overwrite ? "T" : "F"); svn_ra_neon__add_depth_header(extra_headers, depth); return svn_ra_neon__simple_request(NULL, ras, "COPY", src, extra_headers, NULL, 201, 204, pool); }
static csync_vio_method_handle_t *owncloud_open(const char *durl, int flags, mode_t mode) { char *dir = NULL; char getUrl[PATH_MAX]; int put = 0; int rc = NE_OK; #ifdef _WIN32 int gtp = 0; char tmpname[13]; mbchar_t winTmp[PATH_MAX]; mbchar_t *winUrlMB = NULL; char *winTmpUtf8 = NULL; csync_stat_t sb; #endif struct transfer_context *writeCtx = NULL; csync_stat_t statBuf; memset( getUrl, '\0', PATH_MAX ); (void) mode; /* unused on webdav server */ DEBUG_WEBDAV( "=> open called for %s", durl ); if( rc == NE_OK ) dav_connect( durl ); if (flags & O_WRONLY) { put = 1; } if (flags & O_RDWR) { put = 1; } if (flags & O_CREAT) { put = 1; } if( rc == NE_OK && put ) { /* check if the dir name exists. Otherwise return ENOENT */ dir = c_dirname( durl ); if (dir == NULL) { errno = ENOMEM; return NULL; } DEBUG_WEBDAV("Stating directory %s", dir ); if( c_streq( dir, _lastDir )) { DEBUG_WEBDAV("Dir %s is there, we know it already.", dir); } else { if( owncloud_stat( dir, (csync_vio_method_handle_t*)(&statBuf) ) == 0 ) { DEBUG_WEBDAV("Directory of file to open exists."); SAFE_FREE( _lastDir ); _lastDir = c_strdup(dir); } else { DEBUG_WEBDAV("Directory %s of file to open does NOT exist.", dir ); /* the directory does not exist. That is an ENOENT */ errno = ENOENT; SAFE_FREE( dir ); return NULL; } } } writeCtx = c_malloc( sizeof(struct transfer_context) ); writeCtx->url = _cleanPath( durl ); if( ! writeCtx->url ) { DEBUG_WEBDAV("Failed to clean path for %s", durl ); errno = EACCES; rc = NE_ERROR; } if( rc == NE_OK && put) { DEBUG_WEBDAV("PUT request on %s!", writeCtx->url); writeCtx->req = ne_request_create(dav_session.ctx, "PUT", writeCtx->url); writeCtx->method = "PUT"; } if( rc == NE_OK && ! put ) { writeCtx->req = 0; writeCtx->method = "GET"; /* the download via the get function requires a full uri */ snprintf( getUrl, PATH_MAX, "%s://%s%s", ne_get_scheme( dav_session.ctx), ne_get_server_hostport( dav_session.ctx ), writeCtx->url ); DEBUG_WEBDAV("GET request on %s", getUrl ); writeCtx->req = ne_request_create( dav_session.ctx, "GET", getUrl ); /* Call the progress callback */ if (_file_progress_cb) { ne_set_notifier(dav_session.ctx, ne_notify_status_cb, writeCtx); _file_progress_cb( writeCtx->url, CSYNC_NOTIFY_START_DOWNLOAD, 0 , 0, _userdata); } } if( rc != NE_OK ) { SAFE_FREE( writeCtx ); writeCtx = NULL; } SAFE_FREE( dir ); return (csync_vio_method_handle_t *) writeCtx; }
static svn_error_t * generate_error(svn_ra_neon__request_t *req, apr_pool_t *pool) { int errcode = SVN_ERR_RA_DAV_REQUEST_FAILED; const char *context = apr_psprintf(req->pool, _("%s of '%s'"), req->method, req->url); const char *msg; const char *hostport; /* Convert the return codes. */ switch (req->rv) { case NE_OK: switch (req->code) { case 404: return svn_error_create(SVN_ERR_FS_NOT_FOUND, NULL, apr_psprintf(pool, _("'%s' path not found"), req->url)); case 403: return svn_error_create(SVN_ERR_RA_DAV_FORBIDDEN, NULL, apr_psprintf(pool, _("Access to '%s' forbidden"), req->url)); case 301: case 302: case 307: return svn_error_create (SVN_ERR_RA_DAV_RELOCATED, NULL, apr_psprintf(pool, (req->code == 301) ? _("Repository moved permanently to '%s';" " please relocate") : _("Repository moved temporarily to '%s';" " please relocate"), svn_ra_neon__request_get_location(req, pool))); default: return svn_error_create (errcode, NULL, apr_psprintf(pool, _("Server sent unexpected return value (%d %s) " "in response to %s request for '%s'"), req->code, req->code_desc, req->method, req->url)); } case NE_AUTH: case NE_PROXYAUTH: errcode = SVN_ERR_RA_NOT_AUTHORIZED; #ifdef SVN_NEON_0_27 /* neon >= 0.27 gives a descriptive error message after auth * failure; expose this since it's a useful diagnostic e.g. for * an unsupported challenge scheme, or a local GSSAPI error due * to an expired ticket. */ SVN_ERR(svn_utf_cstring_to_utf8(&msg, ne_get_error(req->ne_sess), pool)); msg = apr_psprintf(pool, _("authorization failed: %s"), msg); #else msg = _("authorization failed"); #endif break; case NE_CONNECT: msg = _("could not connect to server"); break; case NE_TIMEOUT: msg = _("timed out waiting for server"); break; default: /* Get the error string from neon and convert to UTF-8. */ SVN_ERR(svn_utf_cstring_to_utf8(&msg, ne_get_error(req->ne_sess), pool)); break; } /* The hostname may contain non-ASCII characters, so convert it to UTF-8. */ SVN_ERR(svn_utf_cstring_to_utf8(&hostport, ne_get_server_hostport(req->ne_sess), pool)); /*### This is a translation nightmare. Make sure to compose full strings and mark those for translation. */ return svn_error_createf(errcode, NULL, _("%s: %s (%s://%s)"), context, msg, ne_get_scheme(req->ne_sess), hostport); }
static csync_vio_method_handle_t *owncloud_open(const char *durl, int flags, mode_t mode) { char *uri = NULL; char *dir = NULL; char getUrl[PATH_MAX]; int put = 0; int rc = NE_OK; #ifdef _WIN32 int gtp = 0; char tmpname[13]; #endif struct transfer_context *writeCtx = NULL; csync_stat_t statBuf; memset( getUrl, '\0', PATH_MAX ); (void) mode; /* unused on webdav server */ DEBUG_WEBDAV(( "=> open called for %s\n", durl )); uri = _cleanPath( durl ); if( ! uri ) { DEBUG_WEBDAV(("Failed to clean path for %s\n", durl )); errno = EACCES; rc = NE_ERROR; } if( rc == NE_OK ) dav_connect( durl ); if (flags & O_WRONLY) { put = 1; } if (flags & O_RDWR) { put = 1; } if (flags & O_CREAT) { put = 1; } if( rc == NE_OK && put ) { /* check if the dir name exists. Otherwise return ENOENT */ dir = c_dirname( durl ); if (dir == NULL) { errno = ENOMEM; return NULL; } DEBUG_WEBDAV(("Stating directory %s\n", dir )); if( c_streq( dir, _lastDir )) { DEBUG_WEBDAV(("Dir %s is there, we know it already.\n", dir)); } else { if( owncloud_stat( dir, (csync_vio_method_handle_t*)(&statBuf) ) == 0 ) { DEBUG_WEBDAV(("Directory of file to open exists.\n")); SAFE_FREE( _lastDir ); _lastDir = c_strdup(dir); } else { DEBUG_WEBDAV(("Directory %s of file to open does NOT exist.\n", dir )); /* the directory does not exist. That is an ENOENT */ errno = ENOENT; SAFE_FREE( dir ); return NULL; } } } writeCtx = c_malloc( sizeof(struct transfer_context) ); writeCtx->bytes_written = 0; if( rc == NE_OK ) { /* open a temp file to store the incoming data */ #ifdef _WIN32 memset( tmpname, '\0', 13 ); gtp = GetTempPath( PATH_MAX, getUrl ); DEBUG_WEBDAV(("win32 tmp path: %s\n", getUrl )); if ( gtp > MAX_PATH || (gtp == 0) ) { DEBUG_WEBDAV(("Failed to compute Win32 tmp path, trying /tmp\n")); strcpy( getUrl, "/tmp/"); } strcpy( tmpname, "csync.XXXXXX" ); if( c_tmpname( tmpname ) == 0 ) { _fmode = _O_BINARY; strcat( getUrl, tmpname ); writeCtx->tmpFileName = c_strdup( getUrl ); writeCtx->fd = open( writeCtx->tmpFileName, O_RDWR | O_CREAT | O_EXCL, 0600 ); } else { writeCtx->fd = -1; } #else writeCtx->tmpFileName = c_strdup( "/tmp/csync.XXXXXX" ); writeCtx->fd = mkstemp( writeCtx->tmpFileName ); #endif DEBUG_WEBDAV(("opening temp directory %s: %d\n", writeCtx->tmpFileName, writeCtx->fd )); if( writeCtx->fd == -1 ) { DEBUG_WEBDAV(("Failed to open temp file, errno = %d\n", errno )); rc = NE_ERROR; /* errno is set by the mkstemp call above. */ } } if( rc == NE_OK && put) { DEBUG_WEBDAV(("PUT request on %s!\n", uri)); /* reset the write buffer */ writeCtx->bytes_written = 0; writeCtx->fileWritten = 0; /* flag to indicate if contents was pushed to file */ writeCtx->req = ne_request_create(dav_session.ctx, "PUT", uri); writeCtx->method = "PUT"; } if( rc == NE_OK && ! put ) { writeCtx->req = 0; writeCtx->method = "GET"; /* Download the data into a local temp file. */ /* the download via the get function requires a full uri */ snprintf( getUrl, PATH_MAX, "%s://%s%s", ne_get_scheme( dav_session.ctx), ne_get_server_hostport( dav_session.ctx ), uri ); DEBUG_WEBDAV(("GET request on %s\n", getUrl )); #define WITH_HTTP_COMPRESSION #ifdef WITH_HTTP_COMPRESSION writeCtx->req = ne_request_create( dav_session.ctx, "GET", getUrl ); /* Allow compressed content by setting the header */ ne_add_request_header( writeCtx->req, "Accept-Encoding", "gzip,deflate" ); /* hook called before the content is parsed to set the correct reader, * either the compressed- or uncompressed reader. */ ne_hook_post_headers( dav_session.ctx, install_content_reader, writeCtx ); /* actually do the request */ rc = ne_request_dispatch(writeCtx->req ); /* possible return codes are: * NE_OK, NE_AUTH, NE_CONNECT, NE_TIMEOUT, NE_ERROR (from ne_request.h) */ if( rc != NE_OK || (rc == NE_OK && ne_get_status(writeCtx->req)->klass != 2) ) { DEBUG_WEBDAV(("request_dispatch failed with rc=%d\n", rc )); if( rc == NE_OK ) rc = NE_ERROR; errno = EACCES; } /* delete the hook again, otherwise they get chained as they are with the session */ ne_unhook_post_headers( dav_session.ctx, install_content_reader, writeCtx ); /* if the compression handle is set through the post_header hook, delete it. */ if( writeCtx->decompress ) { ne_decompress_destroy( writeCtx->decompress ); } /* delete the request in any case */ ne_request_destroy(writeCtx->req); #else DEBUG_WEBDAV(("GET Compression not supported!\n")); rc = ne_get( dav_session.ctx, getUrl, writeCtx->fd ); /* FIX_ESCAPE? */ #endif if( rc != NE_OK ) { DEBUG_WEBDAV(("Download to local file failed: %d.\n", rc)); errno = EACCES; } if( close( writeCtx->fd ) == -1 ) { DEBUG_WEBDAV(("Close of local download file failed.\n")); writeCtx->fd = -1; rc = NE_ERROR; errno = EACCES; } writeCtx->fd = -1; } if( rc != NE_OK ) { SAFE_FREE( writeCtx ); } SAFE_FREE( uri ); SAFE_FREE( dir ); return (csync_vio_method_handle_t *) writeCtx; }