static PyObject* _cbson_insert_message(PyObject* self, PyObject* args) { /* NOTE just using a random number as the request_id */ struct module_state *state = GETSTATE(self); int request_id = rand(); char* collection_name = NULL; int collection_name_length; PyObject* docs; PyObject* doc; PyObject* iterator; int before, cur_size, max_size = 0; int options = 0; unsigned char check_keys; unsigned char safe; unsigned char continue_on_error; unsigned char uuid_subtype; PyObject* last_error_args; buffer_t buffer; int length_location, message_length; PyObject* result; if (!PyArg_ParseTuple(args, "et#ObbObb", "utf-8", &collection_name, &collection_name_length, &docs, &check_keys, &safe, &last_error_args, &continue_on_error, &uuid_subtype)) { return NULL; } if (continue_on_error) { options += 1; } buffer = buffer_new(); if (!buffer) { PyErr_NoMemory(); PyMem_Free(collection_name); return NULL; } // save space for message length length_location = buffer_save_space(buffer, 4); if (length_location == -1) { PyMem_Free(collection_name); PyErr_NoMemory(); return NULL; } if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00" "\xd2\x07\x00\x00", 8) || !buffer_write_bytes(buffer, (const char*)&options, 4) || !buffer_write_bytes(buffer, collection_name, collection_name_length + 1)) { PyMem_Free(collection_name); buffer_free(buffer); return NULL; } iterator = PyObject_GetIter(docs); if (iterator == NULL) { PyObject* InvalidOperation = _error("InvalidOperation"); PyErr_SetString(InvalidOperation, "input is not iterable"); Py_DECREF(InvalidOperation); buffer_free(buffer); PyMem_Free(collection_name); return NULL; } while ((doc = PyIter_Next(iterator)) != NULL) { before = buffer_get_position(buffer); if (!write_dict(state->_cbson, buffer, doc, check_keys, uuid_subtype, 1)) { Py_DECREF(doc); Py_DECREF(iterator); buffer_free(buffer); PyMem_Free(collection_name); return NULL; } Py_DECREF(doc); cur_size = buffer_get_position(buffer) - before; max_size = (cur_size > max_size) ? cur_size : max_size; } Py_DECREF(iterator); if (PyErr_Occurred()) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } if (!max_size) { PyObject* InvalidOperation = _error("InvalidOperation"); PyErr_SetString(InvalidOperation, "cannot do an empty bulk insert"); Py_DECREF(InvalidOperation); buffer_free(buffer); PyMem_Free(collection_name); return NULL; } message_length = buffer_get_position(buffer) - length_location; memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); if (safe) { if (!add_last_error(self, buffer, request_id, collection_name, collection_name_length, last_error_args)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } } PyMem_Free(collection_name); /* objectify buffer */ result = Py_BuildValue("i" BYTES_FORMAT_STRING "i", request_id, buffer_get_buffer(buffer), buffer_get_position(buffer), max_size); buffer_free(buffer); return result; }
int network_init(server *srv) { buffer *b; size_t i; network_backend_t backend; struct nb_map { network_backend_t nb; const char *name; } network_backends[] = { /* lowest id wins */ #if defined USE_LINUX_SENDFILE { NETWORK_BACKEND_LINUX_SENDFILE, "linux-sendfile" }, #endif #if defined USE_FREEBSD_SENDFILE { NETWORK_BACKEND_FREEBSD_SENDFILE, "freebsd-sendfile" }, #endif #if defined USE_SOLARIS_SENDFILEV { NETWORK_BACKEND_SOLARIS_SENDFILEV, "solaris-sendfilev" }, #endif #if defined USE_WRITEV { NETWORK_BACKEND_WRITEV, "writev" }, #endif { NETWORK_BACKEND_WRITE, "write" }, { NETWORK_BACKEND_UNSET, NULL } }; b = buffer_init(); buffer_copy_string_buffer(b, srv->srvconf.bindhost); buffer_append_string_len(b, CONST_STR_LEN(":")); buffer_append_long(b, srv->srvconf.port); if (0 != network_server_init(srv, b, srv->config_storage[0])) { return -1; } buffer_free(b); #ifdef USE_OPENSSL srv->network_ssl_backend_write = network_write_chunkqueue_openssl; #endif /* get a usefull default */ backend = network_backends[0].nb; /* match name against known types */ if (!buffer_is_empty(srv->srvconf.network_backend)) { for (i = 0; network_backends[i].name; i++) { /**/ if (buffer_is_equal_string(srv->srvconf.network_backend, network_backends[i].name, strlen(network_backends[i].name))) { backend = network_backends[i].nb; break; } } if (NULL == network_backends[i].name) { /* we don't know it */ log_error_write(srv, __FILE__, __LINE__, "sb", "server.network-backend has a unknown value:", srv->srvconf.network_backend); return -1; } } switch(backend) { case NETWORK_BACKEND_WRITE: srv->network_backend_write = network_write_chunkqueue_write; break; #ifdef USE_WRITEV case NETWORK_BACKEND_WRITEV: srv->network_backend_write = network_write_chunkqueue_writev; break; #endif #ifdef USE_LINUX_SENDFILE case NETWORK_BACKEND_LINUX_SENDFILE: srv->network_backend_write = network_write_chunkqueue_linuxsendfile; break; #endif #ifdef USE_FREEBSD_SENDFILE case NETWORK_BACKEND_FREEBSD_SENDFILE: srv->network_backend_write = network_write_chunkqueue_freebsdsendfile; break; #endif #ifdef USE_SOLARIS_SENDFILEV case NETWORK_BACKEND_SOLARIS_SENDFILEV: srv->network_backend_write = network_write_chunkqueue_solarissendfilev; break; #endif default: return -1; } /* check for $SERVER["socket"] */ for (i = 1; i < srv->config_context->used; i++) { data_config *dc = (data_config *)srv->config_context->data[i]; specific_config *s = srv->config_storage[i]; size_t j; /* not our stage */ if (COMP_SERVER_SOCKET != dc->comp) continue; if (dc->cond != CONFIG_COND_EQ) { log_error_write(srv, __FILE__, __LINE__, "s", "only == is allowed for $SERVER[\"socket\"]."); return -1; } /* check if we already know this socket, * if yes, don't init it */ for (j = 0; j < srv->srv_sockets.used; j++) { if (buffer_is_equal(srv->srv_sockets.ptr[j]->srv_token, dc->string)) { break; } } if (j == srv->srv_sockets.used) { if (0 != network_server_init(srv, dc->string, s)) return -1; } } return 0; }
void server_free(server *srv) { size_t i; for (i = 0; i < FILE_CACHE_MAX; i++) { buffer_free(srv->mtime_cache[i].str); } #ifdef USE_LINUX_AIO_SENDFILE if (srv->linux_io_ctx) { io_destroy(srv->linux_io_ctx); } #endif #define CLEAN(x) \ buffer_free(srv->x); CLEAN(response_header); CLEAN(parse_full_path); CLEAN(ts_debug_str); CLEAN(ts_date_str); CLEAN(response_range); CLEAN(tmp_buf); CLEAN(empty_string); CLEAN(cond_check_buf); CLEAN(srvconf.errorlog_file); CLEAN(srvconf.breakagelog_file); CLEAN(srvconf.groupname); CLEAN(srvconf.username); CLEAN(srvconf.changeroot); CLEAN(srvconf.bindhost); CLEAN(srvconf.event_handler); CLEAN(srvconf.pid_file); CLEAN(srvconf.modules_dir); CLEAN(srvconf.network_backend); CLEAN(tmp_chunk_len); #undef CLEAN #ifdef USE_GTHREAD fdevent_unregister(srv->ev, srv->wakeup_iosocket); iosocket_free(srv->wakeup_iosocket); #endif #if 0 fdevent_unregister(srv->ev, srv->fd); #endif fdevent_free(srv->ev); free(srv->conns); if (srv->config_storage) { for (i = 0; i < srv->config_context->used; i++) { specific_config *s = srv->config_storage[i]; if (!s) continue; buffer_free(s->document_root); buffer_free(s->server_name); buffer_free(s->server_tag); buffer_free(s->ssl_pemfile); buffer_free(s->ssl_ca_file); buffer_free(s->error_handler); buffer_free(s->errorfile_prefix); array_free(s->mimetypes); buffer_free(s->ssl_cipher_list); free(s); } free(srv->config_storage); srv->config_storage = NULL; } #define CLEAN(x) \ array_free(srv->x); CLEAN(config_context); /* TODO: Seems to not like this inside tests */ // CLEAN(config_touched); CLEAN(srvconf.upload_tempdirs); #undef CLEAN joblist_free(srv, srv->joblist); joblist_free(srv, srv->joblist_prev); fdwaitqueue_free(srv, srv->fdwaitqueue); if (srv->stat_cache) { stat_cache_free(srv->stat_cache); } array_free(srv->srvconf.modules); array_free(srv->split_vals); #ifdef USE_OPENSSL if (srv->ssl_is_init) { CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); ERR_remove_state(0); EVP_cleanup(); } #endif free(srv); }
/* ** mexFunction is the interface function to MATLAB. ** ** plhs - pointer to left-hand OUTPUT mxArrays ** nlhs - number of left-hand OUTPUT arrays ** prhs - pointer to right-hand INPUT mxArrays ** nrhs - number of right-hand INPUT arrays ** */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { fpnum bkgr_green[] = {0.0,1.0,0.0}; /* Background colour */ buffer *bf_mvec,*bf_pvec,*bf_pvecn,*bf_rimg,*bf_blobimg; buffer *bf_bkgr; ibuffer *bf_limg; const int *arg_dims; int arg_ndims,grxfl,rows,cols; int out_dims[]={0,0,0}; int mdims[]={0,0,0}; /* Argument count check */ if((nrhs <4)||(nrhs>5)) { if(nrhs !=0) mexPrintf("Error: 4-5 input arguments expected.\n"); goto mexErrExit; } /* Parse arg 1 (mvec) */ mdims[0]=6;mdims[1]=-1; if(!type_check("mvec",prhs[0],mxDOUBLE_CLASS,2,mdims)) goto mexErrExit; bf_mvec=buffer_encapsulate(prhs[0]); /* Parse arg 2 (pvec) */ mdims[0]=-1;mdims[1]=bf_mvec->cols; if(!type_check("pvec",prhs[1],mxDOUBLE_CLASS,2,mdims)) goto mexErrExit; bf_pvec=buffer_encapsulate(prhs[1]); /* Parse arg 3 (rows) */ mdims[0]=1;mdims[1]=1; if(!type_check("rows",prhs[2],mxDOUBLE_CLASS,2,mdims)) goto mexErrExit; rows=mxGetScalar(prhs[2]); /* Parse arg 4 (cols) */ mdims[0]=1;mdims[1]=1; if(!type_check("cols",prhs[3],mxDOUBLE_CLASS,2,mdims)) goto mexErrExit; cols=mxGetScalar(prhs[3]); /* Set image size */ out_dims[0]=rows; out_dims[1]=cols; /* Copy number of colour bands */ out_dims[2]=bf_pvec->rows; /* Parse arg 4 (bkgr) */ if(nrhs==5) { mdims[0]=out_dims[2];mdims[1]=1; if(!type_check("bkgr",prhs[4],mxDOUBLE_CLASS,2,mdims)) goto mexErrExit; bf_bkgr=buffer_encapsulate(prhs[4]); } else { bf_bkgr=buffer_new0(bkgr_green,3,1,1); /* Use default */ } /* Extend grey to RGB? */ grxfl=0; if(out_dims[2]==1) { grxfl=1; pvec_to_rgb(bf_pvec,&bf_pvecn); out_dims[2]=3; } /* Call visualisation functions */ if(nlhs>0) { /* Create an empty green image */ plhs[0] = mxCreateNumericArray(3,out_dims,mxDOUBLE_CLASS,mxREAL); bf_blobimg = buffer_encapsulate(plhs[0]); buffer_paint(bf_blobimg,bf_bkgr); /* Set area to approximating ellipse area */ mvec_set_area(bf_mvec); /* Blobs are drawn in descending area order */ /* Visualise blobs in the green image */ if(grxfl) draw_ellipses(bf_blobimg,bf_mvec,bf_pvecn); else draw_ellipses(bf_blobimg,bf_mvec,bf_pvec); free(bf_blobimg); /* Only release struct */ } /* Free memory */ free(bf_mvec); /* Only release struct */ free(bf_bkgr); /* Only release struct */ free(bf_pvec); /* Only release struct */ if(grxfl) buffer_free(bf_pvecn); /* Jump to normal exit */ goto mexExit; /* Exit with error message */ mexErrExit: mexPrintf("Usage: <Bimg>=draw_blobs(<mvec>,<pvec>,<rows>,<cols>[,<bkgr>])\n"); mexExit: {} }
static int config_insert(server *srv) { size_t i; int ret = 0; buffer *stat_cache_string; config_values_t cv[] = { { "server.bind", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 */ { "server.errorlog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 */ { "server.errorfile-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 2 */ { "server.chroot", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 3 */ { "server.username", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 4 */ { "server.groupname", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 5 */ { "server.port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 6 */ { "server.tag", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ { "server.use-ipv6", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */ { "server.modules", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 9 */ { "server.event-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */ { "server.pid-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */ { "server.max-request-size", NULL, T_CONFIG_INT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ { "server.max-worker", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 13 */ { "server.document-root", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 14 */ { "server.force-lowercase-filenames", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 15 */ { "debug.log-condition-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 16 */ { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */ { "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 18 */ { "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 19 */ { "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 20 */ { "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 21 */ { "server.error-handler-404", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 22 */ { "server.max-fds", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 23 */ #ifdef HAVE_LSTAT { "server.follow-symlink", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 24 */ #else { "server.follow-symlink", "Your system lacks lstat(). We cant differ symlinks from files." "Please remove server.follow-symlinks from your config.", T_CONFIG_UNSUPPORTED, T_CONFIG_SCOPE_UNSET }, /* 24 */ #endif { "server.kbytes-per-second", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 25 */ { "connection.kbytes-per-second", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 26 */ { "mimetype.use-xattr", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */ { "mimetype.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 28 */ { "ssl.pemfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 29 */ { "ssl.engine", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 30 */ { "debug.log-file-not-found", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 31 */ { "debug.log-request-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 32 */ { "debug.log-response-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 33 */ { "debug.log-request-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 34 */ { "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 35 */ { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */ { "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */ { "ssl.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 38 */ { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 39 */ { "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */ { "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */ { "server.max-connections", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 42 */ { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 43 */ { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 44 */ { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */ { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 46 */ { "server.use-noatime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 49 */ { "server.max-stat-threads", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 48 */ { "server.max-read-threads", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 49 */ { "server.max-connection-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 50 */ { "debug.log-timing", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 51 */ { "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 52 */ { "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */ { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 54 */ { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 55 */ { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 56 */ { "server.breakagelog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 57 */ { "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 58 */ { "debug.log-ssl-noise", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 59 */ { "ssl.verifyclient.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 60 */ { "ssl.verifyclient.enforce", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 61 */ { "ssl.verifyclient.depth", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 62 */ { "ssl.verifyclient.username", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 63 */ { "ssl.verifyclient.exportcert", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 64 */ { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.virtual-default-host", "load mod_simple_vhost and use simple-vhost.default-host instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.virtual-docroot", "load mod_simple_vhost and use simple-vhost.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.userid", "use server.username instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.groupid", "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.use-keep-alive", "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.force-lower-case-files", "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; /* 0 */ cv[0].destination = srv->srvconf.bindhost; cv[1].destination = srv->srvconf.errorlog_file; cv[3].destination = srv->srvconf.changeroot; cv[4].destination = srv->srvconf.username; cv[5].destination = srv->srvconf.groupname; cv[6].destination = &(srv->srvconf.port); cv[9].destination = srv->srvconf.modules; cv[10].destination = srv->srvconf.event_handler; cv[11].destination = srv->srvconf.pid_file; cv[13].destination = &(srv->srvconf.max_worker); cv[23].destination = &(srv->srvconf.max_fds); cv[36].destination = &(srv->srvconf.log_request_header_on_error); cv[37].destination = &(srv->srvconf.log_state_handling); cv[39].destination = &(srv->srvconf.errorlog_use_syslog); stat_cache_string = buffer_init(); cv[41].destination = stat_cache_string; cv[43].destination = srv->srvconf.network_backend; cv[44].destination = srv->srvconf.upload_tempdirs; cv[45].destination = &(srv->srvconf.enable_cores); cv[42].destination = &(srv->srvconf.max_conns); cv[12].destination = &(srv->srvconf.max_request_size); cv[47].destination = &(srv->srvconf.use_noatime); cv[48].destination = &(srv->srvconf.max_stat_threads); cv[49].destination = &(srv->srvconf.max_read_threads); cv[51].destination = &(srv->srvconf.log_timing); cv[57].destination = srv->srvconf.breakagelog_file; srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); assert(srv->config_storage); for (i = 0; i < srv->config_context->used; i++) { specific_config *s; s = calloc(1, sizeof(specific_config)); assert(s); s->document_root = buffer_init(); s->mimetypes = array_init(); s->server_name = buffer_init(); s->ssl_pemfile = buffer_init(); s->ssl_ca_file = buffer_init(); s->error_handler = buffer_init(); s->server_tag = buffer_init(); s->errorfile_prefix = buffer_init(); s->ssl_cipher_list = buffer_init(); s->ssl_use_sslv2 = 1; s->ssl_verifyclient = 0; s->ssl_verifyclient_enforce = 1; s->ssl_verifyclient_username = buffer_init(); s->ssl_verifyclient_depth = 9; s->ssl_verifyclient_export_cert = 0; s->max_keep_alive_requests = 16; s->max_keep_alive_idle = 5; s->max_read_idle = 60; s->max_write_idle = 360; s->max_connection_idle = 360; s->use_xattr = 0; s->is_ssl = 0; s->use_ipv6 = 0; #ifdef HAVE_LSTAT s->follow_symlink = 1; #endif s->kbytes_per_second = 0; s->allow_http11 = 1; s->range_requests = 1; s->etag_use_inode = 1; s->etag_use_mtime = 1; s->etag_use_size = 1; s->force_lowercase_filenames = 0; s->global_kbytes_per_second = 0; s->global_bytes_per_second_cnt = 0; s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt; cv[2].destination = s->errorfile_prefix; cv[7].destination = s->server_tag; cv[8].destination = &(s->use_ipv6); /* 13 max-worker */ cv[14].destination = s->document_root; cv[15].destination = &(s->force_lowercase_filenames); cv[16].destination = &(s->log_condition_handling); cv[46].destination = &(s->log_condition_cache_handling); cv[17].destination = &(s->max_keep_alive_requests); cv[18].destination = s->server_name; cv[19].destination = &(s->max_keep_alive_idle); cv[20].destination = &(s->max_read_idle); cv[21].destination = &(s->max_write_idle); cv[22].destination = s->error_handler; #ifdef HAVE_LSTAT cv[24].destination = &(s->follow_symlink); #endif /* 23 -> max-fds */ cv[25].destination = &(s->global_kbytes_per_second); cv[26].destination = &(s->kbytes_per_second); cv[27].destination = &(s->use_xattr); cv[28].destination = s->mimetypes; cv[29].destination = s->ssl_pemfile; cv[30].destination = &(s->is_ssl); cv[31].destination = &(s->log_file_not_found); cv[32].destination = &(s->log_request_handling); cv[33].destination = &(s->log_response_header); cv[34].destination = &(s->log_request_header); cv[35].destination = &(s->allow_http11); cv[38].destination = s->ssl_ca_file; cv[40].destination = &(s->range_requests); cv[50].destination = &(s->max_connection_idle); cv[52].destination = s->ssl_cipher_list; cv[53].destination = &(s->ssl_use_sslv2); cv[54].destination = &(s->etag_use_inode); cv[55].destination = &(s->etag_use_mtime); cv[56].destination = &(s->etag_use_size); cv[58].destination = &(s->log_timeouts); cv[59].destination = &(s->log_ssl_noise); /* ssl.verify */ cv[60].destination = &(s->ssl_verifyclient); cv[61].destination = &(s->ssl_verifyclient_enforce); cv[62].destination = &(s->ssl_verifyclient_depth); cv[63].destination = s->ssl_verifyclient_username; cv[64].destination = &(s->ssl_verifyclient_export_cert); srv->config_storage[i] = s; if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) { break; } } if (buffer_is_empty(stat_cache_string)) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE; } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE; #ifdef HAVE_FAM_H } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("fam"))) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_FAM; #endif #if defined(HAVE_SYS_INOTIFY_H) } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("inotify"))) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_INOTIFY; #endif } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE; } else { log_error_write(srv, __FILE__, __LINE__, "sb", "server.stat-cache-engine can be one of \"disable\", \"simple\"" #ifdef HAVE_FAM_H ", \"fam\"" #endif #if defined(HAVE_SYS_INOTIFY_H) ", \"inotify\"" #endif " but not:", stat_cache_string); ret = HANDLER_ERROR; } buffer_free(stat_cache_string); return ret; }
int ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen) { DSA_SIG *sig; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN]; u_int rlen, slen, len, dlen; Buffer b; if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { error("ssh_dss_sign: no DSA key"); return -1; } EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); sig = DSA_do_sign(digest, dlen, key->dsa); memset(digest, 'd', sizeof(digest)); if (sig == NULL) { error("ssh_dss_sign: sign failed"); return -1; } rlen = BN_num_bytes(sig->r); slen = BN_num_bytes(sig->s); if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { error("bad sig size %u %u", rlen, slen); DSA_SIG_free(sig); return -1; } memset(sigblob, 0, SIGBLOB_LEN); BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); DSA_SIG_free(sig); if (datafellows & SSH_BUG_SIGBLOB) { if (lenp != NULL) *lenp = SIGBLOB_LEN; if (sigp != NULL) { *sigp = xmalloc(SIGBLOB_LEN); memcpy(*sigp, sigblob, SIGBLOB_LEN); } } else { /* ietf-drafts */ buffer_init(&b); buffer_put_cstring(&b, "ssh-dss"); buffer_put_string(&b, sigblob, SIGBLOB_LEN); len = buffer_len(&b); if (lenp != NULL) *lenp = len; if (sigp != NULL) { *sigp = xmalloc(len); memcpy(*sigp, buffer_ptr(&b), len); } buffer_free(&b); } return 0; }
static int get_wav_metadata(PerlIO *infile, char *file, HV *info, HV *tags) { Buffer buf; off_t file_size; int err = 0; uint32_t chunk_size; file_size = _file_size(infile); buffer_init(&buf, WAV_BLOCK_SIZE); if ( !_check_buf(infile, &buf, 12, WAV_BLOCK_SIZE) ) { err = -1; goto out; } if ( !strncmp( (char *)buffer_ptr(&buf), "RIFF", 4 ) ) { // We've got a RIFF file buffer_consume(&buf, 4); chunk_size = buffer_get_int_le(&buf); // Check format if ( strncmp( (char *)buffer_ptr(&buf), "WAVE", 4 ) ) { PerlIO_printf(PerlIO_stderr(), "Invalid WAV file: missing WAVE header: %s\n", file); err = -1; goto out; } buffer_consume(&buf, 4); my_hv_store( info, "file_size", newSVuv(file_size) ); _parse_wav(infile, &buf, file, file_size, info, tags); } else if ( !strncmp( (char *)buffer_ptr(&buf), "FORM", 4 ) ) { // We've got an AIFF file char *bptr; buffer_consume(&buf, 4); chunk_size = buffer_get_int(&buf); // Check format bptr = buffer_ptr(&buf); if ( bptr[0] == 'A' && bptr[1] == 'I' && bptr[2] == 'F' && (bptr[3] == 'F' || bptr[3] == 'C') ) { buffer_consume(&buf, 4); my_hv_store( info, "file_size", newSVuv(file_size) ); _parse_aiff(infile, &buf, file, file_size, info, tags); } else { PerlIO_printf(PerlIO_stderr(), "Invalid AIFF file: missing AIFF header: %s\n", file); err = -1; goto out; } } else { PerlIO_printf(PerlIO_stderr(), "Invalid WAV file: missing RIFF header: %s\n", file); err = -1; goto out; } out: buffer_free(&buf); if (err) return err; return 0; }
static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow_id) { buffer_t buffer = (buffer_t)NUM2LL(rb_ary_entry(extra, 0)); VALUE check_keys = rb_ary_entry(extra, 1); if (TYPE(key) == T_SYMBOL) { // TODO better way to do this... ? key = rb_str_new2(rb_id2name(SYM2ID(key))); } if (TYPE(key) != T_STRING) { buffer_free(buffer); rb_raise(rb_eTypeError, "keys must be strings or symbols"); } if (!allow_id && strcmp("_id", RSTRING_PTR(key)) == 0) { return ST_CONTINUE; } if (check_keys == Qtrue) { int i; if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') { buffer_free(buffer); rb_raise(InvalidName, "key must not start with '$'"); } for (i = 0; i < RSTRING_LEN(key); i++) { if (RSTRING_PTR(key)[i] == '.') { buffer_free(buffer); rb_raise(InvalidName, "key must not contain '.'"); } } } switch(TYPE(value)) { case T_BIGNUM: case T_FIXNUM: { if (rb_funcall(value, rb_intern(">"), 1, LL2NUM(9223372036854775807LL)) == Qtrue || rb_funcall(value, rb_intern("<"), 1, LL2NUM(-9223372036854775808LL)) == Qtrue) { buffer_free(buffer); rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints"); } if (rb_funcall(value, rb_intern(">"), 1, INT2NUM(2147483647L)) == Qtrue || rb_funcall(value, rb_intern("<"), 1, INT2NUM(-2147483648L)) == Qtrue) { long long ll_value; write_name_and_type(buffer, key, 0x12); ll_value = NUM2LL(value); SAFE_WRITE(buffer, (char*)&ll_value, 8); } else { int int_value; write_name_and_type(buffer, key, 0x10); int_value = NUM2LL(value); SAFE_WRITE(buffer, (char*)&int_value, 4); } break; } case T_TRUE: { write_name_and_type(buffer, key, 0x08); SAFE_WRITE(buffer, &one, 1); break; } case T_FALSE: { write_name_and_type(buffer, key, 0x08); SAFE_WRITE(buffer, &zero, 1); break; } case T_FLOAT: { double d = NUM2DBL(value); write_name_and_type(buffer, key, 0x01); SAFE_WRITE(buffer, (char*)&d, 8); break; } case T_NIL: { write_name_and_type(buffer, key, 0x0A); break; } case T_HASH: { write_name_and_type(buffer, key, 0x03); write_doc(buffer, value, check_keys); break; } case T_ARRAY: { buffer_position length_location, start_position, obj_length; int items, i; VALUE* values; write_name_and_type(buffer, key, 0x04); start_position = buffer_get_position(buffer); // save space for length length_location = buffer_save_space(buffer, 4); if (length_location == -1) { rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); } items = RARRAY_LEN(value); values = RARRAY_PTR(value); for(i = 0; i < items; i++) { char* name; VALUE key; INT2STRING(&name, i); key = rb_str_new2(name); write_element(key, values[i], pack_extra(buffer, check_keys)); free(name); } // write null byte and fill in length SAFE_WRITE(buffer, &zero, 1); obj_length = buffer_get_position(buffer) - start_position; SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4); break; } case T_STRING: { if (strcmp(rb_class2name(RBASIC(value)->klass), "Mongo::Code") == 0) { buffer_position length_location, start_position, total_length; int length; write_name_and_type(buffer, key, 0x0F); start_position = buffer_get_position(buffer); length_location = buffer_save_space(buffer, 4); if (length_location == -1) { rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); } length = RSTRING_LEN(value) + 1; SAFE_WRITE(buffer, (char*)&length, 4); SAFE_WRITE(buffer, RSTRING_PTR(value), length - 1); SAFE_WRITE(buffer, &zero, 1); write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse); total_length = buffer_get_position(buffer) - start_position; SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&total_length, 4); break; } else { int length; write_name_and_type(buffer, key, 0x02); value = TO_UTF8(value); length = RSTRING_LEN(value) + 1; SAFE_WRITE(buffer, (char*)&length, 4); write_utf8(buffer, value); SAFE_WRITE(buffer, &zero, 1); break; } } case T_SYMBOL: { const char* str_value = rb_id2name(SYM2ID(value)); int length = strlen(str_value) + 1; write_name_and_type(buffer, key, 0x0E); SAFE_WRITE(buffer, (char*)&length, 4); SAFE_WRITE(buffer, str_value, length); break; } case T_OBJECT: { // TODO there has to be a better way to do these checks... const char* cls = rb_class2name(RBASIC(value)->klass); if (strcmp(cls, "Mongo::Binary") == 0 || strcmp(cls, "ByteBuffer") == 0) { const char subtype = strcmp(cls, "ByteBuffer") ? (const char)FIX2INT(rb_funcall(value, rb_intern("subtype"), 0)) : 2; VALUE string_data = rb_funcall(value, rb_intern("to_s"), 0); int length = RSTRING_LEN(string_data); write_name_and_type(buffer, key, 0x05); if (subtype == 2) { const int other_length = length + 4; SAFE_WRITE(buffer, (const char*)&other_length, 4); SAFE_WRITE(buffer, &subtype, 1); } SAFE_WRITE(buffer, (const char*)&length, 4); if (subtype != 2) { SAFE_WRITE(buffer, &subtype, 1); } SAFE_WRITE(buffer, RSTRING_PTR(string_data), length); break; } if (strcmp(cls, "Mongo::ObjectID") == 0) { VALUE as_array = rb_funcall(value, rb_intern("to_a"), 0); int i; write_name_and_type(buffer, key, 0x07); for (i = 0; i < 12; i++) { char byte = (char)FIX2INT(RARRAY_PTR(as_array)[i]); SAFE_WRITE(buffer, &byte, 1); } break; } if (strcmp(cls, "Mongo::DBRef") == 0) { buffer_position length_location, start_position, obj_length; VALUE ns, oid; write_name_and_type(buffer, key, 0x03); start_position = buffer_get_position(buffer); // save space for length length_location = buffer_save_space(buffer, 4); if (length_location == -1) { rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); } ns = rb_funcall(value, rb_intern("namespace"), 0); write_element(rb_str_new2("$ref"), ns, pack_extra(buffer, Qfalse)); oid = rb_funcall(value, rb_intern("object_id"), 0); write_element(rb_str_new2("$id"), oid, pack_extra(buffer, Qfalse)); // write null byte and fill in length SAFE_WRITE(buffer, &zero, 1); obj_length = buffer_get_position(buffer) - start_position; SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4); break; } } case T_DATA: { // TODO again, is this really the only way to do this? const char* cls = rb_class2name(RBASIC(value)->klass); if (strcmp(cls, "Time") == 0) { double t = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0)); long long time_since_epoch = (long long)round(t * 1000); write_name_and_type(buffer, key, 0x09); SAFE_WRITE(buffer, (const char*)&time_since_epoch, 8); break; } } case T_REGEXP: { int length = RREGEXP_SRC_LEN(value); char* pattern = (char*)RREGEXP_SRC_PTR(value); long flags = RREGEXP(value)->ptr->options; VALUE has_extra; write_name_and_type(buffer, key, 0x0B); SAFE_WRITE(buffer, pattern, length); SAFE_WRITE(buffer, &zero, 1); if (flags & IGNORECASE) { char ignorecase = 'i'; SAFE_WRITE(buffer, &ignorecase, 1); } if (flags & MULTILINE) { char multiline = 'm'; SAFE_WRITE(buffer, &multiline, 1); } if (flags & EXTENDED) { char extended = 'x'; SAFE_WRITE(buffer, &extended, 1); } has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str")); if (TYPE(has_extra) == T_TRUE) { VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0); buffer_position old_position = buffer_get_position(buffer); SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LEN(extra)); qsort(buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char); } SAFE_WRITE(buffer, &zero, 1); break; } default: { buffer_free(buffer); rb_raise(rb_eTypeError, "no c encoder for this type yet (%d)", TYPE(value)); break; } } return ST_CONTINUE; }
/* * Performs the interactive session. This handles data transmission between * the client and the program. Note that the notion of stdin, stdout, and * stderr in this function is sort of reversed: this function writes to * stdin (of the child program), and reads from stdout and stderr (of the * child program). */ void server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) { fd_set *readset = NULL, *writeset = NULL; int max_fd = 0; u_int nalloc = 0; int wait_status; /* Status returned by wait(). */ pid_t wait_pid; /* pid returned by wait(). */ int waiting_termination = 0; /* Have displayed waiting close message. */ u_int64_t max_time_milliseconds; u_int previous_stdout_buffer_bytes; u_int stdout_buffer_bytes; int type; debug("Entering interactive session."); /* Initialize the SIGCHLD kludge. */ child_terminated = 0; signal(SIGCHLD, sigchld_handler); if (!use_privsep) { signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGQUIT, sigterm_handler); } /* Initialize our global variables. */ fdin = fdin_arg; fdout = fdout_arg; fderr = fderr_arg; /* nonblocking IO */ set_nonblock(fdin); set_nonblock(fdout); /* we don't have stderr for interactive terminal sessions, see below */ if (fderr != -1) set_nonblock(fderr); if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) fdin_is_tty = 1; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); notify_setup(); previous_stdout_buffer_bytes = 0; /* Set approximate I/O buffer size. */ if (packet_is_interactive()) buffer_high = 4096; else buffer_high = 64 * 1024; #if 0 /* Initialize max_fd to the maximum of the known file descriptors. */ max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); if (fderr != -1) max_fd = MAX(max_fd, fderr); #endif /* Initialize Initialize buffers. */ buffer_init(&stdin_buffer); buffer_init(&stdout_buffer); buffer_init(&stderr_buffer); /* * If we have no separate fderr (which is the case when we have a pty * - there we cannot make difference between data sent to stdout and * stderr), indicate that we have seen an EOF from stderr. This way * we don't need to check the descriptor everywhere. */ if (fderr == -1) fderr_eof = 1; server_init_dispatch(); /* Main loop of the server for the interactive session mode. */ for (;;) { /* Process buffered packets from the client. */ process_buffered_input_packets(); /* * If we have received eof, and there is no more pending * input data, cause a real eof by closing fdin. */ if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { if (fdin != fdout) close(fdin); else shutdown(fdin, SHUT_WR); /* We will no longer send. */ fdin = -1; } /* Make packets from buffered stderr data to send to the client. */ make_packets_from_stderr_data(); /* * Make packets from buffered stdout data to send to the * client. If there is very little to send, this arranges to * not send them now, but to wait a short while to see if we * are getting more data. This is necessary, as some systems * wake up readers from a pty after each separate character. */ max_time_milliseconds = 0; stdout_buffer_bytes = buffer_len(&stdout_buffer); if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && stdout_buffer_bytes != previous_stdout_buffer_bytes) { /* try again after a while */ max_time_milliseconds = 10; } else { /* Send it now. */ make_packets_from_stdout_data(); } previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); /* Send channel data to the client. */ if (packet_not_very_much_data_to_write()) channel_output_poll(); /* * Bail out of the loop if the program has closed its output * descriptors, and we have no more data to send to the * client, and there is no pending buffered data. */ if (fdout_eof && fderr_eof && !packet_have_data_to_write() && buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) { if (!channel_still_open()) break; if (!waiting_termination) { const char *s = "Waiting for forwarded connections to terminate...\r\n"; char *cp; waiting_termination = 1; buffer_append(&stderr_buffer, s, strlen(s)); /* Display list of open channels. */ cp = channel_open_message(); buffer_append(&stderr_buffer, cp, strlen(cp)); free(cp); } } max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); max_fd = MAX(max_fd, fderr); max_fd = MAX(max_fd, notify_pipe[0]); /* Sleep in select() until we can do something. */ wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, max_time_milliseconds); if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } /* Process any channel events. */ channel_after_select(readset, writeset); /* Process input from the client and from program stdout/stderr. */ process_input(readset); /* Process output to the client and to program stdin. */ process_output(writeset); } free(readset); free(writeset); /* Cleanup and termination code. */ /* Wait until all output has been sent to the client. */ drain_output(); debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); /* Free and clear the buffers. */ buffer_free(&stdin_buffer); buffer_free(&stdout_buffer); buffer_free(&stderr_buffer); /* Close the file descriptors. */ if (fdout != -1) close(fdout); fdout = -1; fdout_eof = 1; if (fderr != -1) close(fderr); fderr = -1; fderr_eof = 1; if (fdin != -1) close(fdin); fdin = -1; channel_free_all(); /* We no longer want our SIGCHLD handler to be called. */ signal(SIGCHLD, SIG_DFL); while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0) if (errno != EINTR) packet_disconnect("wait: %.100s", strerror(errno)); if (wait_pid != pid) error("Strange, wait returned pid %ld, expected %ld", (long)wait_pid, (long)pid); /* Check if it exited normally. */ if (WIFEXITED(wait_status)) { /* Yes, normal exit. Get exit status and send it to the client. */ debug("Command exited with status %d.", WEXITSTATUS(wait_status)); packet_start(SSH_SMSG_EXITSTATUS); packet_put_int(WEXITSTATUS(wait_status)); packet_send(); packet_write_wait(); /* * Wait for exit confirmation. Note that there might be * other packets coming before it; however, the program has * already died so we just ignore them. The client is * supposed to respond with the confirmation when it receives * the exit status. */ do { type = packet_read(); } while (type != SSH_CMSG_EXIT_CONFIRMATION); debug("Received exit confirmation."); return; } /* Check if the program terminated due to a signal. */ if (WIFSIGNALED(wait_status)) packet_disconnect("Command terminated on signal %d.", WTERMSIG(wait_status)); /* Some weird exit cause. Just exit. */ packet_disconnect("wait returned status %04x.", wait_status); /* NOTREACHED */ }
STRING *signature_to_string(SIGNATURE *sign){ STRING *str; STRING *rs; #ifdef HAVE_LIBGCRYPT const char *r,*s; gcry_sexp_t sexp; size_t size; #elif defined HAVE_LIBCRYPTO STRING *r,*s; #endif unsigned char buffer[40]; BUFFER *tmpbuf=buffer_new(); STRING *tmp; tmp=string_from_char(ssh_type_to_char(sign->type)); buffer_add_ssh_string(tmpbuf,tmp); free(tmp); switch(sign->type){ case TYPE_DSS: memset(buffer,0,40); #ifdef HAVE_LIBGCRYPT sexp=gcry_sexp_find_token(sign->dsa_sign,"r",0); r=gcry_sexp_nth_data(sexp,1,&size); if (*r == 0) /* libgcrypt put 0 when first bit is set */ { size--; r++; } memcpy(buffer,r + size - 20,20); gcry_sexp_release(sexp); sexp=gcry_sexp_find_token(sign->dsa_sign,"s",0); s=gcry_sexp_nth_data(sexp,1,&size); if (*s == 0) { size--; s++; } memcpy(buffer+ 20, s + size - 20, 20); gcry_sexp_release(sexp); #elif defined HAVE_LIBCRYPTO r=make_bignum_string(sign->dsa_sign->r); s=make_bignum_string(sign->dsa_sign->s); rs=string_new(40); memcpy(buffer,r->string+string_len(r)-20,20); memcpy(buffer+ 20, s->string + string_len(s) - 20, 20); free(r); free(s); #endif rs=string_new(40); string_fill(rs,buffer,40); buffer_add_ssh_string(tmpbuf,rs); free(rs); break; case TYPE_RSA: case TYPE_RSA1: #ifdef HAVE_LIBGCRYPT sexp=gcry_sexp_find_token(sign->rsa_sign,"s",0); s=gcry_sexp_nth_data(sexp,1,&size); if (*s == 0) { size--; s++; } rs=string_new(size); string_fill(rs,(char *)s,size); buffer_add_ssh_string(tmpbuf,rs); gcry_sexp_release(sexp); free(rs); #elif defined HAVE_LIBCRYPTO buffer_add_ssh_string(tmpbuf,sign->rsa_sign); #endif break; } str=string_new(buffer_get_len(tmpbuf)); string_fill(str,buffer_get(tmpbuf),buffer_get_len(tmpbuf)); buffer_free(tmpbuf); return str; }
/* TODO : split this function in two so it becomes smaller */ SIGNATURE *signature_from_string(STRING *signature,PUBLIC_KEY *pubkey,int needed_type){ #ifdef HAVE_LIBGCRYPT gcry_sexp_t sig; #elif defined HAVE_LIBCRYPTO DSA_SIG *sig; STRING *r,*s; #endif SIGNATURE *sign=malloc(sizeof(SIGNATURE)); BUFFER *tmpbuf=buffer_new(); STRING *rs; STRING *type_s,*e; int len,rsalen; char *type; buffer_add_data(tmpbuf,signature->string,string_len(signature)); type_s=buffer_get_ssh_string(tmpbuf); if(!type_s){ ssh_set_error(NULL,SSH_FATAL,"Invalid signature packet"); buffer_free(tmpbuf); return NULL; } type=string_to_char(type_s); free(type_s); switch(needed_type){ case TYPE_DSS: if(strcmp(type,"ssh-dss")){ ssh_set_error(NULL,SSH_FATAL,"Invalid signature type : %s",type); buffer_free(tmpbuf); free(type); return NULL; } break; case TYPE_RSA: if(strcmp(type,"ssh-rsa")){ ssh_set_error(NULL,SSH_FATAL,"Invalid signature type : %s",type); buffer_free(tmpbuf); free(type); return NULL; } break; default: ssh_set_error(NULL,SSH_FATAL,"Invalid signature type : %s",type); free(type); buffer_free(tmpbuf); return NULL; } free(type); switch(needed_type){ case TYPE_DSS: rs=buffer_get_ssh_string(tmpbuf); buffer_free(tmpbuf); if(!rs || string_len(rs)!=40){ /* 40 is the dual signature blob len. */ if(rs) free(rs); return NULL; } /* we make use of strings (because we have all-made functions to convert them to bignums (ou pas ;)*/ #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&sig,NULL,"(sig-val(dsa(r %b)(s %b)))",20,rs->string,20,rs->string+20); #elif defined HAVE_LIBCRYPTO r=string_new(20); s=string_new(20); string_fill(r,rs->string,20); string_fill(s,rs->string+20,20); sig=DSA_SIG_new(); sig->r=make_string_bn(r); /* is that really portable ? Openssh's hack isn't better */ sig->s=make_string_bn(s); free(r); free(s); #endif #ifdef DEBUG_CRYPTO ssh_print_hexa("r",rs->string,20); ssh_print_hexa("s",rs->string+20,20); #endif free(rs); sign->type=TYPE_DSS; sign->dsa_sign=sig; return sign; case TYPE_RSA: e=buffer_get_ssh_string(tmpbuf); buffer_free(tmpbuf); if(!e){ return NULL; } len=string_len(e); #ifdef HAVE_LIBGCRYPT rsalen=(gcry_pk_get_nbits(pubkey->rsa_pub)+7)/8; #elif defined HAVE_LIBCRYPTO rsalen=RSA_size(pubkey->rsa_pub); #endif if(len>rsalen){ free(e); free(sign); ssh_set_error(NULL,SSH_FATAL,"signature too big ! %d instead of %d",len,rsalen); return NULL; } if(len<rsalen) ssh_say(0,"Len %d < %d\n",len,rsalen); sign->type=TYPE_RSA; #ifdef HAVE_LIBGCRYPT gcry_sexp_build(&sig,NULL,"(sig-val(rsa(s %b)))",string_len(e),e->string); sign->rsa_sign=sig; #elif defined HAVE_LIBCRYPTO sign->rsa_sign=e; #endif #ifdef DEBUG_CRYPTO ssh_say(0,"Len : %d\n",len); ssh_print_hexa("rsa signature",e->string,len); #endif #ifdef HAVE_LIBGCRYPT free(e); #endif return sign; default: return NULL; } }
/* * IMAPFilter: an IMAP mail filtering utility. */ int main(int argc, char *argv[]) { int c; setlocale(LC_CTYPE, ""); opts.verbose = 0; opts.interactive = 0; opts.log = NULL; opts.config = NULL; opts.oneline = NULL; opts.debug = NULL; env.home = NULL; env.pathmax = -1; while ((c = getopt(argc, argv, "Vc:d:e:il:v?")) != -1) { switch (c) { case 'V': version(); /* NOTREACHED */ break; case 'c': opts.config = optarg; break; case 'd': opts.debug = optarg; break; case 'e': opts.oneline = optarg; break; case 'i': opts.interactive = 1; break; case 'l': opts.log = optarg; break; case 'v': opts.verbose = 1; break; case '?': default: usage(); /* NOTREACHED */ break; } } get_pathmax(); open_debug(); create_homedir(); catch_signals(); open_log(); if (opts.config == NULL) opts.config = get_filepath("config.lua"); buffer_init(&ibuf, INPUT_BUF); buffer_init(&obuf, OUTPUT_BUF); buffer_init(&nbuf, NAMESPACE_BUF); buffer_init(&cbuf, CONVERSION_BUF); regexp_compile(responses); SSL_library_init(); SSL_load_error_strings(); start_lua(); #if LUA_VERSION_NUM < 502 { list *l; session *s; l = sessions; while (l != NULL) { s = l->data; l = l->next; request_logout(s); } } #endif stop_lua(); ERR_free_strings(); regexp_free(responses); buffer_free(&ibuf); buffer_free(&obuf); buffer_free(&nbuf); buffer_free(&cbuf); xfree(env.home); close_log(); close_debug(); exit(0); }
static PyObject* _cbson_query_message(PyObject* self, PyObject* args) { /* NOTE just using a random number as the request_id */ struct module_state *state = GETSTATE(self); int request_id = rand(); unsigned int options; char* collection_name = NULL; int collection_name_length; int begin, cur_size, max_size = 0; int num_to_skip; int num_to_return; PyObject* query; PyObject* field_selector = Py_None; unsigned char uuid_subtype = 3; buffer_t buffer; int length_location, message_length; PyObject* result; if (!PyArg_ParseTuple(args, "Iet#iiO|Ob", &options, "utf-8", &collection_name, &collection_name_length, &num_to_skip, &num_to_return, &query, &field_selector, &uuid_subtype)) { return NULL; } buffer = buffer_new(); if (!buffer) { PyErr_NoMemory(); PyMem_Free(collection_name); return NULL; } // save space for message length length_location = buffer_save_space(buffer, 4); if (length_location == -1) { PyMem_Free(collection_name); PyErr_NoMemory(); return NULL; } if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00\xd4\x07\x00\x00", 8) || !buffer_write_bytes(buffer, (const char*)&options, 4) || !buffer_write_bytes(buffer, collection_name, collection_name_length + 1) || !buffer_write_bytes(buffer, (const char*)&num_to_skip, 4) || !buffer_write_bytes(buffer, (const char*)&num_to_return, 4)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } begin = buffer_get_position(buffer); if (!write_dict(state->_cbson, buffer, query, 0, uuid_subtype, 1)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } max_size = buffer_get_position(buffer) - begin; if (field_selector != Py_None) { begin = buffer_get_position(buffer); if (!write_dict(state->_cbson, buffer, field_selector, 0, uuid_subtype, 1)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } cur_size = buffer_get_position(buffer) - begin; max_size = (cur_size > max_size) ? cur_size : max_size; } PyMem_Free(collection_name); message_length = buffer_get_position(buffer) - length_location; memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); /* objectify buffer */ result = Py_BuildValue("i" BYTES_FORMAT_STRING "i", request_id, buffer_get_buffer(buffer), buffer_get_position(buffer), max_size); buffer_free(buffer); return result; }
static PyObject* _cbson_update_message(PyObject* self, PyObject* args) { /* NOTE just using a random number as the request_id */ struct module_state *state = GETSTATE(self); int request_id = rand(); char* collection_name = NULL; int collection_name_length; int before, cur_size, max_size = 0; PyObject* doc; PyObject* spec; unsigned char multi; unsigned char upsert; unsigned char safe; unsigned char check_keys; unsigned char uuid_subtype; PyObject* last_error_args; int options; buffer_t buffer; int length_location, message_length; PyObject* result; if (!PyArg_ParseTuple(args, "et#bbOObObb", "utf-8", &collection_name, &collection_name_length, &upsert, &multi, &spec, &doc, &safe, &last_error_args, &check_keys, &uuid_subtype)) { return NULL; } options = 0; if (upsert) { options += 1; } if (multi) { options += 2; } buffer = buffer_new(); if (!buffer) { PyErr_NoMemory(); PyMem_Free(collection_name); return NULL; } // save space for message length length_location = buffer_save_space(buffer, 4); if (length_location == -1) { PyMem_Free(collection_name); PyErr_NoMemory(); return NULL; } if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) || !buffer_write_bytes(buffer, "\x00\x00\x00\x00" "\xd1\x07\x00\x00" "\x00\x00\x00\x00", 12) || !buffer_write_bytes(buffer, collection_name, collection_name_length + 1) || !buffer_write_bytes(buffer, (const char*)&options, 4)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } before = buffer_get_position(buffer); if (!write_dict(state->_cbson, buffer, spec, 0, uuid_subtype, 1)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } max_size = buffer_get_position(buffer) - before; before = buffer_get_position(buffer); if (!write_dict(state->_cbson, buffer, doc, check_keys, uuid_subtype, 1)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } cur_size = buffer_get_position(buffer) - before; max_size = (cur_size > max_size) ? cur_size : max_size; message_length = buffer_get_position(buffer) - length_location; memcpy(buffer_get_buffer(buffer) + length_location, &message_length, 4); if (safe) { if (!add_last_error(self, buffer, request_id, collection_name, collection_name_length, last_error_args)) { buffer_free(buffer); PyMem_Free(collection_name); return NULL; } } PyMem_Free(collection_name); /* objectify buffer */ result = Py_BuildValue("i" BYTES_FORMAT_STRING "i", request_id, buffer_get_buffer(buffer), buffer_get_position(buffer), max_size); buffer_free(buffer); return result; }
void TEST_COMPLETE_MULTIPART_UPLOAD_HEADERPARA(void) { char md5_buf[32]; snprintf(object_key, 1024, "%s", __FUNCTION__); snprintf(header_str, 1024, "%s", ""); if (0 != init_complete() ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "uploadId=%s", uploadid_str); #if 0 compute_buf_md5b64((char*)"0123456789", 10, md5_buf); snprintf(header_str, 1024, "Content-MD5: %s", md5_buf); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, com_xml, strlen(com_xml), query_str, header_str, &error); CU_ASSERT(0 == error); CU_ASSERT(403 == resp->status_code); if (resp->status_code != 403) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); #endif resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); if (0 != init_complete(host, bucket, object_key, uploadid_str, com_xml, sizeof(com_xml)) ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "uploadId=%s", uploadid_str); snprintf(header_str, 1024, "Content-Type: %s", "text/plain"); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, header_str, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); if (0 != init_complete(host, bucket, object_key, uploadid_str, com_xml, sizeof(com_xml)) ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "uploadId=%s", uploadid_str); compute_buf_md5b64(com_xml, strlen(com_xml), md5_buf); snprintf(header_str, 1024, "CONTENT-Type: %s", "application/x-www-form-urlencoded"); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, header_str, &error); CU_ASSERT(0 == error); CU_ASSERT(503 == resp->status_code); if (resp->status_code != 503) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = delete_object(host, bucket, object_key, ak, sk, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(204 == resp->status_code); if (resp->status_code != 204) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); return; }
static int http_response_parse_range(server *srv, connection *con, plugin_data *p) { int multipart = 0; int error; off_t start, end; const char *s, *minus; char *boundary = "fkj49sn38dcn3"; data_string *ds; stat_cache_entry *sce = NULL; buffer *content_type = NULL; if (HANDLER_ERROR == stat_cache_get_entry(srv, con, con->physical.path, &sce)) { SEGFAULT(); } start = 0; end = sce->st.st_size - 1; con->response.content_length = 0; if (NULL != (ds = (data_string *)array_get_element(con->response.headers, "Content-Type"))) { content_type = ds->value; } for (s = con->request.http_range, error = 0; !error && *s && NULL != (minus = strchr(s, '-')); ) { char *err; off_t la, le; if (s == minus) { /* -<stop> */ le = strtoll(s, &err, 10); if (le == 0) { /* RFC 2616 - 14.35.1 */ con->http_status = 416; error = 1; } else if (*err == '\0') { /* end */ s = err; end = sce->st.st_size - 1; start = sce->st.st_size + le; } else if (*err == ',') { multipart = 1; s = err + 1; end = sce->st.st_size - 1; start = sce->st.st_size + le; } else { error = 1; } } else if (*(minus+1) == '\0' || *(minus+1) == ',') { /* <start>- */ la = strtoll(s, &err, 10); if (err == minus) { /* ok */ if (*(err + 1) == '\0') { s = err + 1; end = sce->st.st_size - 1; start = la; } else if (*(err + 1) == ',') { multipart = 1; s = err + 2; end = sce->st.st_size - 1; start = la; } else { error = 1; } } else { /* error */ error = 1; } } else { /* <start>-<stop> */ la = strtoll(s, &err, 10); if (err == minus) { le = strtoll(minus+1, &err, 10); /* RFC 2616 - 14.35.1 */ if (la > le) { error = 1; } if (*err == '\0') { /* ok, end*/ s = err; end = le; start = la; } else if (*err == ',') { multipart = 1; s = err + 1; end = le; start = la; } else { /* error */ error = 1; } } else { /* error */ error = 1; } } if (!error) { if (start < 0) start = 0; /* RFC 2616 - 14.35.1 */ if (end > sce->st.st_size - 1) end = sce->st.st_size - 1; if (start > sce->st.st_size - 1) { error = 1; con->http_status = 416; } } if (!error) { if (multipart) { /* write boundary-header */ buffer *b = buffer_init(); buffer_copy_string_len(b, CONST_STR_LEN("\r\n--")); buffer_append_string(b, boundary); /* write Content-Range */ buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Range: bytes ")); buffer_append_int(b, start); buffer_append_string_len(b, CONST_STR_LEN("-")); buffer_append_int(b, end); buffer_append_string_len(b, CONST_STR_LEN("/")); buffer_append_int(b, sce->st.st_size); buffer_append_string_len(b, CONST_STR_LEN("\r\nContent-Type: ")); buffer_append_string_buffer(b, content_type); /* write END-OF-HEADER */ buffer_append_string_len(b, CONST_STR_LEN("\r\n\r\n")); con->response.content_length += buffer_string_length(b); chunkqueue_append_buffer(con->write_queue, b); buffer_free(b); } chunkqueue_append_file(con->write_queue, con->physical.path, start, end - start + 1); con->response.content_length += end - start + 1; } } /* something went wrong */ if (error) return -1; if (multipart) { /* add boundary end */ buffer *b = buffer_init(); buffer_copy_string_len(b, "\r\n--", 4); buffer_append_string(b, boundary); buffer_append_string_len(b, "--\r\n", 4); con->response.content_length += buffer_string_length(b); chunkqueue_append_buffer(con->write_queue, b); buffer_free(b); /* set header-fields */ buffer_copy_string_len(p->range_buf, CONST_STR_LEN("multipart/byteranges; boundary=")); buffer_append_string(p->range_buf, boundary); /* overwrite content-type */ response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(p->range_buf)); } else { /* add Content-Range-header */ buffer_copy_string_len(p->range_buf, CONST_STR_LEN("bytes ")); buffer_append_int(p->range_buf, start); buffer_append_string_len(p->range_buf, CONST_STR_LEN("-")); buffer_append_int(p->range_buf, end); buffer_append_string_len(p->range_buf, CONST_STR_LEN("/")); buffer_append_int(p->range_buf, sce->st.st_size); response_header_insert(srv, con, CONST_STR_LEN("Content-Range"), CONST_BUF_LEN(p->range_buf)); } /* ok, the file is set-up */ return 0; }
int ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, const u_char *data, u_int datalen) { DSA_SIG *sig; const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; u_char digest[EVP_MAX_MD_SIZE], *sigblob; u_int len, dlen; int rlen, ret; Buffer b; if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { error("ssh_dss_verify: no DSA key"); return -1; } /* fetch signature */ if (datafellows & SSH_BUG_SIGBLOB) { sigblob = xmalloc(signaturelen); memcpy(sigblob, signature, signaturelen); len = signaturelen; } else { /* ietf-drafts */ char *ktype; buffer_init(&b); buffer_append(&b, signature, signaturelen); ktype = buffer_get_string(&b, NULL); if (strcmp("ssh-dss", ktype) != 0) { error("ssh_dss_verify: cannot handle type %s", ktype); buffer_free(&b); xfree(ktype); return -1; } xfree(ktype); sigblob = buffer_get_string(&b, &len); rlen = buffer_len(&b); buffer_free(&b); if (rlen != 0) { error("ssh_dss_verify: " "remaining bytes in signature %d", rlen); xfree(sigblob); return -1; } } if (len != SIGBLOB_LEN) { fatal("bad sigbloblen %u != SIGBLOB_LEN", len); } /* parse signature */ if ((sig = DSA_SIG_new()) == NULL) fatal("ssh_dss_verify: DSA_SIG_new failed"); if ((sig->r = BN_new()) == NULL) fatal("ssh_dss_verify: BN_new failed"); if ((sig->s = BN_new()) == NULL) fatal("ssh_dss_verify: BN_new failed"); if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) fatal("ssh_dss_verify: BN_bin2bn failed"); /* clean up */ memset(sigblob, 0, len); xfree(sigblob); /* sha1 the data */ EVP_DigestInit(&md, evp_md); EVP_DigestUpdate(&md, data, datalen); EVP_DigestFinal(&md, digest, &dlen); ret = DSA_do_verify(digest, dlen, sig, key->dsa); memset(digest, 'd', sizeof(digest)); DSA_SIG_free(sig); debug("ssh_dss_verify: signature %s", ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); return ret; }
static int dh_handshake_server(SSH_SESSION *session){ STRING *e,*f,*pubkey,*sign; PUBLIC_KEY *pub; PRIVATE_KEY *prv; BUFFER *buf=buffer_new(); if(packet_wait(session, SSH2_MSG_KEXDH_INIT)) // FIXME BLOCKING return -1; e=buffer_get_ssh_string(session->in_buffer); if(!e){ ssh_set_error(session,SSH_FATAL,"No e number in client request"); return -1; } dh_import_e(session,e); dh_generate_y(session); dh_generate_f(session); f=dh_get_f(session); switch(session->hostkeys){ case TYPE_DSS: prv=session->dsa_key; break; case TYPE_RSA: prv=session->rsa_key; break; default: prv=NULL; } pub=publickey_from_privatekey(prv); pubkey=publickey_to_string(pub); publickey_free(pub); dh_import_pubkey(session,pubkey); dh_build_k(session); make_sessionid(session); sign=ssh_sign_session_id(session,prv); buffer_free(buf); /* free private keys as they should not be readable past this point */ if(session->rsa_key){ private_key_free(session->rsa_key); session->rsa_key=NULL; } if(session->dsa_key){ private_key_free(session->dsa_key); session->dsa_key=NULL; } buffer_add_u8(session->out_buffer,SSH2_MSG_KEXDH_REPLY); buffer_add_ssh_string(session->out_buffer,pubkey); buffer_add_ssh_string(session->out_buffer,f); buffer_add_ssh_string(session->out_buffer,sign); free(sign); packet_send(session); free(f); packet_clear_out(session); buffer_add_u8(session->out_buffer,SSH2_MSG_NEWKEYS); packet_send(session); ssh_say(2,"SSH_MSG_NEWKEYS sent\n"); packet_wait(session,SSH2_MSG_NEWKEYS);// FIXME BLOCKING ssh_say(2,"Got SSH_MSG_NEWKEYS\n"); generate_session_keys(session); /* once we got SSH2_MSG_NEWKEYS we can switch next_crypto and current_crypto */ if(session->current_crypto) crypto_free(session->current_crypto); /* XXX later, include a function to change keys */ session->current_crypto=session->next_crypto; session->next_crypto=crypto_new(); return 0; }
static int userauth_pubkey(Authctxt *authctxt) { Buffer b; Key *key = NULL; char *pkalg, *userstyle; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt->valid) { debug2("userauth_pubkey: disabled because of invalid user"); return 0; } have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { debug2("userauth_pubkey: SSH_BUG_PKAUTH"); /* no explicit pkalg given */ pkblob = packet_get_string(&blen); buffer_init(&b); buffer_append(&b, pkblob, blen); /* so we have to extract the pkalg from the pkblob */ pkalg = buffer_get_string(&b, &alen); buffer_free(&b); } else { pkalg = packet_get_string(&alen); pkblob = packet_get_string(&blen); } pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ logit("userauth_pubkey: unsupported public key algorithm: %s", pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { error("userauth_pubkey: cannot decode key: %s", pkalg); goto done; } if (key->type != pktype) { error("userauth_pubkey: type mismatch for decoded key " "(received %d, expected %d)", key->type, pktype); goto done; } if (key_type_plain(key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { logit("Refusing RSA key because client uses unsafe " "signature scheme"); goto done; } if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); buffer_init(&b); if (datafellows & SSH_OLD_SESSIONID) { buffer_append(&b, session_id2, session_id2_len); } else { buffer_put_string(&b, session_id2, session_id2_len); } /* reconstruct packet */ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); buffer_put_cstring(&b, userstyle); free(userstyle); buffer_put_cstring(&b, datafellows & SSH_BUG_PKSERVICE ? "ssh-userauth" : authctxt->service); if (datafellows & SSH_BUG_PKAUTH) { buffer_put_char(&b, have_sig); } else { buffer_put_cstring(&b, "publickey"); buffer_put_char(&b, have_sig); buffer_put_cstring(&b, pkalg); } buffer_put_string(&b, pkblob, blen); #ifdef DEBUG_PK buffer_dump(&b); #endif pubkey_auth_info(authctxt, key, NULL); /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1) authenticated = 1; buffer_free(&b); free(sig); } else { debug("test whether pkalg/pkblob are acceptable"); packet_check_eom(); /* XXX fake reply and always send PK_OK ? */ /* * XXX this allows testing whether a user is allowed * to login: if you happen to have a valid pubkey this * message is sent. the message is NEVER sent at all * if a user is not allowed to login. is this an * issue? -markus */ if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { packet_start(SSH2_MSG_USERAUTH_PK_OK); packet_put_string(pkalg, alen); packet_put_string(pkblob, blen); packet_send(); packet_write_wait(); authctxt->postponed = 1; } } if (authenticated != 1) auth_clear_options(); done: debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); if (key != NULL) key_free(key); free(pkalg); free(pkblob); return authenticated; }
void TEST_COMPLETE_MULTIPART_UPLOAD_OBJECT(void) { snprintf(object_key, 1024, "%s", __FUNCTION__); if (0 != init_complete() ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "" ); // <Code>NotFoundApi</Code> resp = complete_multipart_upload(host, bucket, NULL, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(404 == resp->status_code); if (resp->status_code != 404) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); // <Code>NotFoundApi</Code> resp = complete_multipart_upload(host, bucket, "", ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(404 == resp->status_code); if (resp->status_code != 404) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); // <Code>NoSuchUpload</Code> resp = complete_multipart_upload(host, bucket, "1a2b3c", ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(404 == resp->status_code); if (resp->status_code != 404) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = delete_object(host, bucket, object_key, ak, sk, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(204 == resp->status_code); if (resp->status_code != 204) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); return; }
int http_request_parse(server *srv, connection *con) { char *uri = NULL, *proto = NULL, *method = NULL, con_length_set; int is_key = 1, key_len = 0, is_ws_after_key = 0, in_folding; char *value = NULL, *key = NULL; char *reqline_host = NULL; int reqline_hostlen = 0; enum { HTTP_CONNECTION_UNSET, HTTP_CONNECTION_KEEPALIVE, HTTP_CONNECTION_CLOSE } keep_alive_set = HTTP_CONNECTION_UNSET; int line = 0; int request_line_stage = 0; size_t i, first, ilen; int done = 0; const unsigned int http_header_strict = (con->conf.http_parseopts & HTTP_PARSEOPT_HEADER_STRICT); /* * Request: "^(GET|POST|HEAD) ([^ ]+(\\?[^ ]+|)) (HTTP/1\\.[01])$" * Option : "^([-a-zA-Z]+): (.+)$" * End : "^$" */ if (con->conf.log_request_header) { log_error_write(srv, __FILE__, __LINE__, "sdsdSb", "fd:", con->fd, "request-len:", buffer_string_length(con->request.request), "\n", con->request.request); } if (con->request_count > 1 && con->request.request->ptr[0] == '\r' && con->request.request->ptr[1] == '\n') { /* we are in keep-alive and might get \r\n after a previous POST request.*/ buffer_copy_string_len(con->parse_request, con->request.request->ptr + 2, buffer_string_length(con->request.request) - 2); } else { /* fill the local request buffer */ buffer_copy_buffer(con->parse_request, con->request.request); } keep_alive_set = 0; con_length_set = 0; /* parse the first line of the request * * should be: * * <method> <uri> <protocol>\r\n * */ ilen = buffer_string_length(con->parse_request); for (i = 0, first = 0; i < ilen && line == 0; i++) { switch(con->parse_request->ptr[i]) { case '\r': if (con->parse_request->ptr[i+1] == '\n') { http_method_t r; char *nuri = NULL; size_t j, jlen; /* \r\n -> \0\0 */ con->parse_request->ptr[i] = '\0'; con->parse_request->ptr[i+1] = '\0'; buffer_copy_string_len(con->request.request_line, con->parse_request->ptr, i); if (request_line_stage != 2) { con->http_status = 400; con->response.keep_alive = 0; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "incomplete request line -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } proto = con->parse_request->ptr + first; *(uri - 1) = '\0'; *(proto - 1) = '\0'; /* we got the first one :) */ if (HTTP_METHOD_UNSET == (r = get_http_method_key(method))) { con->http_status = 501; con->response.keep_alive = 0; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "unknown http-method -> 501"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } con->request.http_method = r; /* * RFC2616 says: * * HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT * * */ if (0 == strncmp(proto, "HTTP/", sizeof("HTTP/") - 1)) { char * major = proto + sizeof("HTTP/") - 1; char * minor = strchr(major, '.'); char *err = NULL; int major_num = 0, minor_num = 0; int invalid_version = 0; if (NULL == minor || /* no dot */ minor == major || /* no major */ *(minor + 1) == '\0' /* no minor */) { invalid_version = 1; } else { *minor = '\0'; major_num = strtol(major, &err, 10); if (*err != '\0') invalid_version = 1; *minor++ = '.'; minor_num = strtol(minor, &err, 10); if (*err != '\0') invalid_version = 1; } if (invalid_version) { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "unknown protocol -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } if (major_num == 1 && minor_num == 1) { con->request.http_version = con->conf.allow_http11 ? HTTP_VERSION_1_1 : HTTP_VERSION_1_0; } else if (major_num == 1 && minor_num == 0) { con->request.http_version = HTTP_VERSION_1_0; } else { con->http_status = 505; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "unknown HTTP version -> 505"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } } else { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "unknown protocol -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } if (0 == strncmp(uri, "http://", 7) && NULL != (nuri = strchr(uri + 7, '/'))) { reqline_host = uri + 7; reqline_hostlen = nuri - reqline_host; buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1); } else if (0 == strncmp(uri, "https://", 8) && NULL != (nuri = strchr(uri + 8, '/'))) { reqline_host = uri + 8; reqline_hostlen = nuri - reqline_host; buffer_copy_string_len(con->request.uri, nuri, proto - nuri - 1); } else { /* everything looks good so far */ buffer_copy_string_len(con->request.uri, uri, proto - uri - 1); } /* check uri for invalid characters */ jlen = buffer_string_length(con->request.uri); if (http_header_strict) { for (j = 0; j < jlen && request_uri_is_valid_char(con->request.uri->ptr[j]); j++) ; } else { char *z = memchr(con->request.uri->ptr, '\0', jlen); j = (NULL == z) ? jlen : (size_t)(z - con->request.uri->ptr); } if (j < jlen) { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { unsigned char buf[2]; buf[0] = con->request.uri->ptr[j]; buf[1] = '\0'; if (con->request.uri->ptr[j] > 32 && con->request.uri->ptr[j] != 127) { /* the character is printable -> print it */ log_error_write(srv, __FILE__, __LINE__, "ss", "invalid character in URI -> 400", buf); } else { /* a control-character, print ascii-code */ log_error_write(srv, __FILE__, __LINE__, "sd", "invalid character in URI -> 400", con->request.uri->ptr[j]); } log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } buffer_copy_buffer(con->request.orig_uri, con->request.uri); con->http_status = 0; i++; line++; first = i+1; } break; case ' ': switch(request_line_stage) { case 0: /* GET|POST|... */ method = con->parse_request->ptr + first; first = i + 1; break; case 1: /* /foobar/... */ uri = con->parse_request->ptr + first; first = i + 1; break; default: /* ERROR, one space to much */ con->http_status = 400; con->response.keep_alive = 0; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "overlong request line -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } request_line_stage++; break; } } in_folding = 0; if (buffer_string_is_empty(con->request.uri)) { con->http_status = 400; con->response.keep_alive = 0; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "no uri specified -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } if (reqline_host) { /* Insert as host header */ data_string *ds; if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { ds = data_string_init(); } buffer_copy_string_len(ds->key, CONST_STR_LEN("Host")); buffer_copy_string_len(ds->value, reqline_host, reqline_hostlen); array_insert_unique(con->request.headers, (data_unset *)ds); con->request.http_host = ds->value; } for (; i <= ilen && !done; i++) { char *cur = con->parse_request->ptr + i; if (is_key) { size_t j; int got_colon = 0; /** * 1*<any CHAR except CTLs or separators> * CTLs == 0-31 + 127, CHAR = 7-bit ascii (0..127) * */ switch(*cur) { case ':': is_key = 0; value = cur + 1; if (is_ws_after_key == 0) { key_len = i - first; } is_ws_after_key = 0; break; case '(': case ')': case '<': case '>': case '@': case ',': case ';': case '\\': case '\"': case '/': case '[': case ']': case '?': case '=': case '{': case '}': con->http_status = 400; con->keep_alive = 0; con->response.keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "sbsds", "invalid character in key", con->request.request, cur, *cur, "-> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; case ' ': case '\t': if (i == first) { is_key = 0; in_folding = 1; value = cur; break; } key_len = i - first; /* skip every thing up to the : */ for (j = 1; !got_colon; j++) { switch(con->parse_request->ptr[j + i]) { case ' ': case '\t': /* skip WS */ continue; case ':': /* ok, done; handle the colon the usual way */ i += j - 1; got_colon = 1; is_ws_after_key = 1; /* we already know the key length */ break; default: /* error */ if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "WS character in key -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } con->http_status = 400; con->response.keep_alive = 0; con->keep_alive = 0; return 0; } } break; case '\r': if (con->parse_request->ptr[i+1] == '\n' && i == first) { /* End of Header */ con->parse_request->ptr[i] = '\0'; con->parse_request->ptr[i+1] = '\0'; i++; done = 1; } else { if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "CR without LF -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } con->http_status = 400; con->keep_alive = 0; con->response.keep_alive = 0; return 0; } break; default: if (http_header_strict ? (*cur < 32 || ((unsigned char)*cur) >= 127) : *cur == '\0') { con->http_status = 400; con->keep_alive = 0; con->response.keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "sbsds", "invalid character in key", con->request.request, cur, *cur, "-> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } /* ok */ break; } } else { switch(*cur) { case '\r': if (con->parse_request->ptr[i+1] == '\n') { data_string *ds = NULL; /* End of Headerline */ con->parse_request->ptr[i] = '\0'; con->parse_request->ptr[i+1] = '\0'; if (in_folding) { buffer *key_b; /** * we use a evil hack to handle the line-folding * * As array_insert_unique() deletes 'ds' in the case of a duplicate * ds points somewhere and we get a evil crash. As a solution we keep the old * "key" and get the current value from the hash and append us * * */ if (!key || !key_len) { /* 400 */ if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "WS at the start of first line -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } con->http_status = 400; con->keep_alive = 0; con->response.keep_alive = 0; return 0; } key_b = buffer_init(); buffer_copy_string_len(key_b, key, key_len); if (NULL != (ds = (data_string *)array_get_element(con->request.headers, key_b->ptr))) { buffer_append_string(ds->value, value); } buffer_free(key_b); } else { int s_len; key = con->parse_request->ptr + first; s_len = cur - value; /* strip trailing white-spaces */ for (; s_len > 0 && (value[s_len - 1] == ' ' || value[s_len - 1] == '\t'); s_len--); value[s_len] = '\0'; if (s_len > 0) { int cmp = 0; if (NULL == (ds = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { ds = data_string_init(); } buffer_copy_string_len(ds->key, key, key_len); buffer_copy_string_len(ds->value, value, s_len); /* retreive values * * * the list of options is sorted to simplify the search */ if (0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Connection")))) { array *vals; size_t vi; /* split on , */ vals = srv->split_vals; array_reset(vals); http_request_split_value(vals, ds->value); for (vi = 0; vi < vals->used; vi++) { data_string *dsv = (data_string *)vals->data[vi]; if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("keep-alive"))) { keep_alive_set = HTTP_CONNECTION_KEEPALIVE; break; } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(dsv->value), CONST_STR_LEN("close"))) { keep_alive_set = HTTP_CONNECTION_CLOSE; break; } } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Length")))) { char *err; unsigned long int r; size_t j, jlen; if (con_length_set) { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "duplicate Content-Length-header -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } jlen = buffer_string_length(ds->value); for (j = 0; j < jlen; j++) { char c = ds->value->ptr[j]; if (!isdigit((unsigned char)c)) { log_error_write(srv, __FILE__, __LINE__, "sbs", "content-length broken:", ds->value, "-> 400"); con->http_status = 400; con->keep_alive = 0; array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } r = strtoul(ds->value->ptr, &err, 10); if (*err == '\0') { con_length_set = 1; con->request.content_length = r; } else { log_error_write(srv, __FILE__, __LINE__, "sbs", "content-length broken:", ds->value, "-> 400"); con->http_status = 400; con->keep_alive = 0; array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Content-Type")))) { /* if dup, only the first one will survive */ if (!con->request.http_content_type) { con->request.http_content_type = ds->value->ptr; } else { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "duplicate Content-Type-header -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Expect")))) { /* HTTP 2616 8.2.3 * Expect: 100-continue * * -> (10.1.1) 100 (read content, process request, send final status-code) * -> (10.4.18) 417 (close) * * (not handled at all yet, we always send 417 here) * * What has to be added ? * 1. handling of chunked request body * 2. out-of-order sending from the HTTP/1.1 100 Continue * header * */ if (srv->srvconf.reject_expect_100_with_417 && 0 == buffer_caseless_compare(CONST_BUF_LEN(ds->value), CONST_STR_LEN("100-continue"))) { con->http_status = 417; con->keep_alive = 0; array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Host")))) { if (reqline_host) { /* ignore all host: headers as we got the host in the request line */ ds->free((data_unset*) ds); ds = NULL; } else if (!con->request.http_host) { con->request.http_host = ds->value; } else { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "duplicate Host-header -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-Modified-Since")))) { /* Proxies sometimes send dup headers * if they are the same we ignore the second * if not, we raise an error */ if (!con->request.http_if_modified_since) { con->request.http_if_modified_since = ds->value->ptr; } else if (0 == strcasecmp(con->request.http_if_modified_since, ds->value->ptr)) { /* ignore it if they are the same */ ds->free((data_unset *)ds); ds = NULL; } else { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "duplicate If-Modified-Since header -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("If-None-Match")))) { /* if dup, only the first one will survive */ if (!con->request.http_if_none_match) { con->request.http_if_none_match = ds->value->ptr; } else { ds->free((data_unset*) ds); ds = NULL; } } else if (cmp > 0 && 0 == (cmp = buffer_caseless_compare(CONST_BUF_LEN(ds->key), CONST_STR_LEN("Range")))) { if (!con->request.http_range) { /* bytes=.*-.* */ if (0 == strncasecmp(ds->value->ptr, "bytes=", 6) && NULL != strchr(ds->value->ptr+6, '-')) { /* if dup, only the first one will survive */ con->request.http_range = ds->value->ptr + 6; } } else { con->http_status = 400; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "duplicate Range-header -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } array_insert_unique(con->request.headers, (data_unset *)ds); return 0; } } if (ds) array_insert_unique(con->request.headers, (data_unset *)ds); } else { /* empty header-fields are not allowed by HTTP-RFC, we just ignore them */ } } i++; first = i+1; is_key = 1; value = NULL; #if 0 /** * for Bug 1230 keep the key_len a live */ key_len = 0; #endif in_folding = 0; } else { if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "sbs", "CR without LF", con->request.request, "-> 400"); } con->http_status = 400; con->keep_alive = 0; con->response.keep_alive = 0; return 0; } break; case ' ': case '\t': /* strip leading WS */ if (value == cur) value = cur+1; break; default: if (http_header_strict ? (*cur >= 0 && *cur < 32) : *cur == '\0') { if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "sds", "invalid char in header", (int)*cur, "-> 400"); } con->http_status = 400; con->keep_alive = 0; return 0; } break; } } } con->header_len = i; /* do some post-processing */ if (con->request.http_version == HTTP_VERSION_1_1) { if (keep_alive_set != HTTP_CONNECTION_CLOSE) { /* no Connection-Header sent */ /* HTTP/1.1 -> keep-alive default TRUE */ con->keep_alive = 1; } else { con->keep_alive = 0; } /* RFC 2616, 14.23 */ if (con->request.http_host == NULL || buffer_string_is_empty(con->request.http_host)) { con->http_status = 400; con->response.keep_alive = 0; con->keep_alive = 0; if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "HTTP/1.1 but Host missing -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } return 0; } } else { if (keep_alive_set == HTTP_CONNECTION_KEEPALIVE) { /* no Connection-Header sent */ /* HTTP/1.0 -> keep-alive default FALSE */ con->keep_alive = 1; } else { con->keep_alive = 0; } } /* check hostname field if it is set */ if (!buffer_is_empty(con->request.http_host) && (((con->conf.http_parseopts & HTTP_PARSEOPT_HOST_STRICT) && 0 != request_check_hostname(con->request.http_host)) || ((con->conf.http_parseopts & HTTP_PARSEOPT_HOST_NORMALIZE) && 0 != http_request_host_normalize(con->request.http_host)))) { if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", "Invalid Hostname -> 400"); log_error_write(srv, __FILE__, __LINE__, "Sb", "request-header:\n", con->request.request); } con->http_status = 400; con->response.keep_alive = 0; con->keep_alive = 0; return 0; } switch(con->request.http_method) { case HTTP_METHOD_GET: case HTTP_METHOD_HEAD: /* content-length is forbidden for those */ if (con_length_set && con->request.content_length != 0) { /* content-length is missing */ log_error_write(srv, __FILE__, __LINE__, "s", "GET/HEAD with content-length -> 400"); con->keep_alive = 0; con->http_status = 400; return 0; } break; case HTTP_METHOD_POST: /* content-length is required for them */ if (!con_length_set) { /* content-length is missing */ log_error_write(srv, __FILE__, __LINE__, "s", "POST-request, but content-length missing -> 411"); con->keep_alive = 0; con->http_status = 411; return 0; } break; default: /* require Content-Length if request contains request body */ if (array_get_element(con->request.headers, "Transfer-Encoding")) { /* presence of Transfer-Encoding in request headers requires "chunked" * be final encoding in HTTP/1.1. Return 411 Length Required as * lighttpd does not support request input transfer-encodings */ con->keep_alive = 0; con->http_status = 411; /* 411 Length Required */ return 0; } break; } /* check if we have read post data */ if (con_length_set) { /* don't handle more the SSIZE_MAX bytes in content-length */ if (con->request.content_length > SSIZE_MAX) { con->http_status = 413; con->keep_alive = 0; log_error_write(srv, __FILE__, __LINE__, "sos", "request-size too long:", (off_t) con->request.content_length, "-> 413"); return 0; } /* we have content */ if (con->request.content_length != 0) { return 1; } } return 0; }
void TEST_COMPLETE_MULTIPART_UPLOAD_KEY(void) { snprintf(object_key, 1024, "%s", __FUNCTION__); if (0 != init_complete() ){ CU_ASSERT(0); return ; } query_str[0] = 0; resp = complete_multipart_upload(host, bucket, object_key, NULL, NULL, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(-1 == error); CU_ASSERT(NULL == resp); resp = complete_multipart_upload(host, bucket, object_key, "", NULL, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(-1 == error); CU_ASSERT(NULL == resp); resp = complete_multipart_upload(host, bucket, object_key, NULL, "", uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(-1 == error); CU_ASSERT(NULL == resp); resp = complete_multipart_upload(host, bucket, object_key, "", "", uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(403 == resp->status_code); if (resp->status_code != 403) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = complete_multipart_upload(host, bucket, object_key, "sdfasdfasd", "7s9d7fasdf9asd89fasdfhsd", uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(403 == resp->status_code); if (resp->status_code != 403) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = delete_object(host, bucket, object_key, ak, sk, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(204 == resp->status_code); if (resp->status_code != 204) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); return; }
static void context_free(config_t *context) { buffer_ptr_free(context->configs_stack); buffer_free(context->basedir); }
void TEST_COMPLETE_MULTIPART_UPLOAD_BUFDATAPARA(void) { snprintf(object_key, 1024, "%s", __FUNCTION__); if (0 != init_complete() ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "uploadId=%s", uploadid_str); char etag[32]; char *etag_ptr = strstr(com_xml, "<ETag>\""); CU_ASSERT(NULL != etag_ptr); memcpy(etag, etag_ptr + strlen("<ETag>\""), 32); snprintf(com_xml, sizeof(com_xml), "<CompleteMultipartUpload>\n<Part>\n<PartNumber>%d</PartNumber>\n<ETag>\"%.*s\"</ETag>" "</Part>\n</CompleteMultipartUpload>", 2, 32, etag); // <Code>InvalidPart</Code> resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(400 == resp->status_code); if (resp->status_code != 400) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); #if 0 snprintf(com_xml, sizeof(com_xml), "<CompleteMultipartUpload>\n<Part>\n<PartNumber>%d</PartNumber>\n<ETag>\"abcdefgabcdefgabcdefgabcdefg1234\"</ETag>" "</Part>\n</CompleteMultipartUpload>", 1); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); snprintf(com_xml, sizeof(com_xml), "<CompleteMultipartUpload>\n<Part>\n<PartNumber>%d</PartNumber>\n<ETag>%.*s</ETag>" "</Part>\n</CompleteMultipartUpload>", 1, 32, etag); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); #endif snprintf(com_xml, sizeof(com_xml), "<CompleteMultipartUpload>\n<Part>\n<PartNumber>%d</PartNumber>\n<ETag>\"%.*s\"</ETag>" "</Part>\n</CompleteMultipartUpload>", 1, 32, etag); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = delete_object(host, bucket, object_key, ak, sk, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(204 == resp->status_code); if (resp->status_code != 204) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); return; }
static int tokenizer_close(server *srv, tokenizer_t *t) { UNUSED(srv); buffer_free(t->file); return stream_close(&(t->s)); }
static int init_complete() { int result = 0; buffer* sub_resp = NULL; sub_resp = init_multipart_upload(host, bucket, object_key, ak, sk, NULL, NULL, &result); CU_ASSERT(0 == result); CU_ASSERT(200 == sub_resp->status_code); if (200 != sub_resp->status_code) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", sub_resp->status_code); printf("status msg = %s\n", sub_resp->status_msg); printf("error msg = %s\n", sub_resp->body); buffer_free(sub_resp); return 1; } else { char *oid_beg_ptr = strstr(sub_resp->body, "<UploadId>"); if (oid_beg_ptr) { oid_beg_ptr += strlen("<UploadId>"); char *oid_end_ptr = strstr(oid_beg_ptr, "</UploadId>"); if (oid_end_ptr) { strncpy(uploadid_str, oid_beg_ptr, oid_end_ptr - oid_beg_ptr); uploadid_str[oid_end_ptr - oid_beg_ptr] = 0; } } } buffer_free(sub_resp); sub_resp = upload_part(host, bucket, object_key, ak, sk, uploadid_str, 1, "abcdefghijklmn", 14, NULL, NULL, &result); CU_ASSERT(0 == result); CU_ASSERT(200 == sub_resp->status_code); if (sub_resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", sub_resp->status_code); printf("status msg = %s\n", sub_resp->status_msg); printf("error msg = %s\n", sub_resp->body); buffer_free(sub_resp); return 2; } char *etag_ptr = strstr(sub_resp->header, "ETag: \""); if (etag_ptr) { etag_ptr += strlen("ETag: \""); }else { buffer_free(sub_resp); return -2; } snprintf(com_xml, sizeof(com_xml), "<CompleteMultipartUpload>\n" "<Part>\n" "<PartNumber>%d</PartNumber>\n" "<ETag>\"%.*s\"</ETag>" "</Part>\n</CompleteMultipartUpload>", 1, 32, etag_ptr); buffer_free(sub_resp); return 0; }
int network_server_init(server *srv, buffer *host_token, specific_config *s) { int val; socklen_t addr_len; server_socket *srv_socket; char *sp; unsigned int port = 0; const char *host; buffer *b; int is_unix_domain_socket = 0; int fd; #ifdef SO_ACCEPTFILTER struct accept_filter_arg afa; #endif #ifdef __WIN32 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return -1; } #endif srv_socket = calloc(1, sizeof(*srv_socket)); srv_socket->fd = -1; srv_socket->srv_token = buffer_init(); buffer_copy_string_buffer(srv_socket->srv_token, host_token); b = buffer_init(); buffer_copy_string_buffer(b, host_token); /* ipv4:port * [ipv6]:port */ if (NULL == (sp = strrchr(b->ptr, ':'))) { log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b); return -1; } host = b->ptr; /* check for [ and ] */ if (b->ptr[0] == '[' && *(sp-1) == ']') { *(sp-1) = '\0'; host++; s->use_ipv6 = 1; } *(sp++) = '\0'; port = strtol(sp, NULL, 10); if (host[0] == '/') { /* host is a unix-domain-socket */ is_unix_domain_socket = 1; } else if (port == 0 || port > 65535) { log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port); return -1; } if (*host == '\0') host = NULL; if (is_unix_domain_socket) { #ifdef HAVE_SYS_UN_H srv_socket->addr.plain.sa_family = AF_UNIX; if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); return -1; } #else log_error_write(srv, __FILE__, __LINE__, "s", "ERROR: Unix Domain sockets are not supported."); return -1; #endif } #ifdef HAVE_IPV6 if (s->use_ipv6) { srv_socket->addr.plain.sa_family = AF_INET6; if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); return -1; } srv_socket->use_ipv6 = 1; } #endif if (srv_socket->fd == -1) { srv_socket->addr.plain.sa_family = AF_INET; if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); return -1; } } /* */ srv->cur_fds = srv_socket->fd; val = 1; if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno)); return -1; } switch(srv_socket->addr.plain.sa_family) { #ifdef HAVE_IPV6 case AF_INET6: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in6)); srv_socket->addr.ipv6.sin6_family = AF_INET6; if (host == NULL) { srv_socket->addr.ipv6.sin6_addr = in6addr_any; } else { struct addrinfo hints, *res; int r; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) { log_error_write(srv, __FILE__, __LINE__, "sssss", "getaddrinfo failed: ", gai_strerror(r), "'", host, "'"); return -1; } memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen); freeaddrinfo(res); } srv_socket->addr.ipv6.sin6_port = htons(port); addr_len = sizeof(struct sockaddr_in6); break; #endif case AF_INET: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in)); srv_socket->addr.ipv4.sin_family = AF_INET; if (host == NULL) { srv_socket->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY); } else { struct hostent *he; if (NULL == (he = gethostbyname(host))) { log_error_write(srv, __FILE__, __LINE__, "sds", "gethostbyname failed: ", h_errno, host); return -1; } if (he->h_addrtype != AF_INET) { log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype); return -1; } if (he->h_length != sizeof(struct in_addr)) { log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length); return -1; } memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length); } srv_socket->addr.ipv4.sin_port = htons(port); addr_len = sizeof(struct sockaddr_in); break; case AF_UNIX: srv_socket->addr.un.sun_family = AF_UNIX; strcpy(srv_socket->addr.un.sun_path, host); #ifdef SUN_LEN addr_len = SUN_LEN(&srv_socket->addr.un); #else /* stevens says: */ addr_len = strlen(host) + 1 + sizeof(srv_socket->addr.un.sun_family); #endif /* check if the socket exists and try to connect to it. */ if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) { close(fd); log_error_write(srv, __FILE__, __LINE__, "ss", "server socket is still in use:", host); return -1; } /* connect failed */ switch(errno) { case ECONNREFUSED: unlink(host); break; case ENOENT: break; default: log_error_write(srv, __FILE__, __LINE__, "sds", "testing socket failed:", host, strerror(errno)); return -1; } break; default: addr_len = 0; return -1; } if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { switch(srv_socket->addr.plain.sa_family) { case AF_UNIX: log_error_write(srv, __FILE__, __LINE__, "sds", "can't bind to socket:", host, strerror(errno)); break; default: log_error_write(srv, __FILE__, __LINE__, "ssds", "can't bind to port:", host, port, strerror(errno)); break; } return -1; } if (-1 == listen(srv_socket->fd, 128 * 8)) { log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno)); return -1; } if (s->is_ssl) { #ifdef USE_OPENSSL if (srv->ssl_is_init == 0) { SSL_load_error_strings(); SSL_library_init(); srv->ssl_is_init = 1; if (0 == RAND_status()) { log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", "not enough entropy in the pool"); return -1; } } if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ERR_error_string(ERR_get_error(), NULL)); return -1; } if (!s->ssl_use_sslv2) { /* disable SSLv2 */ if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ERR_error_string(ERR_get_error(), NULL)); return -1; } } if (!buffer_is_empty(s->ssl_cipher_list)) { /* Disable support for low encryption ciphers */ if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ERR_error_string(ERR_get_error(), NULL)); return -1; } } if (buffer_is_empty(s->ssl_pemfile)) { log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); return -1; } if (!buffer_is_empty(s->ssl_ca_file)) { if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); return -1; } } if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); return -1; } if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); return -1; } if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", "Private key does not match the certificate public key, reason:", ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); return -1; } SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); srv_socket->ssl_ctx = s->ssl_ctx; #else buffer_free(srv_socket->srv_token); free(srv_socket); buffer_free(b); log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", "ssl requested but openssl support is not compiled in"); return -1; #endif } else { #ifdef SO_ACCEPTFILTER /* * FreeBSD accf_http filter * */ memset(&afa, 0, sizeof(afa)); strcpy(afa.af_name, "httpready"); if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) { if (errno != ENOENT) { log_error_write(srv, __FILE__, __LINE__, "ss", "can't set accept-filter 'httpready': ", strerror(errno)); } } #endif } srv_socket->is_ssl = s->is_ssl; srv_socket->fde_ndx = -1; if (srv->srv_sockets.size == 0) { srv->srv_sockets.size = 4; srv->srv_sockets.used = 0; srv->srv_sockets.ptr = malloc(srv->srv_sockets.size * sizeof(server_socket)); } else if (srv->srv_sockets.used == srv->srv_sockets.size) { srv->srv_sockets.size += 4; srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket)); } srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket; buffer_free(b); return 0; }
void TEST_COMPLETE_MULTIPART_UPLOAD_QUERYPARA(void) { char md5_buf[32]; snprintf(object_key, 1024, "%s", __FUNCTION__); if (0 != init_complete() ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "uploadId=%s", uploadid_str); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); snprintf(object_key, 1024, "%s", __FUNCTION__); if (0 != init_complete() ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "uploadid=%s", uploadid_str); // resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); snprintf(object_key, 1024, "%s", __FUNCTION__); if (0 != init_complete() ){ CU_ASSERT(0); return ; } snprintf(query_str, sizeof(query_str), "UPLOADID=%s", uploadid_str); // resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(200 == resp->status_code); if (resp->status_code != 200) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); if (0 != init_complete() ){ CU_ASSERT(0); return ; } // <Code>NoSuchUpload</Code> snprintf(query_str, sizeof(query_str), "uploadId=%s001", uploadid_str); resp = complete_multipart_upload(host, bucket, object_key, ak, sk, uploadid_str, com_xml, strlen(com_xml), query_str, "", &error); CU_ASSERT(0 == error); CU_ASSERT(403 == resp->status_code); if (resp->status_code != 403) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); resp = delete_object(host, bucket, object_key, ak, sk, NULL, &error); CU_ASSERT(0 == error); CU_ASSERT(204 == resp->status_code); if (resp->status_code != 204) { printf("test %s:%d:\n", __FUNCTION__, __LINE__); printf("status code = %ld\n", resp->status_code); printf("status msg = %s\n", resp->status_msg); printf("error msg = %s\n", resp->body); } buffer_free(resp); return; }
static int network_server_init(server *srv, buffer *host_token, specific_config *s) { int val; socklen_t addr_len; server_socket *srv_socket; char *sp; unsigned int port = 0; const char *host; buffer *b; int is_unix_domain_socket = 0; int fd; #ifdef __WIN32 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return -1; } #endif srv_socket = calloc(1, sizeof(*srv_socket)); srv_socket->fd = -1; srv_socket->fde_ndx = -1; srv_socket->srv_token = buffer_init(); buffer_copy_string_buffer(srv_socket->srv_token, host_token); b = buffer_init(); buffer_copy_string_buffer(b, host_token); /* ipv4:port * [ipv6]:port */ if (NULL == (sp = strrchr(b->ptr, ':'))) { log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b); goto error_free_socket; } host = b->ptr; /* check for [ and ] */ if (b->ptr[0] == '[' && *(sp-1) == ']') { *(sp-1) = '\0'; host++; s->use_ipv6 = 1; } *(sp++) = '\0'; port = strtol(sp, NULL, 10); if (host[0] == '/') { /* host is a unix-domain-socket */ is_unix_domain_socket = 1; } else if (port == 0 || port > 65535) { log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port); goto error_free_socket; } if (*host == '\0') host = NULL; if (is_unix_domain_socket) { #ifdef HAVE_SYS_UN_H srv_socket->addr.plain.sa_family = AF_UNIX; if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, 0))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); goto error_free_socket; } #else log_error_write(srv, __FILE__, __LINE__, "s", "ERROR: Unix Domain sockets are not supported."); goto error_free_socket; #endif } #ifdef HAVE_IPV6 if (s->use_ipv6) { srv_socket->addr.plain.sa_family = AF_INET6; if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); goto error_free_socket; } srv_socket->use_ipv6 = 1; } #endif if (srv_socket->fd == -1) { srv_socket->addr.plain.sa_family = AF_INET; if (-1 == (srv_socket->fd = socket(srv_socket->addr.plain.sa_family, SOCK_STREAM, IPPROTO_TCP))) { log_error_write(srv, __FILE__, __LINE__, "ss", "socket failed:", strerror(errno)); goto error_free_socket; } } #ifdef FD_CLOEXEC /* set FD_CLOEXEC now, fdevent_fcntl_set is called later; needed for pipe-logger forks */ fcntl(srv_socket->fd, F_SETFD, FD_CLOEXEC); #endif /* */ srv->cur_fds = srv_socket->fd; val = 1; if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { log_error_write(srv, __FILE__, __LINE__, "ss", "socketsockopt failed:", strerror(errno)); goto error_free_socket; } switch(srv_socket->addr.plain.sa_family) { #ifdef HAVE_IPV6 case AF_INET6: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in6)); srv_socket->addr.ipv6.sin6_family = AF_INET6; if (host == NULL) { srv_socket->addr.ipv6.sin6_addr = in6addr_any; } else { struct addrinfo hints, *res; int r; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) { log_error_write(srv, __FILE__, __LINE__, "sssss", "getaddrinfo failed: ", gai_strerror(r), "'", host, "'"); goto error_free_socket; } memcpy(&(srv_socket->addr), res->ai_addr, res->ai_addrlen); freeaddrinfo(res); } srv_socket->addr.ipv6.sin6_port = htons(port); addr_len = sizeof(struct sockaddr_in6); break; #endif case AF_INET: memset(&srv_socket->addr, 0, sizeof(struct sockaddr_in)); srv_socket->addr.ipv4.sin_family = AF_INET; if (host == NULL) { srv_socket->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY); } else { struct hostent *he; if (NULL == (he = gethostbyname(host))) { log_error_write(srv, __FILE__, __LINE__, "sds", "gethostbyname failed: ", h_errno, host); goto error_free_socket; } if (he->h_addrtype != AF_INET) { log_error_write(srv, __FILE__, __LINE__, "sd", "addr-type != AF_INET: ", he->h_addrtype); goto error_free_socket; } if (he->h_length != sizeof(struct in_addr)) { log_error_write(srv, __FILE__, __LINE__, "sd", "addr-length != sizeof(in_addr): ", he->h_length); goto error_free_socket; } memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length); } srv_socket->addr.ipv4.sin_port = htons(port); addr_len = sizeof(struct sockaddr_in); break; case AF_UNIX: srv_socket->addr.un.sun_family = AF_UNIX; strcpy(srv_socket->addr.un.sun_path, host); #ifdef SUN_LEN addr_len = SUN_LEN(&srv_socket->addr.un); #else /* stevens says: */ addr_len = strlen(host) + 1 + sizeof(srv_socket->addr.un.sun_family); #endif /* check if the socket exists and try to connect to it. */ if (-1 != (fd = connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len))) { close(fd); log_error_write(srv, __FILE__, __LINE__, "ss", "server socket is still in use:", host); goto error_free_socket; } /* connect failed */ switch(errno) { case ECONNREFUSED: unlink(host); break; case ENOENT: break; default: log_error_write(srv, __FILE__, __LINE__, "sds", "testing socket failed:", host, strerror(errno)); goto error_free_socket; } break; default: goto error_free_socket; } if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { switch(srv_socket->addr.plain.sa_family) { case AF_UNIX: log_error_write(srv, __FILE__, __LINE__, "sds", "can't bind to socket:", host, strerror(errno)); break; default: log_error_write(srv, __FILE__, __LINE__, "ssds", "can't bind to port:", host, port, strerror(errno)); break; } goto error_free_socket; } if (-1 == listen(srv_socket->fd, 128 * 8)) { log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno)); goto error_free_socket; } if (s->is_ssl) { #ifdef USE_OPENSSL if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) { log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); goto error_free_socket; } #else buffer_free(srv_socket->srv_token); free(srv_socket); buffer_free(b); log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", "ssl requested but openssl support is not compiled in"); goto error_free_socket; #endif #ifdef TCP_DEFER_ACCEPT } else if (s->defer_accept) { int v = s->defer_accept; if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) { log_error_write(srv, __FILE__, __LINE__, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno)); } #endif } else { #ifdef SO_ACCEPTFILTER /* FreeBSD accf_http filter */ struct accept_filter_arg afa; memset(&afa, 0, sizeof(afa)); strcpy(afa.af_name, "httpready"); if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) { if (errno != ENOENT) { log_error_write(srv, __FILE__, __LINE__, "ss", "can't set accept-filter 'httpready': ", strerror(errno)); } } #endif } srv_socket->is_ssl = s->is_ssl; if (srv->srv_sockets.size == 0) { srv->srv_sockets.size = 4; srv->srv_sockets.used = 0; srv->srv_sockets.ptr = malloc(srv->srv_sockets.size * sizeof(server_socket)); } else if (srv->srv_sockets.used == srv->srv_sockets.size) { srv->srv_sockets.size += 4; srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket)); } srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket; buffer_free(b); return 0; error_free_socket: if (srv_socket->fd != -1) { /* check if server fd are already registered */ if (srv_socket->fde_ndx != -1) { fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd); fdevent_unregister(srv->ev, srv_socket->fd); } close(srv_socket->fd); } buffer_free(srv_socket->srv_token); free(srv_socket); return -1; }
int mail_transaction_log_file_open(struct mail_transaction_log_file *file) { struct mail_index *index = file->log->index; unsigned int i; bool ignore_estale; int ret; for (i = 0;; i++) { if (!index->readonly) { file->fd = nfs_safe_open(file->filepath, O_RDWR | O_APPEND); } else { file->fd = nfs_safe_open(file->filepath, O_RDONLY); } if (file->fd == -1 && errno == EACCES) { file->fd = nfs_safe_open(file->filepath, O_RDONLY); index->readonly = TRUE; } if (file->fd == -1) { if (errno == ENOENT) return 0; log_file_set_syscall_error(file, "open()"); return -1; } ignore_estale = i < MAIL_INDEX_ESTALE_RETRY_COUNT; if (mail_transaction_log_file_stat(file, ignore_estale) < 0) ret = -1; else if (mail_transaction_log_file_is_dupe(file)) { /* probably our already opened .log file has been renamed to .log.2 and we're trying to reopen it. also possible that hit a race condition where .log and .log.2 are linked. */ return 0; } else { ret = mail_transaction_log_file_read_hdr(file, ignore_estale); } if (ret > 0) { /* success */ break; } if (ret == 0) { /* corrupted */ if (index->readonly) { /* don't delete */ } else { i_unlink_if_exists(file->filepath); } return 0; } if (errno != ESTALE || i == MAIL_INDEX_ESTALE_RETRY_COUNT) { /* syscall error */ return -1; } /* ESTALE - try again */ buffer_free(&file->buffer); } mail_transaction_log_file_add_to_list(file); return 1; }