static struct music_file *new_music_file(const char *spath, const char *lpath) { struct music_file *p = calloc(1, sizeof(*p)); if (p == NULL) return p; p->shortpath = buffer_init(); if (p->shortpath == NULL) { free(p); return NULL; } p->longpath = buffer_init(); if (p->longpath == NULL) { buffer_free(p->shortpath); free(p); return NULL; } buffer_copy_string(p->shortpath, spath); buffer_copy_string(p->longpath, lpath); p->next = NULL; return p; }
static void proxy_set_header(connection *con, const char *key, const char *value) { data_string *ds_dst; if (NULL == (ds_dst = (data_string *)array_get_unused_element(con->request.headers, TYPE_STRING))) { ds_dst = data_string_init(); } buffer_copy_string(ds_dst->key, key); buffer_copy_string(ds_dst->value, value); array_insert_unique(con->request.headers, (data_unset *)ds_dst); }
static int ssi_env_add(array *env, const char *key, const char *val) { data_string *ds; if (NULL == (ds = (data_string *)array_get_unused_element(env, TYPE_STRING))) { ds = data_string_init(); } buffer_copy_string(ds->key, key); buffer_copy_string(ds->value, val); array_insert_unique(env, (data_unset *)ds); return 0; }
static int magnet_env_set(lua_State *L) { server *srv; connection *con; const char *key = luaL_checkstring(L, 2); const char *val = luaL_checkstring(L, 3); buffer *dest = NULL; lua_pushstring(L, "lighty.srv"); lua_gettable(L, LUA_REGISTRYINDEX); srv = lua_touserdata(L, -1); lua_pop(L, 1); lua_pushstring(L, "lighty.con"); lua_gettable(L, LUA_REGISTRYINDEX); con = lua_touserdata(L, -1); lua_pop(L, 1); if (NULL != (dest = magnet_env_get_buffer(srv, con, key))) { buffer_copy_string(dest, val); } else { /* couldn't save */ return luaL_error(L, "couldn't store '%s' in lighty.env[]", key); } return 0; }
void query_one_hostname(){ smb_srv_info_t *p; for (p = smb_srv_info_list; p; p = p->next) { if(strcmp(p->name->ptr, "")!=0){ continue; } if(p->id==0){ Cdbg(DBE, "query_one_hostname [%s]\n", p->ip->ptr); //continue; } char* hostname = smbc_nmblookup(p->ip->ptr); if(hostname==NULL){ //Cdbg(DBE, "\t\tCan't query samba server name[%s]\n", p->ip->ptr); buffer_free(p->ip); buffer_free(p->mac); buffer_free(p->name); DLIST_REMOVE(smb_srv_info_list, p); free(p); } else{ buffer_copy_string(p->name, hostname); } } }
buffer *buffer_init_string(const char *str) { buffer *b = buffer_init(); buffer_copy_string(b, str); return b; }
static void test_configfile_addrbuf_eq_remote_ip_mask (void) { int i, m; buffer * const s = buffer_init(); sock_addr rmt; for (i = 0; i < (int)(sizeof(rmtmask)/sizeof(rmtmask[0])); ++i) { #ifndef HAVE_INET_PTON rmt.ipv4.sin_family = AF_INET; rmt.ipv4.sin_addr.s_addr = inet_addr(rmtmask[i].rmtstr); #else if (rmtmask[i].rmtfamily == AF_INET) { rmt.ipv4.sin_family = AF_INET; inet_pton(AF_INET, rmtmask[i].rmtstr, &rmt.ipv4.sin_addr); #ifdef HAVE_IPV6 } else if (rmtmask[i].rmtfamily == AF_INET6) { rmt.ipv6.sin6_family = AF_INET6; inet_pton(AF_INET6, rmtmask[i].rmtstr, &rmt.ipv6.sin6_addr); #endif } else { continue; } #endif buffer_copy_string(s, rmtmask[i].string); m = config_addrbuf_eq_remote_ip_mask(NULL,s,strchr(s->ptr,'/'),&rmt); if (m != rmtmask[i].expect) { fprintf(stderr, "failed assertion: %s %s %s\n", rmtmask[i].string, rmtmask[i].expect ? "==" : "!=", rmtmask[i].rmtstr); exit(-1); } } buffer_free(s); }
static int proxy_create_env(server *srv, handler_ctx *hctx) { size_t i; connection *con = hctx->remote_conn; buffer *b; /* build header */ b = buffer_init(); /* request line */ buffer_copy_string(b, get_http_method_name(con->request.http_method)); buffer_append_string_len(b, CONST_STR_LEN(" ")); buffer_append_string_buffer(b, con->request.uri); buffer_append_string_len(b, CONST_STR_LEN(" HTTP/1.0\r\n")); proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr))); /* http_host is NOT is just a pointer to a buffer * which is NULL if it is not set */ if (!buffer_string_is_empty(con->request.http_host)) { proxy_set_header(con, "X-Host", con->request.http_host->ptr); } proxy_set_header(con, "X-Forwarded-Proto", con->uri.scheme->ptr); /* request header */ for (i = 0; i < con->request.headers->used; i++) { data_string *ds; ds = (data_string *)con->request.headers->data[i]; if (!buffer_is_empty(ds->value) && !buffer_is_empty(ds->key)) { if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Connection"))) continue; if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Proxy-Connection"))) continue; buffer_append_string_buffer(b, ds->key); buffer_append_string_len(b, CONST_STR_LEN(": ")); buffer_append_string_buffer(b, ds->value); buffer_append_string_len(b, CONST_STR_LEN("\r\n")); } } buffer_append_string_len(b, CONST_STR_LEN("\r\n")); hctx->wb->bytes_in += buffer_string_length(b); chunkqueue_append_buffer(hctx->wb, b); buffer_free(b); /* body */ if (con->request.content_length) { chunkqueue *req_cq = con->request_content_queue; chunkqueue_steal(hctx->wb, req_cq, req_cq->bytes_in); } return 0; }
static void aicloud_connection_smb_info_url_patch(server *srv, connection *con) { char strr[2048]="\0"; char uri[2048]="\0"; UNUSED(srv); char* pch = strchr(con->request.uri->ptr,'?'); if(pch){ buffer_copy_string_len(con->url_options, pch+1, strlen(pch)-1); int len = pch-con->request.uri->ptr; strncpy(uri,con->request.uri->ptr, len); } else{ strcpy(uri,con->request.uri->ptr); } if(con->mode == DIRECT){ sprintf(strr, "%s", uri); } else { if(con->smb_info&&con->smb_info->server->used) { if(con->mode == SMB_BASIC){ if(con->smb_info->username->used&&con->smb_info->password->used){ sprintf(strr, "smb://%s:%s@%s", con->smb_info->username->ptr, con->smb_info->password->ptr, uri+1); } else sprintf(strr, "smb://%s", uri+1); } else if(con->mode == SMB_NTLM){ sprintf(strr, "smb://%s", uri+1); } } else { sprintf(strr, "smb://"); } } buffer_copy_string(con->url.path, strr); buffer_copy_string(con->url.rel_path, uri); buffer_urldecode_path(con->url.path); buffer_urldecode_path(con->url.rel_path); }
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) { const char *servername; connection *con = (connection *) SSL_get_app_data(ssl); UNUSED(al); buffer_copy_string(con->uri.scheme, "https"); if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { #if 0 /* this "error" just means the client didn't support it */ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", "failed to get TLS server name"); #endif return SSL_TLSEXT_ERR_NOACK; } buffer_copy_string(con->tlsext_server_name, servername); buffer_to_lower(con->tlsext_server_name); /* Sometimes this is still set, confusing COMP_HTTP_HOST */ buffer_reset(con->uri.authority); config_cond_cache_reset(srv, con); config_setup_connection(srv, con); config_patch_connection(srv, con, COMP_SERVER_SOCKET); config_patch_connection(srv, con, COMP_HTTP_SCHEME); config_patch_connection(srv, con, COMP_HTTP_HOST); if (NULL == con->conf.ssl_ctx) { /* ssl_ctx <=> pemfile was set <=> ssl_ctx got patched: so this should never happen */ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", "null SSL_CTX for TLS server name", con->tlsext_server_name); return SSL_TLSEXT_ERR_ALERT_FATAL; } /* switch to new SSL_CTX in reaction to a client's server_name extension */ if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) { log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", "failed to set SSL_CTX for TLS server name", con->tlsext_server_name); return SSL_TLSEXT_ERR_ALERT_FATAL; } return SSL_TLSEXT_ERR_OK; }
connection *connection_accepted(server *srv, server_socket *srv_socket, sock_addr *cnt_addr, int cnt) { connection *con; srv->cur_fds++; /* ok, we have the connection, register it */ #if 0 log_error_write(srv, __FILE__, __LINE__, "sd", "appected()", cnt); #endif srv->con_opened++; con = connections_get_new_connection(srv); con->fd = cnt; con->fde_ndx = -1; fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con); connection_set_state(srv, con, CON_STATE_REQUEST_START); con->connection_start = srv->cur_ts; con->dst_addr = *cnt_addr; buffer_copy_string(con->dst_addr_buf, inet_ntop_cache_get_ip(srv, &(con->dst_addr))); con->srv_socket = srv_socket; if (-1 == fdevent_fcntl_set_nb_cloexec_sock(srv->ev, con->fd)) { log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno)); connection_close(srv, con); return NULL; } #ifdef USE_OPENSSL /* connect FD to SSL */ if (srv_socket->is_ssl) { if (NULL == (con->ssl = SSL_new(srv_socket->ssl_ctx))) { log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ERR_error_string(ERR_get_error(), NULL)); connection_close(srv, con); return NULL; } con->renegotiations = 0; SSL_set_app_data(con->ssl, con); SSL_set_accept_state(con->ssl); if (1 != (SSL_set_fd(con->ssl, cnt))) { log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", ERR_error_string(ERR_get_error(), NULL)); connection_close(srv, con); return NULL; } } #endif return con; }
static int chmEnum(struct chmFile *h, struct chmUnitInfo *ui, void *context) { t_win_menuitem item; t_fs_filetype ft; char fname[PATH_MAX] = ""; char t[20]; int size = strlen(ui->path); if (size == 0 || ui->path[size - 1] == '/') return CHM_ENUMERATOR_CONTINUE; ft = fs_file_get_type(ui->path); if (ft == fs_filetype_chm || ft == fs_filetype_zip || ft == fs_filetype_rar || ft == fs_filetype_umd || ft == fs_filetype_pdb) return CHM_ENUMERATOR_CONTINUE; win_menuitem_new(&item); buffer_copy_string(item.compname, ui->path); SPRINTF_S(t, "%u", (unsigned int) ui->length); buffer_copy_string(item.shortname, t); if (ui->path[0] == '/') { strncpy_s(fname, NELEMS(fname), ui->path + 1, 256); } else { strncpy_s(fname, NELEMS(fname), ui->path, 256); } charsets_utf8_conv((unsigned char *) fname, sizeof(fname), (unsigned char *) fname, sizeof(fname)); item.data = (void *) ft; filename_to_itemname(&item, fname); item.selected = false; item.icolor = ((p_fs_chm_enum) context)->icolor; item.selicolor = ((p_fs_chm_enum) context)->selicolor; item.selrcolor = ((p_fs_chm_enum) context)->selrcolor; item.selbcolor = ((p_fs_chm_enum) context)->selbcolor; item.data3 = ui->length; win_menu_add(g_menu, &item); return CHM_ENUMERATOR_CONTINUE; }
void query_one_hostname(void) { smb_srv_info_t *p; int bchange = 0; for (p = smb_srv_info_list; p; p = p->next) { if(is_shutdown || g_kill_list) break; Cdbg(DBE, "Query samba server name, ip=[%s]", p->ip->ptr); const char *hostname = smbc_nmblookup(p->ip->ptr); if( strcmp(p->name->ptr, "")!=0&& hostname!=NULL && strcmp(p->name->ptr, hostname)==0 && p->online ==1 ){ if(hostname){ free((char*) hostname); hostname=NULL; } continue; } if(hostname==NULL){ if(p->online==1){ p->online = 0; bchange = 1; Cdbg(DBE, "Can't query samba server name, set ip=[%s] offline", p->ip->ptr); } } else{ p->online = 1; buffer_reset(p->name); buffer_copy_string(p->name, hostname); bchange = 1; Cdbg(DBE, "query samba server name[%s], set ip=[%s] online", hostname, p->ip->ptr ); } if(bchange==1) save_arpping_list(); if(hostname){ free((char*) hostname); hostname=NULL; } } //if(bchange==1) // save_arpping_list(); }
static buffer *magnet_env_get_buffer_by_id(server *srv, connection *con, int id) { buffer *dest = NULL; UNUSED(srv); /** * map all internal variables to lua * */ switch (id) { case MAGNET_ENV_PHYICAL_PATH: dest = con->physical.path; break; case MAGNET_ENV_PHYICAL_REL_PATH: dest = con->physical.rel_path; break; case MAGNET_ENV_PHYICAL_DOC_ROOT: dest = con->physical.doc_root; break; case MAGNET_ENV_PHYICAL_BASEDIR: dest = con->physical.basedir; break; case MAGNET_ENV_URI_PATH: dest = con->uri.path; break; case MAGNET_ENV_URI_PATH_RAW: dest = con->uri.path_raw; break; case MAGNET_ENV_URI_SCHEME: dest = con->uri.scheme; break; case MAGNET_ENV_URI_AUTHORITY: dest = con->uri.authority; break; case MAGNET_ENV_URI_QUERY: dest = con->uri.query; break; case MAGNET_ENV_REQUEST_METHOD: buffer_copy_string(srv->tmp_buf, get_http_method_name(con->request.http_method)); dest = srv->tmp_buf; break; case MAGNET_ENV_REQUEST_URI: dest = con->request.uri; break; case MAGNET_ENV_REQUEST_ORIG_URI: dest = con->request.orig_uri; break; case MAGNET_ENV_REQUEST_PATH_INFO: dest = con->request.pathinfo; break; case MAGNET_ENV_REQUEST_REMOTE_IP: dest = con->dst_addr_buf; break; case MAGNET_ENV_REQUEST_PROTOCOL: buffer_copy_string(srv->tmp_buf, get_http_version_name(con->request.http_version)); dest = srv->tmp_buf; break; case MAGNET_ENV_UNSET: break; } return dest; }
int response_header_overwrite(server *srv, connection *con, const char *key, size_t keylen, const char *value, size_t vallen) { data_string *ds; UNUSED(srv); /* if there already is a key by this name overwrite the value */ if (NULL != (ds = (data_string *)array_get_element(con->response.headers, key))) { buffer_copy_string(ds->value, value); return 0; } return response_header_insert(srv, con, key, keylen, value, vallen); }
void print_help() { buffer * b=buffer_init(); buffer_copy_string(b, "minihttpd is a simple,high-performance webserver\n" \ "usage:\n" \ "-f configuration_file specify the configuration file you want to load for minihttpd\n" \ "-D specify the minihttpd do not run as a deamon process\n" \ "-v print the minihttpd version information\n" \ "-h show help\n"); fprintf(stdout,"%s",(const char*)b->ptr); buffer_free(b); }
static int add_parent_to_menu(p_win_menu menu, u32 icolor, u32 selicolor, u32 selrcolor, u32 selbcolor) { t_win_menuitem item; if (menu == NULL) { return -1; } win_menuitem_new(&item); STRCPY_S(item.name, "<..>"); buffer_copy_string(item.compname, ".."); buffer_copy_string(item.shortname, ".."); item.data = (void *) fs_filetype_dir; item.width = 4; item.selected = false; item.icolor = icolor; item.selicolor = selicolor; item.selrcolor = selrcolor; item.selbcolor = selbcolor; win_menu_add(menu, &item); return 0; }
void save_arpping_list(void) { #if EMBEDDED_EANBLE smb_srv_info_t* c; buffer* smbdav_list = buffer_init(); buffer_copy_string(smbdav_list, ""); for (c = smb_srv_info_list; c; c = c->next) { if(c->name->used == 0 || strcmp(c->name->ptr,"")==0) continue; char temp[50]="\0"; sprintf(temp, "%s<%s<%s<%d>", c->name->ptr, c->ip->ptr, c->mac->ptr, c->online); buffer_append_string(smbdav_list, temp); } Cdbg(DBE, "nvram_set_smbdav_str %s", smbdav_list->ptr); nvram_set_smbdav_str(smbdav_list->ptr); buffer_free(smbdav_list); #else unlink(g_temp_file); smb_srv_info_t* c; char mybuffer[100]; FILE* fp = fopen(g_temp_file, "w"); Cdbg(DBE, "save_arpping_list %s", g_temp_file); if(fp!=NULL){ smb_srv_info_t* c; for (c = smb_srv_info_list; c; c = c->next) { if(c->name->used == 0 || strcmp(c->name->ptr,"")==0) continue; fprintf(fp, "%s<%s<%s<%d\n", c->name->ptr, c->ip->ptr, c->mac->ptr, c->online); } fclose(fp); } #endif }
static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) { int curelem = lua_gettop(L); int result; lua_getglobal(L, varname); if (lua_isstring(L, curelem)) { buffer_copy_string(b, lua_tostring(L, curelem)); result = 0; } else { result = -1; } lua_pop(L, 1); force_assert(curelem == lua_gettop(L)); return result; }
static int ssi_env_add_request_headers(server *srv, connection *con, plugin_data *p) { size_t i; for (i = 0; i < con->request.headers->used; i++) { data_string *ds; ds = (data_string *)con->request.headers->data[i]; if (ds->value->used && ds->key->used) { size_t j; buffer_reset(srv->tmp_buf); /* don't forward the Authorization: Header */ if (0 == strcasecmp(ds->key->ptr, "AUTHORIZATION")) { continue; } if (0 != strcasecmp(ds->key->ptr, "CONTENT-TYPE")) { buffer_copy_string(srv->tmp_buf, "HTTP_"); srv->tmp_buf->used--; } buffer_prepare_append(srv->tmp_buf, ds->key->used + 2); for (j = 0; j < ds->key->used - 1; j++) { char c = '_'; if (light_isalpha(ds->key->ptr[j])) { /* upper-case */ c = ds->key->ptr[j] & ~32; } else if (light_isdigit(ds->key->ptr[j])) { /* copy */ c = ds->key->ptr[j]; } srv->tmp_buf->ptr[srv->tmp_buf->used++] = c; } srv->tmp_buf->ptr[srv->tmp_buf->used] = '\0'; ssi_env_add(p->ssi_cgi_env, srv->tmp_buf->ptr, ds->value->ptr); } } return 0; }
void smbc_wrapper_response_401(server *srv, connection *con) { data_string *ds = (data_string *)array_get_element(con->request.headers, "user-Agent"); //- Browser response if( ds && (strstr( ds->value->ptr, "Mozilla" )||strstr( ds->value->ptr, "Opera" )) ){ if(con->mode == SMB_BASIC||con->mode == DIRECT){ Cdbg(DBE, "con->mode == SMB_BASIC -> return 401"); con->http_status = 401; return; } } Cdbg(DBE, "smbc_wrapper_response_401 -> return 401"); char str[50]; UNUSED(srv); buffer* tmp_buf = buffer_init(); if(con->mode == SMB_BASIC){ //sprintf(str, "Basic realm=\"%s\"", "smbdav"); if(con->smb_info&&con->smb_info->server->used) sprintf(str, "Basic realm=\"smb://%s\"", con->smb_info->server->ptr); else sprintf(str, "Basic realm=\"%s\"", "webdav"); } else if(con->mode == SMB_NTLM) sprintf(str, "NTLM"); else sprintf(str, "Basic realm=\"%s\"", "webdav"); buffer_copy_string(tmp_buf, str); response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf)); con->http_status = 401; buffer_free(tmp_buf); }
static int lua_to_c_get_string(lua_State *L, const char *varname, buffer *b) { int curelem; lua_pushstring(L, varname); curelem = lua_gettop(L); lua_gettable(L, LUA_GLOBALSINDEX); /* it should be a table */ if (!lua_isstring(L, curelem)) { lua_settop(L, curelem - 1); return -1; } buffer_copy_string(b, lua_tostring(L, curelem)); lua_pop(L, 1); assert(curelem - 1 == lua_gettop(L)); return 0; }
void smbc_wrapper_response_realm_401(server *srv, connection *con) { /* if(con->mode == SMB_BASIC){ if(con->smb_info&&con->smb_info->server->used){ Cdbg(DBE, "sssssssss"); con->http_status = 401; } return; } */ char str[50]; UNUSED(srv); buffer* tmp_buf = buffer_init(); if(con->mode == SMB_BASIC){ //sprintf(str, "Basic realm=\"%s\"", "smbdav"); if(con->smb_info&&con->smb_info->server->used) sprintf(str, "Basic realm=\"smb://%s\"", con->smb_info->server->ptr); else sprintf(str, "Basic realm=\"%s\"", "webdav"); } else if(con->mode == SMB_NTLM) sprintf(str, "NTLM"); else sprintf(str, "Basic realm=\"%s\"", "webdav"); buffer_copy_string(tmp_buf, str); response_header_insert(srv, con, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tmp_buf)); con->http_status = 401; buffer_free(tmp_buf); }
int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) { size_t i; data_unset *du; for (i = 0; cv[i].key; i++) { data_string *touched; if (NULL == (du = array_get_element(ca, cv[i].key))) { /* no found */ continue; } /* touched */ touched = data_string_init(); buffer_copy_string(touched->value, ""); buffer_copy_string_buffer(touched->key, du->key); array_insert_unique(srv->config_touched, (data_unset *)touched); } return config_insert_values_internal(srv, ca, cv); }
static cond_result_t config_check_cond_nocache(server *srv, connection *con, data_config *dc) { buffer *l; server_socket *srv_sock = con->srv_socket; /* check parent first */ if (dc->parent && dc->parent->context_ndx) { /** * a nested conditional * * if the parent is not decided yet or false, we can't be true either */ if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "sb", "go parent", dc->parent->key); } switch (config_check_cond_cached(srv, con, dc->parent)) { case COND_RESULT_FALSE: return COND_RESULT_FALSE; case COND_RESULT_UNSET: return COND_RESULT_UNSET; default: break; } } if (dc->prev) { /** * a else branch * * we can only be executed, if all of our previous brothers * are false */ if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "sb", "go prev", dc->prev->key); } /* make sure prev is checked first */ config_check_cond_cached(srv, con, dc->prev); /* one of prev set me to FALSE */ switch (con->cond_cache[dc->context_ndx].result) { case COND_RESULT_FALSE: return con->cond_cache[dc->context_ndx].result; default: break; } } if (!con->conditional_is_valid[dc->comp]) { if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "dss", dc->comp, dc->key->ptr, con->conditional_is_valid[dc->comp] ? "yeah" : "nej"); } return COND_RESULT_UNSET; } /* pass the rules */ switch (dc->comp) { case COMP_HTTP_HOST: { char *ck_colon = NULL, *val_colon = NULL; if (!buffer_string_is_empty(con->uri.authority)) { /* * append server-port to the HTTP_POST if necessary */ l = con->uri.authority; switch(dc->cond) { case CONFIG_COND_NE: case CONFIG_COND_EQ: ck_colon = strchr(dc->string->ptr, ':'); val_colon = strchr(l->ptr, ':'); if (NULL != ck_colon && NULL == val_colon) { /* condition "host:port" but client send "host" */ buffer_copy_buffer(srv->cond_check_buf, l); buffer_append_string_len(srv->cond_check_buf, CONST_STR_LEN(":")); buffer_append_int(srv->cond_check_buf, sock_addr_get_port(&(srv_sock->addr))); l = srv->cond_check_buf; } else if (NULL != val_colon && NULL == ck_colon) { /* condition "host" but client send "host:port" */ buffer_copy_string_len(srv->cond_check_buf, l->ptr, val_colon - l->ptr); l = srv->cond_check_buf; } break; default: break; } #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT } else if (!buffer_string_is_empty(con->tlsext_server_name)) { l = con->tlsext_server_name; #endif } else { l = srv->empty_string; } break; } case COMP_HTTP_REMOTE_IP: { char *nm_slash; /* handle remoteip limitations * * "10.0.0.1" is provided for all comparisions * * only for == and != we support * * "10.0.0.1/24" */ if ((dc->cond == CONFIG_COND_EQ || dc->cond == CONFIG_COND_NE) && (con->dst_addr.plain.sa_family == AF_INET) && (NULL != (nm_slash = strchr(dc->string->ptr, '/')))) { int nm_bits; long nm; char *err; struct in_addr val_inp; if (*(nm_slash+1) == '\0') { log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string); return COND_RESULT_FALSE; } nm_bits = strtol(nm_slash + 1, &err, 10); if (*err) { log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, err); return COND_RESULT_FALSE; } if (nm_bits > 32 || nm_bits < 0) { log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: invalid netmask:", dc->string, err); return COND_RESULT_FALSE; } /* take IP convert to the native */ buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr); #ifdef __WIN32 if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) { log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); return COND_RESULT_FALSE; } #else if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) { log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); return COND_RESULT_FALSE; } #endif /* build netmask */ nm = nm_bits ? htonl(~((1 << (32 - nm_bits)) - 1)) : 0; if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) { return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE; } else { return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE; } } else { l = con->dst_addr_buf; } break; } case COMP_HTTP_SCHEME: l = con->uri.scheme; break; case COMP_HTTP_URL: l = con->uri.path; break; case COMP_HTTP_QUERY_STRING: l = con->uri.query; break; case COMP_SERVER_SOCKET: l = srv_sock->srv_token; break; case COMP_HTTP_REFERER: { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { l = ds->value; } else { l = srv->empty_string; } break; } case COMP_HTTP_COOKIE: { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) { l = ds->value; } else { l = srv->empty_string; } break; } case COMP_HTTP_USER_AGENT: { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "User-Agent"))) { l = ds->value; } else { l = srv->empty_string; } break; } case COMP_HTTP_REQUEST_METHOD: { const char *method = get_http_method_name(con->request.http_method); /* we only have the request method as const char but we need a buffer for comparing */ buffer_copy_string(srv->tmp_buf, method); l = srv->tmp_buf; break; } case COMP_HTTP_LANGUAGE: { data_string *ds; if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Accept-Language"))) { l = ds->value; } else { l = srv->empty_string; } break; } default: return COND_RESULT_FALSE; } if (NULL == l) { if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "bsbs", dc->comp_key, "(", l, ") compare to NULL"); } return COND_RESULT_FALSE; } if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key, "(", l, ") compare to ", dc->string); } switch(dc->cond) { case CONFIG_COND_NE: case CONFIG_COND_EQ: if (buffer_is_equal(l, dc->string)) { return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE; } else { return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_FALSE : COND_RESULT_TRUE; } break; #ifdef HAVE_PCRE_H case CONFIG_COND_NOMATCH: case CONFIG_COND_MATCH: { cond_cache_t *cache = &con->cond_cache[dc->context_ndx]; int n; #ifndef elementsof #define elementsof(x) (sizeof(x) / sizeof(x[0])) #endif n = pcre_exec(dc->regex, dc->regex_study, CONST_BUF_LEN(l), 0, 0, cache->matches, elementsof(cache->matches)); cache->patterncount = n; if (n > 0) { cache->comp_value = l; cache->comp_type = dc->comp; return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_TRUE : COND_RESULT_FALSE; } else { /* cache is already cleared */ return (dc->cond == CONFIG_COND_MATCH) ? COND_RESULT_FALSE : COND_RESULT_TRUE; } break; } #endif default: /* no way */ break; } return COND_RESULT_FALSE; }
handler_t http_response_prepare(server *srv, connection *con) { handler_t r; Cdbg(DBE, "enter http_response_prepare..mode=[%d], status=[%d][%s]", con->mode, con->http_status, connection_get_state(con->http_status)); /* looks like someone has already done a decision */ if ( (con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) && (con->http_status != 0 && con->http_status != 200)) { /* remove a packets in the queue */ if (con->file_finished == 0) { chunkqueue_reset(con->write_queue); } return HANDLER_FINISHED; } /* no decision yet, build conf->filename */ if ( (con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) && con->physical.path->used == 0) { char *qstr; /* we only come here when we have the parse the full request again * * a HANDLER_COMEBACK from mod_rewrite and mod_fastcgi might be a * problem here as mod_setenv might get called multiple times * * fastcgi-auth might lead to a COMEBACK too * fastcgi again dead server too * * mod_compress might add headers twice too * * */ config_cond_cache_reset(srv, con); config_setup_connection(srv, con); /* Perhaps this could be removed at other places. */ if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "run condition"); } config_patch_connection(srv, con, COMP_SERVER_SOCKET); /* SERVERsocket */ /** * prepare strings * * - uri.path_raw * - uri.path (secure) * - uri.query * */ /** * Name according to RFC 2396 * * - scheme * - authority * - path * - query * * (scheme)://(authority)(path)?(query)#fragment * * */ if (con->conf.is_ssl) { buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("https")); } else { buffer_copy_string_len(con->uri.scheme, CONST_STR_LEN("http")); } buffer_copy_string_buffer(con->uri.authority, con->request.http_host); buffer_to_lower(con->uri.authority); config_patch_connection(srv, con, COMP_HTTP_SCHEME); /* Scheme: */ config_patch_connection(srv, con, COMP_HTTP_HOST); /* Host: */ config_patch_connection(srv, con, COMP_HTTP_REMOTE_IP); /* Client-IP */ config_patch_connection(srv, con, COMP_HTTP_REFERER); /* Referer: */ config_patch_connection(srv, con, COMP_HTTP_USER_AGENT);/* User-Agent: */ config_patch_connection(srv, con, COMP_HTTP_LANGUAGE); /* Accept-Language: */ config_patch_connection(srv, con, COMP_HTTP_COOKIE); /* Cookie: */ config_patch_connection(srv, con, COMP_HTTP_REQUEST_METHOD); /* REQUEST_METHOD */ /** their might be a fragment which has to be cut away */ if (NULL != (qstr = strchr(con->request.uri->ptr, '#'))) { con->request.uri->used = qstr - con->request.uri->ptr; con->request.uri->ptr[con->request.uri->used++] = '\0'; } /** extract query string from request.uri */ if (NULL != (qstr = strchr(con->request.uri->ptr, '?'))) { buffer_copy_string(con->uri.query, qstr + 1); buffer_copy_string_len(con->uri.path_raw, con->request.uri->ptr, qstr - con->request.uri->ptr); } else { buffer_reset(con->uri.query); buffer_copy_string_buffer(con->uri.path_raw, con->request.uri); } if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- splitting Request-URI"); log_error_write(srv, __FILE__, __LINE__, "sb", "Request-URI : ", con->request.uri); log_error_write(srv, __FILE__, __LINE__, "sb", "URI-scheme : ", con->uri.scheme); log_error_write(srv, __FILE__, __LINE__, "sb", "URI-authority: ", con->uri.authority); log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path_raw); log_error_write(srv, __FILE__, __LINE__, "sb", "URI-query : ", con->uri.query); } /** * * call plugins * * - based on the raw URL * */ switch(r = plugins_call_handle_uri_raw(srv, con)) { case HANDLER_GO_ON: break; case HANDLER_FINISHED: case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: case HANDLER_ERROR: return r; default: log_error_write(srv, __FILE__, __LINE__, "sd", "handle_uri_raw: unknown return value", r); break; } /* build filename * * - decode url-encodings (e.g. %20 -> ' ') * - remove path-modifiers (e.g. /../) */ if (con->request.http_method == HTTP_METHOD_OPTIONS && con->uri.path_raw->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') { /* OPTIONS * ... */ buffer_copy_string_buffer(con->uri.path, con->uri.path_raw); } else { buffer_copy_string_buffer(srv->tmp_buf, con->uri.path_raw); buffer_urldecode_path(srv->tmp_buf); buffer_path_simplify(con->uri.path, srv->tmp_buf); } if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- sanatising URI"); log_error_write(srv, __FILE__, __LINE__, "sb", "URI-path : ", con->uri.path); } #ifdef USE_OPENSSL if (con->conf.is_ssl && con->conf.ssl_verifyclient) { https_add_ssl_entries(con); } #endif /** * * call plugins * * - based on the clean URL * */ config_patch_connection(srv, con, COMP_HTTP_URL); /* HTTPurl */ config_patch_connection(srv, con, COMP_HTTP_QUERY_STRING); /* HTTPqs */ /* do we have to downgrade to 1.0 ? */ if (!con->conf.allow_http11) { con->request.http_version = HTTP_VERSION_1_0; } switch(r = plugins_call_handle_uri_clean(srv, con)) { case HANDLER_GO_ON: break; case HANDLER_FINISHED: case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: case HANDLER_ERROR: return r; default: log_error_write(srv, __FILE__, __LINE__, ""); break; } if (con->request.http_method == HTTP_METHOD_OPTIONS && con->uri.path->ptr[0] == '*' && con->uri.path_raw->ptr[1] == '\0') { /* option requests are handled directly without checking of the path */ response_header_insert(srv, con, CONST_STR_LEN("Allow"), CONST_STR_LEN("OPTIONS, GET, HEAD, POST")); con->http_status = 200; con->file_finished = 1; return HANDLER_FINISHED; } /*** * * border * * logical filename (URI) becomes a physical filename here * * * */ /* 1. stat() * ... ISREG() -> ok, go on * ... ISDIR() -> index-file -> redirect * * 2. pathinfo() * ... ISREG() * * 3. -> 404 * */ /* * SEARCH DOCUMENT ROOT */ /* set a default */ buffer_copy_string_buffer(con->physical.doc_root, con->conf.document_root); buffer_copy_string_buffer(con->physical.rel_path, con->uri.path); #if defined(__WIN32) || defined(__CYGWIN__) /* strip dots from the end and spaces * * windows/dos handle those filenames as the same file * * foo == foo. == foo..... == "foo... " == "foo.. ./" * * This will affect in some cases PATHINFO * * on native windows we could prepend the filename with \\?\ to circumvent * this behaviour. I have no idea how to push this through cygwin * * */ if (con->physical.rel_path->used > 1) { buffer *b = con->physical.rel_path; size_t i; if (b->used > 2 && b->ptr[b->used-2] == '/' && (b->ptr[b->used-3] == ' ' || b->ptr[b->used-3] == '.')) { b->ptr[b->used--] = '\0'; } for (i = b->used - 2; b->used > 1; i--) { if (b->ptr[i] == ' ' || b->ptr[i] == '.') { b->ptr[b->used--] = '\0'; } else { break; } } } #endif if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- before doc_root"); log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); log_error_write(srv, __FILE__, __LINE__, "sb", "Rel-Path :", con->physical.rel_path); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } /* the docroot plugin should set the doc_root and might also set the physical.path * for us (all vhost-plugins are supposed to set the doc_root) * */ switch(r = plugins_call_handle_docroot(srv, con)) { case HANDLER_GO_ON: break; case HANDLER_FINISHED: case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: case HANDLER_ERROR: return r; default: log_error_write(srv, __FILE__, __LINE__, ""); break; } /* MacOS X and Windows can't distiguish between upper and lower-case * * convert to lower-case */ if (con->conf.force_lowercase_filenames) { buffer_to_lower(con->physical.rel_path); } /* the docroot plugins might set the servername, if they don't we take http-host */ if (buffer_is_empty(con->server_name)) { buffer_copy_string_buffer(con->server_name, con->uri.authority); } /** * create physical filename * -> physical.path = docroot + rel_path * */ buffer_copy_string_buffer(con->physical.path, con->physical.doc_root); BUFFER_APPEND_SLASH(con->physical.path); buffer_copy_string_buffer(con->physical.basedir, con->physical.path); if (con->physical.rel_path->used && con->physical.rel_path->ptr[0] == '/') { buffer_append_string_len(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2); //buffer_append_string_encoded(con->physical.path, con->physical.rel_path->ptr + 1, con->physical.rel_path->used - 2, ENCODING_REL_URI); //Cdbg(1,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa %s", con->physical.path->ptr); } else { buffer_append_string_buffer(con->physical.path, con->physical.rel_path); } if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- after doc_root"); log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); log_error_write(srv, __FILE__, __LINE__, "sb", "Rel-Path :", con->physical.rel_path); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } switch(r = plugins_call_handle_physical(srv, con)) { case HANDLER_GO_ON: break; case HANDLER_FINISHED: case HANDLER_COMEBACK: case HANDLER_WAIT_FOR_EVENT: case HANDLER_ERROR: return r; default: log_error_write(srv, __FILE__, __LINE__, ""); break; } if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- logical -> physical"); log_error_write(srv, __FILE__, __LINE__, "sb", "Doc-Root :", con->physical.doc_root); log_error_write(srv, __FILE__, __LINE__, "sb", "Rel-Path :", con->physical.rel_path); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } } /* * Noone catched away the file from normal path of execution yet (like mod_access) * * Go on and check of the file exists at all */ if (con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) { char *slash = NULL; char *pathinfo = NULL; int found = 0; stat_cache_entry *sce = NULL; if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- handling physical path"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } if ( HANDLER_ERROR != stat_cache_get_entry(srv, con, smbc_wrapper_physical_url_path(srv, con), &sce)) { /* file exists */ if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- file found"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } #ifdef HAVE_LSTAT if ((sce->is_symlink != 0) && !con->conf.follow_symlink) { con->http_status = 403; if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- access denied due symlink restriction"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } buffer_reset(con->physical.path); return HANDLER_FINISHED; }; #endif if (S_ISDIR(sce->st.st_mode)) { if (con->uri.path->ptr[con->uri.path->used - 2] != '/') { /* redirect to .../ */ http_response_redirect_to_directory(srv, con); return HANDLER_FINISHED; } #ifdef HAVE_LSTAT } else if (!S_ISREG(sce->st.st_mode) && !sce->is_symlink) { #else } else if (!S_ISREG(sce->st.st_mode)) { #endif /* any special handling of non-reg files ?*/ } } else { switch (errno) { case EACCES: con->http_status = 403; if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- access denied"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } buffer_reset(con->physical.path); return HANDLER_FINISHED; case ENOENT: con->http_status = 404; if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- file not found"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } buffer_reset(con->physical.path); return HANDLER_FINISHED; case ENOTDIR: /* PATH_INFO ! :) */ break; default: /* we have no idea what happend. let's tell the user so. */ con->http_status = 500; buffer_reset(con->physical.path); log_error_write(srv, __FILE__, __LINE__, "ssbsb", "file not found ... or so: ", strerror(errno), con->uri.path, "->", con->physical.path); return HANDLER_FINISHED; } /* not found, perhaps PATHINFO */ buffer_copy_string_buffer(srv->tmp_buf, con->physical.path); do { if (slash) { buffer_copy_string_len(con->physical.path, srv->tmp_buf->ptr, slash - srv->tmp_buf->ptr); } else { buffer_copy_string_buffer(con->physical.path, srv->tmp_buf); } if (HANDLER_ERROR != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { found = S_ISREG(sce->st.st_mode); break; } if (pathinfo != NULL) { *pathinfo = '\0'; } slash = strrchr(srv->tmp_buf->ptr, '/'); if (pathinfo != NULL) { /* restore '/' */ *pathinfo = '/'; } if (slash) pathinfo = slash; } while ((found == 0) && (slash != NULL) && ((size_t)(slash - srv->tmp_buf->ptr) > (con->physical.basedir->used - 2))); if (found == 0) { /* no it really doesn't exists */ con->http_status = 404; if (con->conf.log_file_not_found) { log_error_write(srv, __FILE__, __LINE__, "sbsb", "file not found:", con->uri.path, "->", con->physical.path); } buffer_reset(con->physical.path); return HANDLER_FINISHED; } #ifdef HAVE_LSTAT if ((sce->is_symlink != 0) && !con->conf.follow_symlink) { con->http_status = 403; if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- access denied due symlink restriction"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } buffer_reset(con->physical.path); return HANDLER_FINISHED; }; #endif /* we have a PATHINFO */ if (pathinfo) { buffer_copy_string(con->request.pathinfo, pathinfo); /* * shorten uri.path */ con->uri.path->used -= strlen(pathinfo); con->uri.path->ptr[con->uri.path->used - 1] = '\0'; } if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- after pathinfo check"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); log_error_write(srv, __FILE__, __LINE__, "sb", "URI :", con->uri.path); log_error_write(srv, __FILE__, __LINE__, "sb", "Pathinfo :", con->request.pathinfo); } } if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- handling subrequest"); log_error_write(srv, __FILE__, __LINE__, "sb", "Path :", con->physical.path); } /* call the handlers */ switch(r = plugins_call_handle_subrequest_start(srv, con)) { case HANDLER_GO_ON: /* request was not handled */ break; case HANDLER_FINISHED: default: if (con->conf.log_request_handling) { log_error_write(srv, __FILE__, __LINE__, "s", "-- subrequest finished"); } /* something strange happend */ return r; } /* if we are still here, no one wanted the file, status 403 is ok I think */ if ((con->mode == DIRECT || con->mode == SMB_BASIC || con->mode == SMB_NTLM) && con->http_status == 0) { switch (con->request.http_method) { case HTTP_METHOD_OPTIONS: con->http_status = 200; break; default: con->http_status = 403; } return HANDLER_FINISHED; } } switch(r = plugins_call_handle_subrequest(srv, con)) { case HANDLER_GO_ON: /* request was not handled, looks like we are done */ return HANDLER_FINISHED; case HANDLER_FINISHED: /* request is finished */ default: /* something strange happend */ return r; } /* can't happen */ return HANDLER_COMEBACK; }
handler_t basic_authentication_handler(server *srv, connection *con, plugin_data *p) { data_string *ds_auth = (data_string *)array_get_element(con->request.headers, "Authorization"); buffer *user = buffer_init(); buffer *pass = buffer_init(); buffer_copy_string(user, " "); buffer_copy_string(pass, " "); //Cdbg(DBE, "*********** con->request.uri..%s", con->request.uri->ptr); char *auth_username = NULL; char *auth_password = NULL; if( smbc_parser_basic_authentication(srv, con, &auth_username, &auth_password) != 1 ){ if(con->smb_info==NULL) goto error_401; //Cdbg(DBE, "1111111, %s, %s", con->smb_info->username->ptr, con->smb_info->password->ptr); if( con->smb_info->username->used && con->smb_info->password->used ){ buffer_copy_string_buffer(user, con->smb_info->username); buffer_copy_string_buffer(pass, con->smb_info->password); } Cdbg(DBE, "fail smbc_parser_basic_authentication-> %s, %s", user->ptr, pass->ptr); } else{ buffer_copy_string(user, auth_username); buffer_copy_string(pass, auth_password); free(auth_username); free(auth_password); } time_t cur_time = time(NULL); double result = difftime(cur_time, con->smb_info->auth_time); Cdbg(DBE, "difftime=[%1f]", result); if(con->smb_info->qflag == SMB_HOST_QUERY) { data_string *ds2 = (data_string *)array_get_element(con->request.headers, "user-Agent"); //- MUST login again more than 30 minutes if(result>1800){ goto error_401; } if( con->smb_info && buffer_is_equal_string(con->smb_info->username, "RELOGIN", 7) ){ buffer_reset(con->smb_info->username); buffer_reset(con->smb_info->password); goto error_401; } if(con->smb_info->username->used && con->smb_info->password->used){ buffer_copy_string_buffer(user, con->smb_info->username); buffer_copy_string_buffer(pass, con->smb_info->password); Cdbg(DBE, "SMB_HOST_QUERY-->copy from smb_info user=[%s], pass=[%s]", user->ptr, pass->ptr); } #if EMBEDDED_EANBLE if( strcmp(user->ptr, nvram_get_http_username())!=0 || strcmp(pass->ptr, nvram_get_http_passwd())!=0 ){ Cdbg(DBE, "smbc_host_account_authentication fail user=[%s], pass=[%s]", user->ptr, pass->ptr); goto error_401; } #else if( strcmp(user->ptr, "admin")!=0 || strcmp(pass->ptr, "admin")!=0 ){ Cdbg(DBE, "smbc_host_account_authentication fail user=[%s], pass=[%s]", user->ptr, pass->ptr); goto error_401; } #endif } else { //- check user / password struct stat st; if( con->smb_info && buffer_is_equal_string(con->smb_info->username, "RELOGIN", 7) ){ buffer_reset(con->smb_info->username); buffer_reset(con->smb_info->password); goto error_401; } int res = smbc_server_check_creds( con->smb_info->server->ptr, con->smb_info->share->ptr, con->smb_info->workgroup->ptr, user->ptr, pass->ptr ); //if( res == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED)) { if( res == 0xc00000bb ){ buffer_free(user); buffer_free(pass); con->http_status = 406; return HANDLER_FINISHED; } else if(res != 0) { //the username/password for smb_server is not correct if(con->smb_info->username->used && con->smb_info->password->used){ buffer_copy_string_buffer(user, con->smb_info->username); buffer_copy_string_buffer(pass, con->smb_info->password); Cdbg(DBE, "Try to login again, server=%s, share=%s, user=%s, pass=%s", con->smb_info->server->ptr, con->smb_info->share->ptr, user->ptr, pass->ptr); //- MUST login again more than 30 minutes if(result>1800){ buffer_copy_string(pass, ""); } //sprintf(strr, "smb://%s:%s@%s", user->ptr, pass->ptr, con->request.uri->ptr+1); int res = smbc_server_check_creds(con->smb_info->server->ptr, con->smb_info->share->ptr, con->smb_info->workgroup->ptr, user->ptr, pass->ptr); if(res != 0) goto error_401; } else goto error_401; } } con->smb_info->auth_time = time(NULL); if( !buffer_is_equal_string(user, "no", 2) && !buffer_is_equal_string(pass, "no", 2)){ buffer_copy_string_buffer(con->smb_info->username, user); buffer_copy_string_buffer(con->smb_info->password, pass); Cdbg(DBE, "save username=[%s], password=[%s], time=[%d] to con->smb_info", con->smb_info->username->ptr, con->smb_info->password->ptr, con->smb_info->auth_time); } buffer_free(user); buffer_free(pass); return HANDLER_UNSET; error_401: buffer_free(user); buffer_free(pass); if(con->smb_info) con->smb_info->auth_time = time(NULL); smbc_wrapper_response_401(srv, con); return HANDLER_FINISHED; }
int smbc_host_account_authentication(connection* con, const char *username, const char *password){ char *nvram_acc_list, *nvram_acc_webdavproxy; int st_samba_mode = 1; if (con->mode != SMB_BASIC&&con->mode != DIRECT) return -1; #if EMBEDDED_EANBLE char *a = nvram_get_acc_list(); if(a==NULL) return -1; int l = strlen(a); nvram_acc_list = (char*)malloc(l+1); strncpy(nvram_acc_list, a, l); nvram_acc_list[l] = '\0'; char *b = nvram_get_acc_webdavproxy(); if(b==NULL) return -1; l = strlen(b); nvram_acc_webdavproxy = (char*)malloc(l+1); strncpy(nvram_acc_webdavproxy, b, l); nvram_acc_webdavproxy[l] = '\0'; st_samba_mode = nvram_get_st_samba_mode(); #else int i = 100; nvram_acc_list = (char*)malloc(100); strcpy(nvram_acc_list, "admin<admin>jerry<jerry"); nvram_acc_webdavproxy = (char*)malloc(100); strcpy(nvram_acc_webdavproxy, "admin<1>jerry<0"); #endif int found_account = 0, account_right = -1; //- Share All, use guest account if(st_samba_mode==0){ buffer_copy_string(con->router_user, "guest"); account_right = 1; return account_right; } char * pch; pch = strtok(nvram_acc_list, "<>"); while(pch!=NULL){ char *name; char *pass; int len; //- User Name len = strlen(pch); name = (char*)malloc(len+1); strncpy(name, pch, len); name[len] = '\0'; //- User Password pch = strtok(NULL,"<>"); len = strlen(pch); pass = (char*)malloc(len+1); strncpy(pass, pch, len); pass[len] = '\0'; if( strcmp(username, name) == 0 && strcmp(password, pass) == 0 ){ //Cdbg(1, "22222222222 name = %s, pass=%s, right=%d", username, password, right); int len2; char *pch2, *name2; pch2 = strtok(nvram_acc_webdavproxy, "<>"); while(pch2!=NULL){ //- User Name len2 = strlen(pch2); name2 = (char*)malloc(len2+1); strncpy(name2, pch2, len2); name2[len2] = '\0'; //- User Right pch2 = strtok(NULL,"<>"); account_right = atoi(pch2); if( strcmp(username, name2) == 0 ){ free(name2); if(con->smb_info) con->smb_info->auth_right = account_right; //- Copy user name to router_user buffer_copy_string(con->router_user, username); found_account = 1; break; } free(name2); pch2 = strtok(NULL,"<>"); } free(name); free(pass); if(found_account==1) break; } free(name); free(pass); pch = strtok(NULL,"<>"); } free(nvram_acc_list); free(nvram_acc_webdavproxy); return account_right; }
void save_sharelink_list(){ #if EMBEDDED_EANBLE share_link_info_t* c; buffer* sharelink_list = buffer_init(); buffer_copy_string(sharelink_list, ""); for (c = share_link_info_list; c; c = c->next) { if(c->toshare == 0) continue; buffer* temp = buffer_init(); buffer_copy_string_buffer(temp, c->shortpath); buffer_append_string(temp, "<"); buffer_append_string_buffer(temp, c->realpath); buffer_append_string(temp, "<"); buffer_append_string_buffer(temp, c->filename); buffer_append_string(temp, "<"); buffer_append_string_buffer(temp, c->auth); buffer_append_string(temp, "<"); char strTime[25] = {0}; sprintf(strTime, "%lu", c->expiretime); buffer_append_string(temp, strTime); buffer_append_string(temp, "<"); char strTime2[25] = {0}; sprintf(strTime2, "%lu", c->createtime); buffer_append_string(temp, strTime2); buffer_append_string(temp, ">"); buffer_append_string_buffer(sharelink_list, temp); buffer_free(temp); } nvram_set_sharelink_str(sharelink_list->ptr); buffer_free(sharelink_list); #else unlink(g_temp_sharelink_file); smb_srv_info_t* c; char mybuffer[100]; FILE* fp = fopen(g_temp_sharelink_file, "w"); if(fp!=NULL){ share_link_info_t* c; for (c = share_link_info_list; c; c = c->next) { if(c->toshare == 0) continue; fprintf(fp, "%s<%s<%s<%s<%lu<%lu\n", c->shortpath->ptr, c->realpath->ptr, c->filename->ptr, c->auth->ptr, c->expiretime, c->createtime); } fclose(fp); } #endif }
int smbc_aidisk_account_authentication(connection* con, const char *username, const char *password){ char *nvram_acc_list; int st_samba_mode = 1; if (con->mode != SMB_BASIC&&con->mode != DIRECT) return -1; #if EMBEDDED_EANBLE char *a = nvram_get_acc_list(); if(a==NULL) return -1; int l = strlen(a); nvram_acc_list = (char*)malloc(l+1); strncpy(nvram_acc_list, a, l); nvram_acc_list[l] = '\0'; st_samba_mode = nvram_get_st_samba_mode(); #else int i = 100; nvram_acc_list = (char*)malloc(100); strcpy(nvram_acc_list, "admin<admin>jerry<jerry"); #endif int account_right = -1; //- Share All, use guest account if(st_samba_mode==1){ buffer_copy_string(con->aidisk_username, "guest"); buffer_copy_string(con->aidisk_passwd, ""); return 1; } char * pch; pch = strtok(nvram_acc_list, "<>"); while(pch!=NULL){ char *name; char *pass; int len; //- User Name len = strlen(pch); name = (char*)malloc(len+1); strncpy(name, pch, len); name[len] = '\0'; //- User Password pch = strtok(NULL,"<>"); len = strlen(pch); pass = (char*)malloc(len+1); strncpy(pass, pch, len); pass[len] = '\0'; if( strcmp(username, name) == 0 && strcmp(password, pass) == 0 ){ buffer_copy_string(con->aidisk_username, username); buffer_copy_string(con->aidisk_passwd, password); account_right = 1; free(name); free(pass); break; } free(name); free(pass); pch = strtok(NULL,"<>"); } free(nvram_acc_list); return account_right; }