├── .github ├── FUNDING.yml └── workflows │ ├── check.yml │ └── scan-build.yml ├── .gitignore ├── CHANGELOG ├── CODE_OF_CONDUCT.md ├── COPYING ├── Credits ├── Makefile.am ├── README.md ├── SECURITY ├── TODOlist ├── auth.c ├── auth.h ├── auth.py ├── base64.c ├── base64.h ├── buffered_reader.c ├── buffered_reader.h ├── cachedir.c ├── cachedir.h ├── cgi.c ├── cgi.h ├── configuration.c ├── configuration.h ├── configure.ac ├── daemon ├── weborf ├── weborf-generator ├── weborf.service ├── weborf@.service └── weborf_launcher ├── debian ├── NEWS ├── changelog ├── clean ├── control ├── copyright ├── patches │ └── series ├── rules ├── source │ └── format ├── tests │ └── control ├── upstream │ ├── metadata │ └── signing-key.asc ├── watch ├── weborf-daemon.install ├── weborf.examples ├── weborf.install └── weborf.lintian-overrides ├── do_debian ├── embedded_auth.h ├── examples ├── auth.py ├── index.py ├── weborf_auth.c ├── weborf_auth.service ├── weborf_auth_dav.c └── xinetd.conf ├── instance.c ├── instance.h ├── listener.c ├── listener.h ├── manage ├── mime.c ├── mime.h ├── myio.c ├── myio.h ├── mynet.c ├── mynet.h ├── mystring.c ├── mystring.h ├── options.h.in ├── queue.c ├── queue.h ├── qweborf ├── .gitignore ├── Makefile ├── integration │ ├── qweborf.desktop │ ├── qweborf.metainfo.xml │ ├── qweborf.png │ └── qweborf_servicemenu.desktop ├── man │ └── qweborf.1 ├── mypy.conf ├── qweborf │ ├── __init__.py │ ├── __main__.py │ ├── main.ui │ ├── nhelper.py │ ├── qweborf │ ├── qweborf.py │ └── whelper.py └── setup.py ├── testsuite ├── cachedir ├── cert │ ├── certificate.pem │ └── key.pem ├── cgi ├── etag ├── functions.sh ├── index_file ├── ip_listener ├── range ├── site1 │ ├── cgi.py │ ├── empty │ ├── robots.txt │ ├── sub1 │ │ ├── index.dat │ │ └── index.txt │ └── sub2 │ │ └── index.dat ├── site1http ├── site1https ├── site1mimetype ├── site2 │ └── site2.txt ├── version_and_help └── vhost ├── types.h ├── utils.c ├── utils.h ├── webdav.c ├── webdav.h ├── weborf.1 ├── weborf.conf └── weborf.conf.5 /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | liberapay: ltworf 2 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: make check 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: autoreconf 12 | run: autoreconf -f -i 13 | - name: configure 14 | run: ./configure 15 | - name: weborf tests 16 | run: make check || (cat test-suite.log; false) 17 | -------------------------------------------------------------------------------- /.github/workflows/scan-build.yml: -------------------------------------------------------------------------------- 1 | name: clang scan build check 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: install scan build 11 | run: sudo apt-get -y install clang-tools 12 | - name: autoreconf 13 | run: autoreconf -f -i 14 | - name: configure 15 | run: ./configure 16 | - name: scan build 17 | run: scan-build --status-bugs gcc -c *.c 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *-swp 2 | *.o 3 | weborf 4 | config.h.in 5 | *~ 6 | *.pyc 7 | configure 8 | config.h 9 | config.log 10 | config.status 11 | stamp-h1 12 | Makefile.in 13 | .deps 14 | options.h 15 | build-aux 16 | aclocal.m4 17 | autom4te.cache 18 | qweborf/main.py 19 | weborf.kdev4 20 | .kdev4/ 21 | Makefile 22 | *.log 23 | *.trs 24 | deb-pkg/ 25 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | International code of conduct 2 | ============================= 3 | 4 | No USA cultural imperialism allowed 5 | ----------------------------------- 6 | 7 | This project welcomes every contributor from any background. For this reason we can't let the USA and USA influenced politically correct culture dictate conduct for everyone. Diversity is beautiful, let's not ask of people to forgo their culture to contribute. 8 | 9 | Achieving social justice is important. Being superficial about it only to feel morally superior is not the way to achieve it and is not tolerated here. 10 | 11 | 12 | The code of conduct only pertains this project 13 | ---------------------------------------------- 14 | 15 | This document only applies to the project and the communication channels. 16 | 17 | It does not apply to anything any contributor might say or do outside of project channels. 18 | 19 | It only applies to contributors. People whose only contribution is a code of conduct complaint are not contributors. 20 | 21 | 22 | Language 23 | -------- 24 | 25 | Try to be nice and constructive. 26 | 27 | Harassing and intentionally offending other people is not allowed. 28 | 29 | Foul language is allowed. 30 | 31 | People often contribute to this project in their own time and are not paid, for this reason asking contributors to behave "professionally" makes no sense. Hobbies do not require professionality. 32 | 33 | Jokes are allowed. 34 | 35 | It can happen to unintentionally offend someone. Do not reiterate the offensive behaviour, provided that the request is reasonable. 36 | 37 | People who are easily offended by things not intended to be offensive must try to become more tolerant towards other people, other cultures and their ways of expressing themselves. 38 | 39 | For example, a person might consider offensive the sight of a woman with or without a headscarf. This person needs to try to become more tolerant to other people's culture. 40 | 41 | It is not allowed to be offended on behalf of others. Please do not presume to know what others are thinking. 42 | 43 | Examples of allowed language: 44 | 45 | * This software is retarded 46 | * This program runs like shit 47 | * This bug is annoying 48 | 49 | Examples of disallowed language: 50 | 51 | * You are retarded 52 | * You are shitty and so is your program 53 | 54 | 55 | Skill discrimination is absolutely fine 56 | --------------------------------------- 57 | 58 | Unlike other code of conducts, this allows skill discrimination. 59 | 60 | Everyone is welcome to contribute according to their skill level and more experienced contributors are encouraged to act as mentors. 61 | 62 | It is nice if they have time and patience to mentor potential contributors, but since time is a limited resource, it is also fine to turn down low quality and low effort contributions with little explaination. 63 | 64 | New contributors are expected to respond to comments and be willing to improve the quality of their contribution. 65 | 66 | Conflict resolution 67 | ------------------- 68 | 69 | This code of conduct is inevitably vague. Follow the intention rather than the letter. 70 | 71 | The final word rests with the project owners or their delegates. 72 | 73 | 74 | Changes to license 75 | ------------------ 76 | 77 | It is not allowed to ask for license change and complain about copyleft. 78 | 79 | If you disagree with the license, feel free to start your own project from scratch without getting in touch and never look at the source code, to avoid copyright issues. 80 | 81 | See also 82 | -------- 83 | 84 | * International code of conduct: https://github.com/ltworf/international_code_of_conduct 85 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright © 2007-2018 Salvo "LtWorf" Tomaselli , 2 | Copyright © 2007 Salvo Rinaldi 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | 17 | On Debian systems, the complete text of the GNU General Public License 18 | can be found in the /usr/share/common-licenses/GPL-3 file. 19 | 20 | Additional permission under GNU GPL version 3 section 7 21 | 22 | If you modify this Program, or any covered work, by linking or 23 | combining it with OpenSSL (or a modified version of that library), 24 | containing parts covered by the terms of OpenSSL License, the 25 | licensors of this Program grant you additional permission to 26 | convey the resulting work. Corresponding Source for a non-source 27 | form of such a combination shall include the source code for the 28 | parts of OpenSSL used as well as that of the covered work. 29 | -------------------------------------------------------------------------------- /Credits: -------------------------------------------------------------------------------- 1 | Angelo Puglisi, for fixing a warning and founding and fixing a buffer overflow 2 | Simone Veneziano, for improving performaces of a string function 3 | Prof. Giuseppe Pappalardo for the Synchronized queue 4 | Salvo Rinaldi for handling non pipelined connections and sending content length 5 | David Paleino and Enrico Zini for sponsoring the debian package and helping improving it 6 | David Paleino (once again) for the autotool stuff 7 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | #SUBDIRS = 2 | 3 | bin_PROGRAMS = weborf 4 | weborf_SOURCES = \ 5 | auth.c \ 6 | base64.c \ 7 | buffered_reader.c \ 8 | cachedir.c \ 9 | cgi.c \ 10 | configuration.c \ 11 | instance.c \ 12 | listener.c \ 13 | mime.c \ 14 | myio.c \ 15 | mynet.c \ 16 | mystring.c \ 17 | queue.c \ 18 | utils.c \ 19 | webdav.c 20 | 21 | EXTRA_DIST = \ 22 | auth.h \ 23 | buffered_reader.h \ 24 | cgi.h \ 25 | configuration.h \ 26 | instance.h \ 27 | mime.h \ 28 | mynet.h \ 29 | types.h \ 30 | webdav.h \ 31 | base64.h \ 32 | cachedir.h \ 33 | embedded_auth.h \ 34 | listener.h \ 35 | myio.h \ 36 | mystring.h \ 37 | queue.h \ 38 | utils.h \ 39 | examples \ 40 | daemon \ 41 | weborf.conf \ 42 | testsuite/* \ 43 | qweborf/qweborf/__init__.py \ 44 | qweborf/qweborf/main.ui \ 45 | qweborf/qweborf/nhelper.py \ 46 | qweborf/qweborf/whelper.py \ 47 | qweborf/qweborf/qweborf.py \ 48 | qweborf/qweborf/qweborf \ 49 | qweborf/man/qweborf.1 \ 50 | qweborf/integration/qweborf.png \ 51 | qweborf/integration/qweborf.desktop \ 52 | qweborf/integration/qweborf_servicemenu.desktop \ 53 | qweborf/integration/qweborf.metainfo.xml \ 54 | qweborf/setup.py \ 55 | qweborf/Makefile 56 | 57 | dist-hook: 58 | rm -rf `find $(distdir)/ -name .git` 59 | 60 | install-data-local: 61 | install -d echo $(DESTDIR)/etc/weborf.d 62 | ln -s ../weborf.conf $(DESTDIR)/etc/weborf.d/weborf.conf 63 | install -D -m644 daemon/weborf.service $(DESTDIR)/lib/systemd/system/weborf.service 64 | install -D -m644 daemon/weborf@.service $(DESTDIR)/lib/systemd/system/weborf@.service 65 | install -D daemon/weborf-generator $(DESTDIR)/lib/systemd/system-generators/weborf-generator 66 | 67 | install-data-hook: 68 | chmod a+x $(DESTDIR)$(datadir)/weborf/weborf_launcher 69 | 70 | dist_man_MANS = weborf.1 weborf.conf.5 71 | 72 | init_SCRIPTS = daemon/weborf 73 | 74 | pkgdata_DATA = daemon/weborf_launcher 75 | 76 | sysconf_DATA = weborf.conf 77 | 78 | dist_doc_DATA = \ 79 | CHANGELOG \ 80 | Credits \ 81 | README.md \ 82 | TODOlist 83 | 84 | TESTS = \ 85 | testsuite/version_and_help \ 86 | testsuite/site1http \ 87 | testsuite/site1https \ 88 | testsuite/ip_listener \ 89 | testsuite/etag \ 90 | testsuite/index_file \ 91 | testsuite/range \ 92 | testsuite/cgi \ 93 | testsuite/cachedir \ 94 | testsuite/site1mimetype \ 95 | testsuite/vhost \ 96 | testsuite/functions.sh 97 | 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PROJECT MOVED 2 | ============= 3 | 4 | [This project moved here](https://codeberg.org/ltworf/weborf/) 5 | 6 | 7 | User friendly webserver 8 | 9 | qweborf 10 | ======= 11 | Provides a GUI to share local files. 12 | 13 | It can do NAT traversal to share files outside of the local network. 14 | 15 | Can enable authentication and sending directories as `.tar.gz` files. 16 | 17 | 18 | weborf 19 | ====== 20 | The web server used by qweborf. 21 | 22 | Can be used from inetd, supports WebDAV, caching, CGI, virtual hosts. 23 | 24 | 25 | Compile 26 | ======= 27 | 28 | These are the steps to compile weborf. 29 | 30 | ``` 31 | autoreconf -f -i # Only if you cloned from git 32 | 33 | make clean 34 | ./configure 35 | make 36 | ``` 37 | 38 | To compile qweborf. 39 | 40 | ``` 41 | pyuic5 qweborf/main.ui > qweborf/main.py 42 | ``` 43 | Run 44 | === 45 | ``` 46 | ./weborf 47 | ``` 48 | 49 | 50 | qweborf: will look for weborf in the PATH. 51 | ``` 52 | python3 -m qweborf 53 | ``` 54 | -------------------------------------------------------------------------------- /SECURITY: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Only the latest release is supported. I will not backport fixes. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | Contact me at tiposchi@tiscali.it 10 | 11 | My PGP key is on this file, on git. 12 | debian/upstream/signing-key.asc 13 | -------------------------------------------------------------------------------- /TODOlist: -------------------------------------------------------------------------------- 1 | - Allow external script for modurl, must have the headers... 2 | - use openSSL (instead of using read and write, use wrappers so openssl or direct accesso to socket can be used) 3 | - Create a Doxyfile to use doxygen -------------------------------------------------------------------------------- /auth.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "types.h" 32 | #include "auth.h" 33 | #include "instance.h" 34 | #include "base64.h" 35 | 36 | extern weborf_configuration_t weborf_conf; 37 | 38 | #include "embedded_auth.h" 39 | 40 | /** 41 | Checks that the authentication socket exists and is a unix socket 42 | */ 43 | void auth_set_socket(char *u_socket) { 44 | #ifdef EMBEDDED_AUTH 45 | weborf_conf.authsock = "embedded"; 46 | #else 47 | struct stat sb; 48 | if (stat(u_socket, &sb) == -1) { 49 | perror("Existing unix socket expected"); 50 | #ifdef SERVERDBG 51 | syslog(LOG_ERR, "%s doesn't exist", u_socket); 52 | #endif 53 | exit(5); 54 | } 55 | 56 | if ((sb.st_mode & S_IFMT) != S_IFSOCK) { 57 | #ifdef SERVERDBG 58 | syslog(LOG_ERR, "%s is not a socket", u_socket); 59 | #endif 60 | dprintf(2, "Socket expected\n"); 61 | exit(5); 62 | } 63 | 64 | 65 | weborf_conf.authsock = u_socket; 66 | #endif 67 | } 68 | 69 | /** 70 | This function checks if the authentication can be granted or not calling the external program. 71 | Returns 0 if authorization is granted. 72 | */ 73 | int auth_check_request(connection_t *connection_prop) { 74 | if (weborf_conf.authsock==NULL) return 0; 75 | 76 | char username[PWDLIMIT*2]; 77 | char* password=username; //will be changed if there is a password 78 | 79 | char* auth=strstr(connection_prop->http_param,"Authorization: Basic ");//Locates the auth information 80 | if (auth==NULL) { //No auth informations 81 | username[0]=0; 82 | //password[0]=0; 83 | } else { //Retrieves provided username and password 84 | char*auth_end=strstr(auth,"\r\n");//Finds the end of the header 85 | if (auth_end==NULL) return -1; 86 | char a[PWDLIMIT*2]; 87 | auth+=21;//Moves the begin of the string to exclude Authorization: Basic 88 | if ((auth_end-auth+1)<(PWDLIMIT*2)) 89 | memcpy(&a,auth,auth_end-auth); //Copies the base64 encoded string to a temp buffer 90 | else { //Auth string is too long for the buffer 91 | #ifdef SERVERDBG 92 | syslog(LOG_ERR,"Unable to accept authentication, buffer is too small"); 93 | #endif 94 | return ERR_NOMEM; 95 | } 96 | 97 | a[auth_end-auth]=0; 98 | decode64(username,a);//Decodes the base64 string 99 | 100 | password=strstr(username,":");//Locates the separator : 101 | if (password==NULL) return -1; 102 | password[0]=0;//Nulls the separator to split username and password 103 | password++;//make password point to the beginning of the password 104 | } 105 | 106 | int result=-1; 107 | 108 | #ifdef EMBEDDED_AUTH 109 | result=c_auth(connection_prop->page, 110 | connection_prop->ip_addr, 111 | connection_prop->method, 112 | username, 113 | password, 114 | connection_prop->http_param); 115 | #else 116 | { 117 | int s,len; 118 | struct sockaddr_un remote; 119 | s=socket(AF_UNIX,SOCK_STREAM,0); 120 | 121 | remote.sun_family = AF_UNIX; 122 | strcpy(remote.sun_path, weborf_conf.authsock); 123 | len = strlen(remote.sun_path) + sizeof(remote.sun_family); 124 | if (connect(s, (struct sockaddr *)&remote, len) == -1) {//Unable to connect 125 | return -1; 126 | } 127 | char* auth_str=malloc(HEADBUF+PWDLIMIT*2); 128 | if (auth_str==NULL) { 129 | #ifdef SERVERDBG 130 | syslog(LOG_CRIT,"Not enough memory to allocate buffers"); 131 | #endif 132 | return -1; 133 | } 134 | 135 | int auth_str_l=snprintf(auth_str,HEADBUF+PWDLIMIT*2,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n",connection_prop->page,connection_prop->ip_addr,connection_prop->method,username,password,connection_prop->http_param); 136 | if (write(s,auth_str,auth_str_l)==auth_str_l && read(s,auth_str,1)==0) {//All data written and no output, ok 137 | result=0; 138 | } 139 | 140 | close(s); 141 | free(auth_str); 142 | } 143 | #endif 144 | 145 | return result; 146 | } 147 | -------------------------------------------------------------------------------- /auth.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_AUTH_H 22 | #define WEBORF_AUTH_H 23 | 24 | #include "types.h" 25 | #include "options.h" 26 | 27 | void auth_set_socket(char *u_socket); 28 | int auth_check_request(connection_t* connection_prop); 29 | 30 | #endif -------------------------------------------------------------------------------- /auth.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Auth script 4 | # Copyright (C) 2008 Salvo "LtWorf" Tomaselli 5 | # 6 | # Relation is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | # 19 | # author Salvo "LtWorf" Tomaselli 20 | 21 | # This is an example authentication script. You can modify it to make it fit your needs 22 | import socket,os 23 | 24 | s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 25 | try: 26 | os.remove("/tmp/weborf_auth.socket") 27 | except OSError: 28 | pass 29 | s.bind("/tmp/weborf_auth.socket") 30 | s.listen(1) 31 | while 1: 32 | conn, addr = s.accept() 33 | data = conn.recv(4096).split('\r\n') 34 | #print data 35 | conn.close() 36 | -------------------------------------------------------------------------------- /base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007-2016 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | #include 23 | #include 24 | #include "base64.h" 25 | 26 | /** 27 | Returns the base64 (6bit) code of a char 28 | */ 29 | static char getCode(char c) { 30 | if ('A' <=c && c<='Z') { 31 | return c-'A'; 32 | } else if ('a' <=c && c<='z') { 33 | return c-'a'+26; 34 | } else if ('0' <=c && c<='9') { 35 | return c-'0'+52; 36 | } else if (c=='+') 37 | return 62; 38 | else if(c=='/') 39 | return 63; 40 | return 0; 41 | } 42 | 43 | /** 44 | Decodes a group of 4 characters and put 3 resulting chars in res 45 | res buffer must be able to contain 3 bytes. 46 | */ 47 | void decode4_64(char *res, char *group) { 48 | 49 | ///////CALCULATE CHAR 0 50 | res[0] = getCode(group[0]) << 2; 51 | 52 | char t = getCode(group[1]); 53 | char t1 = t; 54 | 55 | t >>= 4; 56 | res[0] = res[0] | t; //Completed 1st char 57 | 58 | ///////CALCULATE CHAR 1 59 | res[1] = t1 << 4; 60 | 61 | t = getCode(group[2]); 62 | t1 = t; 63 | 64 | res[1] = res[1] | (t >> 2); 65 | 66 | //CALCULATE CHAR 2 67 | res[2] = t1 << 6; 68 | t = getCode(group[3]); 69 | 70 | res[2] = res[2] | t; 71 | } 72 | 73 | /** 74 | Decodes a base64 string, putting the result inside the result buffer. 75 | Terminates with a \0 the buffer, so string functions can be used on the result. 76 | Doesn't change the encoded string. 77 | result's length must be at least: (strlen(encoded) /4 *3 )+1 78 | */ 79 | void decode64(char *result, char *encoded) { 80 | char *res = result; 81 | 82 | while (encoded[0] != 0) { 83 | decode4_64(res, encoded); 84 | encoded += 4; 85 | res += 3; 86 | res[0] = 0; 87 | 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_BASE64_H 22 | #define WEBORF_BASE64_H 23 | 24 | void decode64(char *result, char *encoded); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /buffered_reader.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2009-2018 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "buffered_reader.h" 28 | #include "myio.h" 29 | 30 | /** 31 | This funcion inits the struct allocating a buffer of the specified size. 32 | It will return 0 on success and 1 on fail. 33 | */ 34 | int buffer_init(buffered_read_t* buf, ssize_t size) 35 | { 36 | buf->buffer = malloc(sizeof(char) * size); 37 | buf->size = size; 38 | buffer_reset(buf); 39 | return (buf->buffer == NULL) ? 1 : 0; 40 | } 41 | 42 | /** 43 | Resets the pointers, so the buffer is ready for new reads on new 44 | file descriptor 45 | */ 46 | void buffer_reset (buffered_read_t * buf) { 47 | buf->end = buf->start = buf->buffer; 48 | } 49 | 50 | /** 51 | This function will free the memory allocated by the buffer used in the struct. 52 | */ 53 | void buffer_free(buffered_read_t * buf) { 54 | free(buf->buffer); 55 | } 56 | 57 | static ssize_t buffer_fill(fd_t fd, buffered_read_t * buf) { 58 | ssize_t r; 59 | 60 | buf->start = buf->buffer; 61 | 62 | //Timeout implementation 63 | struct pollfd monitor[1]; 64 | monitor[0].fd = myio_getfd(fd); //File descriptor to monitor 65 | monitor[0].events = POLLIN; //Monitor on input events 66 | 67 | //Waits the timeout or reads the data. 68 | //If timeout is reached and no input is available 69 | //will behave like the stream is closed. 70 | if (poll(monitor, 1, READ_TIMEOUT) == 0) { 71 | r = 0; 72 | } else { 73 | r = myio_read(fd, buf->buffer, buf->size); 74 | } 75 | 76 | if (r <= 0) { //End of the stream 77 | buf->end = buf->start; 78 | } else { 79 | buf->end = buf->start + r; 80 | } 81 | 82 | return r; 83 | } 84 | 85 | /** 86 | This function is designed to be similar to a normal read, but it uses an internal 87 | buffer. 88 | When the buffer is empty, it will try to fill it. 89 | An important difference from the normal read is that this function will wait until 90 | the requested amount of bytes are available, or until the timeout occurs. 91 | Timeout duration is defined with the READ_TIMEOUT define. 92 | On some special cases, the read data could be less than the requested one. For example if 93 | end of file is reached and it is impossible to do further reads. 94 | */ 95 | ssize_t buffer_read(fd_t fd, void *b, ssize_t count, buffered_read_t * buf) { 96 | ssize_t wrote = 0; //Count of written bytes 97 | ssize_t available, needed; //Available bytes in buffer, and requested bytes remaining 98 | 99 | 100 | while (wrote < count) { 101 | available = buf->end - buf->start; 102 | needed = count - wrote; 103 | 104 | if (needed <= available) { //More data in buffer than needed 105 | memcpy(b, buf->start, needed); 106 | buf->start += needed; 107 | return wrote + needed; 108 | } else { //Requesting more data than available 109 | if (available > 0) {//Empty the remaining data in the buffer 110 | memcpy(b, buf->start, available); 111 | b += available; 112 | wrote += available; 113 | } 114 | //Filing the buffer again 115 | if (buffer_fill(fd,buf) <= 0) { //End of the stream 116 | return wrote; 117 | } 118 | } 119 | 120 | } /*while */ 121 | return wrote; 122 | } 123 | 124 | 125 | /** 126 | * This function returns how many bytes must be read in order to 127 | * read enough data for it to end with the string needle. 128 | * strlen(needle) must be added to the returned value to include the 129 | * needle string in the result of the read. 130 | * 131 | * If the string needle is not in the buffer then the entire size 132 | * of the data present in cache will be return. 133 | * */ 134 | size_t buffer_strstr(fd_t fd, buffered_read_t * buf, char * needle) { 135 | if (buf->end - buf->start==0) { 136 | buffer_fill(fd,buf); 137 | } 138 | 139 | buf->end[0]=0; 140 | char *r=strstr(buf->start,needle); 141 | 142 | if (r==NULL) { 143 | return buf->end - buf->start; 144 | } else { 145 | return r-buf->start; 146 | 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /buffered_reader.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2009-2018 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #ifndef BUFFERED_READER_H 21 | #define BUFFERED_READER_H 22 | 23 | #include 24 | #include 25 | 26 | #include "types.h" 27 | 28 | typedef struct { 29 | char *buffer; //Buffer where the reader stores the read data 30 | char *start; //Pointer to non-consumed data 31 | char *end; //Pointer to 1st byte after end of the data. A read must continue after end. 32 | int size; //Size of the buffer 33 | } buffered_read_t; 34 | 35 | void buffer_reset (buffered_read_t * buf); 36 | int buffer_init(buffered_read_t * buf, ssize_t size); 37 | void buffer_free(buffered_read_t * buf); 38 | ssize_t buffer_read(fd_t fd, void *b, ssize_t count, buffered_read_t * buf); 39 | size_t buffer_strstr(fd_t fd, buffered_read_t * buf, char * needle); 40 | #endif 41 | -------------------------------------------------------------------------------- /cachedir.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2020 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "cachedir.h" 33 | #include "utils.h" 34 | #include "types.h" 35 | #include "instance.h" 36 | 37 | 38 | char *cachedir=NULL; 39 | 40 | /** 41 | Generates the filename for the cached entity and stores it in the buffer 42 | */ 43 | static inline void cached_filename(unsigned int uprefix,connection_t *connection_prop, char *buffer) { 44 | snprintf(buffer,PATH_LEN,"%s/%u-%llu-%llu-%ld",cachedir,uprefix,(unsigned long long int)connection_prop->strfile_stat.st_ino,(unsigned long long int)connection_prop->strfile_stat.st_dev,connection_prop->strfile_stat.st_mtime); 45 | } 46 | 47 | /** 48 | Returns true if the caching is enabled and 49 | false otherwise 50 | */ 51 | bool cache_is_enabled() { 52 | return cachedir != NULL; 53 | } 54 | 55 | /** 56 | Sends a cached item if present and returns true. 57 | Returns false on cache miss. 58 | */ 59 | bool cache_send_item(unsigned int uprefix,connection_t* connection_prop) {//Try to send the cached file instead 60 | int cachedfd=cache_get_item_fd(uprefix,connection_prop); 61 | 62 | if (cachedfd==-1) 63 | return false; 64 | 65 | int oldfd=connection_prop->strfile_fd; 66 | connection_prop->strfile_fd=cachedfd; 67 | 68 | /* 69 | replaces the stat of the directory with the stat of the cached file 70 | it is safe here since get_cached_item has already been executed 71 | */ 72 | fstat(connection_prop->strfile_fd, &connection_prop->strfile_stat); 73 | 74 | write_file(connection_prop); 75 | 76 | //Restore file descriptor so it can be closed later 77 | connection_prop->strfile_fd=oldfd; 78 | 79 | //Closes the cache file descriptor 80 | close(cachedfd); 81 | 82 | return true; 83 | } 84 | 85 | /** 86 | 87 | This function returns the file descriptor to the file containing the cached 88 | item. 89 | 90 | If a cache miss occurs -1 will be returned 91 | If cache is not in use (cache_init was not called) it will always return -1 92 | 93 | uprefix is an integer that must be unique for each call of get_cached_dir. 94 | Its purpose is to distinguish between calls that will eventually generate an 95 | HTML file and calls that will generate XML or other data. 96 | So the directory would be the same but the generated content is different. 97 | 98 | Acquires a shared lock on the file, so if the file is already opened in write mode 99 | the lock will fail and the function will return the same result of a cache miss. 100 | */ 101 | int cache_get_item_fd(unsigned int uprefix,connection_t* connection_prop) { 102 | if (!cachedir) return -1; 103 | 104 | char fname[PATH_LEN]; 105 | 106 | //Get the filename 107 | cached_filename(uprefix,connection_prop,fname); 108 | 109 | int fd=open(fname,O_RDONLY); 110 | if (fd==-1) return -1; //Cache miss 111 | 112 | //Acquire lock on the file and return the file descriptor 113 | if (flock(fd,LOCK_SH|LOCK_NB)==0) 114 | return fd; 115 | 116 | //Lock could not be acquired 117 | close(fd); 118 | return -1; 119 | } 120 | 121 | 122 | /** 123 | Same as cache_get_item_fd but here the file is created and opened for 124 | reading and writing, and will be created if it doesn't exist 125 | 126 | An exclusive lock will be acquired over the file, since it is being opened 127 | for writing too. 128 | */ 129 | int cache_get_item_fd_wr(unsigned int uprefix,connection_t *connection_prop) { 130 | if (!cachedir) return -1; 131 | 132 | char fname[PATH_LEN]; 133 | 134 | //Get the filename 135 | cached_filename(uprefix,connection_prop,fname); 136 | 137 | int fd = open(fname,O_RDWR| O_CREAT,S_IRUSR|S_IWUSR); 138 | 139 | //Acquire the exclusive lock in a non-blocking way 140 | if (flock(fd,LOCK_EX|LOCK_NB)==0) { 141 | return fd; 142 | } 143 | close(fd); 144 | return -1; 145 | 146 | } 147 | 148 | /** 149 | Stores the content of the buffer "content" in cache, for the size specified by content_len 150 | The cache file will have an exclusive lock to prevent multiple threads accessing the same file 151 | in write mode. 152 | 153 | Lock is acquired in a non-blocking way, so if the file is already locked the method will just return 154 | without writing anything on the file. This behavior is wanted because it is assumed that the lock is held 155 | by another thread writing the same content on the file, waiting for the lock to be released would lead to 156 | override the content of the file with the same content. 157 | */ 158 | void cache_store_item(unsigned int uprefix,connection_t* connection_prop, char *content, size_t content_len) { 159 | if (!cachedir) return; 160 | 161 | char fname[PATH_LEN]; 162 | cached_filename(uprefix,connection_prop,fname); 163 | 164 | int fd=open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 165 | 166 | if (fd == -1) return; //Just do nothing in case of error 167 | 168 | //Try to acquire lock in a non-blocking way, and exit if another thread has that lock 169 | if (flock(fd,LOCK_EX|LOCK_NB)!=0) { 170 | close(fd); 171 | return; 172 | } 173 | 174 | if (write(fd, content, content_len) != content_len) 175 | unlink(fname); 176 | close(fd); 177 | return; 178 | } 179 | 180 | 181 | 182 | /** 183 | This function initializes a cache directory. 184 | If the dir is not a directory or it is impossible to stat 185 | weborf will terminate. 186 | If it is impossible to delete and create files in it, weborf 187 | will just log a warning. 188 | */ 189 | void cache_init(char* dir) { 190 | cachedir=dir; 191 | 192 | { 193 | //Check if it exists 194 | struct stat stat_buf; 195 | if (stat(dir, &stat_buf)!=0) { 196 | dprintf(2, "Unable to stat cache directory\n"); 197 | #ifdef SERVERDBG 198 | syslog(LOG_ERR,"Unable to stat cache directory"); 199 | #endif 200 | exit(10); 201 | } 202 | 203 | //Check it is a directory 204 | if (!S_ISDIR(stat_buf.st_mode)) { 205 | dprintf(2, "--cache parameter must be a directory\n"); 206 | #ifdef SERVERDBG 207 | syslog(LOG_ERR,"--cache parameter must be a directory"); 208 | #endif 209 | exit(10); 210 | } 211 | } 212 | 213 | //check we have permissions 214 | if (access(dir,W_OK|R_OK)!=0) { 215 | dprintf(2,"no read or write permissions on cache dir\n"); 216 | #ifdef SERVERDBG 217 | syslog(LOG_ERR,"no read or write permissions on cache dir"); 218 | #endif 219 | exit(10); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /cachedir.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2020 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_CACHEDIR_H 22 | #define WEBORF_CACHEDIR_H 23 | 24 | 25 | #include "types.h" 26 | 27 | bool cache_send_item(unsigned int uprefix,connection_t* connection_prop); 28 | int cache_get_item_fd(unsigned int uprefix,connection_t* connection_prop); 29 | int cache_get_item_fd_wr(unsigned int uprefix,connection_t *connection_prop); 30 | void cache_store_item(unsigned int uprefix,connection_t* connection_prop, char *content, size_t content_len); 31 | void cache_init(char *dir); 32 | bool cache_is_enabled(); 33 | 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /cgi.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2018 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_CGI_H 22 | #define WEBORF_CGI_H 23 | 24 | 25 | #include "options.h" 26 | #include "types.h" 27 | 28 | int exec_page(char * executor,string_t* post_param,char* real_basedir,connection_t* connection_prop); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /configuration.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2019 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef HAVE_LIBSSL 31 | #include 32 | #include 33 | #endif 34 | 35 | #include "configuration.h" 36 | #include "types.h" 37 | #include "utils.h" 38 | #include "cachedir.h" 39 | #include "auth.h" 40 | 41 | weborf_configuration_t weborf_conf = { 42 | .tar_directory=false, 43 | .is_inetd=false, 44 | .virtual_host = false, 45 | .exec_script = false, 46 | .ip = NULL, 47 | .port = PORT, 48 | .basedir=BASEDIR, 49 | .uid = ROOTUID, 50 | .gid = ROOTGID, 51 | .daemonize = false, 52 | #ifdef HAVE_LIBSSL 53 | .sslctx = NULL, 54 | #endif 55 | 56 | #ifdef SEND_MIMETYPES 57 | .send_content_type = false, 58 | #endif 59 | }; 60 | 61 | /** 62 | * Enables sending mime types in response to GET requests 63 | * or prints an error and exits if the support was not 64 | * compiled 65 | * */ 66 | static void configuration_enable_sending_mime() { 67 | #ifdef SEND_MIMETYPES 68 | weborf_conf.send_content_type=true; 69 | #else 70 | fprintf(stderr, "Support for MIME is not available\n"); 71 | syslog(LOG_ERR, "Support for MIME is not available\n"); 72 | exit(19); 73 | #endif 74 | } 75 | 76 | 77 | /** 78 | Sets the base dir, making sure that it is really a directory. 79 | */ 80 | static void configuration_set_basedir(char * bd) { 81 | struct stat stat_buf; 82 | stat(bd, &stat_buf); 83 | 84 | if (!S_ISDIR(stat_buf.st_mode)) { 85 | //Not a directory 86 | fprintf(stderr, "%s must be a directory\n", bd); 87 | syslog(LOG_ERR, "%s must be a directory\n", bd); 88 | exit(1); 89 | } 90 | weborf_conf.basedir = bd; 91 | } 92 | 93 | /** 94 | * Sets default CGI configuration, 95 | * run .php and .py as CGI 96 | * */ 97 | static void configuration_set_default_CGI() { 98 | weborf_conf.cgi_paths.len = 4; 99 | weborf_conf.cgi_paths.data[0] = ".php"; 100 | weborf_conf.cgi_paths.data[1] = CGI_PHP; 101 | weborf_conf.cgi_paths.data[2] = ".py"; 102 | weborf_conf.cgi_paths.data[3] = CGI_PY; 103 | weborf_conf.cgi_paths.data_l[0] = strlen(".php"); 104 | weborf_conf.cgi_paths.data_l[1] = strlen(CGI_PHP); 105 | weborf_conf.cgi_paths.data_l[2] = strlen(".py"); 106 | weborf_conf.cgi_paths.data_l[3] = strlen(CGI_PY); 107 | } 108 | 109 | /** 110 | * Sets the default index file 111 | * */ 112 | static void configuration_set_default_index() { 113 | weborf_conf.indexes[0] = INDEX; 114 | weborf_conf.indexes_l = 1; 115 | } 116 | 117 | static void configuration_set_cgi(char *optarg) { 118 | if (!optarg || strlen(optarg) == 0) { 119 | weborf_conf.cgi_paths.len = 0; //count of indexes 120 | return; 121 | } 122 | int i = 0; 123 | weborf_conf.cgi_paths.len = 1; //count of indexes 124 | weborf_conf.cgi_paths.data[0] = optarg; //1st one points to begin of param 125 | while (optarg[++i] != 0) { //Reads the string 126 | if (optarg[i] == ',') { 127 | optarg[i] = 0; //Nulling the comma 128 | //Increasing counter and making next item point to char after the comma 129 | weborf_conf.cgi_paths.data[weborf_conf.cgi_paths.len++] = &optarg[i + 1]; 130 | if (weborf_conf.cgi_paths.len == MAXINDEXCOUNT) { 131 | fprintf(stderr, "Too many cgis, change MAXINDEXCOUNT in options.h to allow more\n"); 132 | syslog(LOG_ERR, "Too many cgis, change MAXINDEXCOUNT in options.h to allow more\n"); 133 | exit(6); 134 | } 135 | } 136 | } 137 | 138 | if (weborf_conf.cgi_paths.len % 2 == 1) { 139 | fprintf(stderr, "--cgi components must be an even number\n"); 140 | syslog(LOG_ERR, "--cgi components must be an even number\n"); 141 | exit(6); 142 | } 143 | 144 | for (i=0; i. 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_CONFIGURATION_H 22 | #define WEBORF_CONFIGURATION_H 23 | 24 | #include "types.h" 25 | #include "options.h" 26 | 27 | void configuration_load(int argc, char *argv[]); 28 | 29 | #endif -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([weborf], [1.0], [tiposchi@tiscali.it]) 2 | AC_CONFIG_AUX_DIR([build-aux]) 3 | AC_CONFIG_SRCDIR([queue.c]) 4 | AC_CONFIG_HEADERS([config.h]) 5 | 6 | m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) 7 | AM_INIT_AUTOMAKE([foreign -Wall -Werror]) 8 | AM_MAINTAINER_MODE 9 | 10 | 11 | AC_PROG_CC 12 | 13 | 14 | AC_SUBST([cgibindir], [${libdir}/cgi-bin]) 15 | AC_SUBST([initdir], [${sysconfdir}/init.d]) 16 | 17 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/file.h sys/socket.h syslog.h unistd.h]) 18 | AC_CHECK_FUNCS([alarm inet_ntoa localtime_r memmove memset mkdir putenv rmdir setenv socket strstr strtol strtoul ftruncate strrchr]) 19 | 20 | AC_SYS_LARGEFILE 21 | 22 | 23 | AC_HEADER_STDBOOL 24 | AC_TYPE_OFF_T 25 | AC_TYPE_SIZE_T 26 | AC_TYPE_SSIZE_T 27 | AC_TYPE_UID_T 28 | 29 | AC_FUNC_FORK 30 | AC_FUNC_MALLOC 31 | AC_C_INLINE 32 | 33 | AC_CHECK_LIB([pthread], [pthread_create], , \ 34 | AC_MSG_ERROR([libpthread is needed]) 35 | ) 36 | AC_CHECK_LIB([magic], [magic_load]) 37 | AC_CHECK_LIB([crypto], [RAND_add]) 38 | AC_CHECK_LIB([ssl], [SSL_new]) 39 | 40 | #AC_CONFIG_HEADERS([config.h options.h]) 41 | 42 | AC_CONFIG_FILES([Makefile 43 | options.h 44 | ]) 45 | 46 | 47 | AC_OUTPUT 48 | -------------------------------------------------------------------------------- /daemon/weborf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (C) 2008-2018 Salvo "LtWorf" Tomaselli 3 | # 4 | # Weborf is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | # 17 | # author Salvo "LtWorf" Tomaselli 18 | 19 | 20 | ### BEGIN INIT INFO 21 | # Provides: weborf 22 | # Required-Start: $network $local_fs $syslog $remote_fs 23 | # Required-Stop: $remote_fs 24 | # Should-Start: $named 25 | # Should-Stop: 26 | # Default-Start: 2 3 4 5 27 | # Default-Stop: 0 1 6 28 | # Short-Description: Fast and small webserver 29 | # Description: Weborf is a configurationless webserver mainly meant to allow users 30 | # to easily share their directories over the web. 31 | # It also supports php5-cgi. 32 | ### END INIT INFO 33 | function clear_cache { 34 | CDIR=`cat /etc/weborf.conf | egrep "^cachedir=" | cut -d= -f2` 35 | rm -rf $CDIR/* 36 | } 37 | 38 | function status { 39 | if ! test -e $PIDFILE 40 | then 41 | echo "Weborf doesn't appear to be running" 42 | else 43 | echo "Weborf appears to be running" 44 | fi 45 | } 46 | 47 | function stopWeborf { 48 | #Stops all the running weborf servers (the ones started with init) 49 | 50 | if ! test -e $PIDFILE 51 | then 52 | echo "Weborf is not running or it was not started by init" 53 | exit 0 54 | fi 55 | 56 | echo -n "Stopping weborf " 57 | for i in `cat $PIDFILE` 58 | do 59 | echo -n .. 60 | kill $i 61 | done 62 | echo "done" 63 | rm -f $PIDFILE 64 | } 65 | 66 | function startWeborf { 67 | #This function will start all the needed processes for weborf 68 | if test -e $PIDFILE 69 | then 70 | logger -s -perror "Weborf already running, if you're sure it is not running, delete $PIDFILE" 71 | exit 2 72 | fi 73 | 74 | logger -s "Starting weborf" 75 | nohup /usr/share/weborf/weborf_launcher /etc/weborf.conf >/dev/null 2> /dev/null & 76 | echo ${!} >> $PIDFILE # Writes PID so weborf can be terminated 77 | } 78 | 79 | 80 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 81 | DAEMON=/usr/bin/weborf # Introduce the server's location here 82 | NAME=weborf # Introduce the short server's name here 83 | PIDFILE=/var/run/$NAME.pid 84 | 85 | test -x $DAEMON || exit 0 86 | 87 | . /lib/lsb/init-functions 88 | 89 | # Default options, these can be overriden by the information 90 | # at /etc/default/$NAME 91 | DAEMON_OPTS="" # Additional options given to the server 92 | 93 | DIETIME=3 # Time to wait for the server to die, in seconds 94 | # If this value is set too low you might not 95 | # let some servers to die gracefully and 96 | # 'restart' will not work 97 | 98 | #STARTTIME=2 # Time to wait for the server to start, in seconds 99 | # If this value is set each time the server is 100 | # started (on start or restart) the script will 101 | # stall to try to determine if it is running 102 | # If it is not set and the server takes time 103 | # to setup a pid file the log message might 104 | # be a false positive (says it did not start 105 | # when it actually did) 106 | 107 | case $1 in 108 | start) 109 | startWeborf;; 110 | stop) 111 | stopWeborf;; 112 | restart) 113 | stopWeborf 114 | startWeborf;; 115 | force-reload) 116 | stopWeborf 117 | startWeborf;; 118 | status) 119 | status;; 120 | clearcache) 121 | clear_cache;; 122 | * ) 123 | echo "Usage: $0 {start|stop|restart|force-reload|status|clearcache}";; 124 | esac 125 | -------------------------------------------------------------------------------- /daemon/weborf-generator: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This systemd generator creates dependency symlinks that make all weborf 3 | # instances with start=auto configuration file be started/stopped/reloaded 4 | # when weborf.service is started/stopped/reloaded. 5 | 6 | set -eu 7 | 8 | gendir="$1" 9 | wantdir="$1/weborf.service.wants" 10 | instance="/lib/systemd/system/weborf@.service" 11 | 12 | mkdir -p "$wantdir" 13 | 14 | for conf in /etc/weborf.d/*.conf; do 15 | # abort loop if glob was not expanded (but accept dead symlinks) 16 | if ! test -e "$conf" && ! test -L "$conf"; then continue; fi 17 | 18 | if ! grep "^start=auto$" < $conf > /dev/null; then 19 | continue 20 | fi 21 | ln -s "$instance" "$wantdir/weborf@`basename $conf`.service" 22 | done 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /daemon/weborf.service: -------------------------------------------------------------------------------- 1 | # systemd service for managing all weborf instances on the system. This 2 | # service is actually a systemd target, but we are using a service since 3 | # targets cannot be reloaded. 4 | 5 | [Unit] 6 | Description=Weborf webserver 7 | Documentation=man:weborf.conf(5) 8 | 9 | [Service] 10 | Type=oneshot 11 | ExecStart=/bin/true 12 | ExecReload=/bin/true 13 | RemainAfterExit=on 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /daemon/weborf@.service: -------------------------------------------------------------------------------- 1 | [Install] 2 | WantedBy=multi-user.target 3 | 4 | [Unit] 5 | Description=Weborf webserver with %I 6 | AssertPathExists=/etc/weborf.d/%i 7 | PartOf=weborf.service 8 | ReloadPropagatedFrom=weborf.service 9 | Before=weborf.service 10 | Documentation=man:weborf.conf(5) 11 | 12 | [Service] 13 | PrivateTmp=true 14 | User=root 15 | Type=forking 16 | Restart=always 17 | ExecStart=/usr/share/weborf/weborf_launcher /etc/weborf.d/%i -d 18 | StandardOutput=null 19 | StandardError=null 20 | SyslogIdentifier=weborf-%i 21 | 22 | # Some security tuning 23 | NoNewPrivileges=yes 24 | SystemCallArchitectures=native 25 | PrivateDevices=yes 26 | PrivateTmp=yes 27 | ProtectHome=read-only 28 | ProtectKernelTunables=true 29 | ProtectKernelModules=true 30 | ProtectControlGroups=true 31 | -------------------------------------------------------------------------------- /daemon/weborf_launcher: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (C) 2018-2020 Salvo "LtWorf" Tomaselli 3 | # 4 | # Weborf is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | # 17 | # author Salvo "LtWorf" Tomaselli 18 | 19 | CONFFILE="$1" 20 | 21 | if ! [ -e "$CONFFILE" ]; then 22 | logger --id=$$ -s -perror "File $CONFFILE does not exist" 23 | exit 1 24 | fi 25 | 26 | logger --id=$$ -perror "Starting weborf using $CONFFILE" 27 | 28 | VIRTUALS=`cat "$CONFFILE" | egrep "^virtual=" | cut -c 9-` 29 | USERNAME=`cat "$CONFFILE" | egrep "^user=" | cut -d= -f2` 30 | GROUPNAME=`cat "$CONFFILE" | egrep "^group=" | cut -d= -f2` 31 | BASEDIR=`cat "$CONFFILE" | egrep "^basedir=" | cut -d= -f2` 32 | INDEXES=`cat "$CONFFILE" | egrep "^indexes=" | cut -d= -f2` 33 | USE_CGI=`cat "$CONFFILE" | egrep "^use-cgi=" | cut -d= -f2` 34 | USE_MIME=`cat "$CONFFILE" | egrep "^use-mime=" | cut -d= -f2` 35 | CGI_BIN=`cat "$CONFFILE" | egrep "^cgi=" | cut -d= -f2` 36 | CACHE_DIR=`cat "$CONFFILE" | egrep "^cachedir=" | cut -d= -f2` 37 | PORT=`cat "$CONFFILE" | egrep "^port=" | cut -d= -f2` 38 | AUTH_SOCKET=`cat "$CONFFILE" | grep "^auth-socket=" | cut -d= -f2` 39 | KEY=`cat "$CONFFILE" | grep "^key=" | cut -d= -f2` 40 | CERT=`cat "$CONFFILE" | grep "^cert=" | cut -d= -f2` 41 | 42 | # Include defaults if available 43 | if [ -f /etc/default/weborf ] ; then 44 | . /etc/default/weborf 45 | fi 46 | 47 | if [ -z "$USERNAME" ] || [ -z "$GROUPNAME" ]; then 48 | logger --id=$$ -s -perror "User or group not set" 49 | fi 50 | 51 | if test "$USERNAME" = "root" 52 | then 53 | logger --id=$$ -s -perror "You are trying to run weborf as root!" 54 | exit 0 #LSB requires 0 termination in each case 55 | fi 56 | 57 | USERID=`cat /etc/passwd | grep "^${USERNAME}:" | cut -d: -f3` #Gets the userid 58 | GROUPID=$(grep "^${GROUPNAME}:" < /etc/group | cut -d: -f3) 59 | 60 | if [ -z "$GROUPID" ]; then 61 | logger --id=$$ -perror -s "Unable to find group $GROUPNAME" 62 | exit 1 63 | fi 64 | 65 | if [ -z "$USERID" ]; then 66 | logger --id=$$ -s -perror "Unable to find user $USERNAME" 67 | exit 1 68 | fi 69 | 70 | if test -n "$CACHE_DIR" 71 | then 72 | if ! test -d $CACHE_DIR 73 | then 74 | #Does not exist or it is not a directory 75 | logger --id=$$ -s "Creating cachedir for weborf: $CACHE_DIR" 76 | rm -rf $CACHE_DIR 77 | mkdir -m700 $CACHE_DIR 78 | fi 79 | chown $USERNAME $CACHE_DIR 80 | CACHE_DIR="-C $CACHE_DIR" 81 | fi 82 | 83 | if test -n "$AUTH_SOCKET" 84 | then 85 | AUTH_SOCKET="-a $AUTH_SOCKET" 86 | fi 87 | 88 | if test -n "$INDEXES" 89 | then 90 | INDEXES="-I $INDEXES" 91 | fi 92 | 93 | if [ -n "$CERT" ]; then 94 | CERT="--cert $CERT --key $KEY" 95 | elif [ -n "$KEY" ] && [ -z "$CERT" ]; then 96 | logger --id=$$ -s "Key set but certificate is not" 97 | exit 1 98 | fi 99 | 100 | if test -n "$PORT" 101 | then 102 | PORT="-p $PORT" 103 | else 104 | PORT="-p 80" 105 | fi 106 | 107 | if test -n "$VIRTUALS" 108 | then 109 | VIRTUALS="-V $VIRTUALS" 110 | fi 111 | 112 | if test -n "$CGI_BIN" 113 | then 114 | CGI_BIN=-c $CGI_BIN 115 | fi 116 | 117 | if test $USE_CGI = "true" 118 | then 119 | CGI="-Y" 120 | fi 121 | 122 | if test $USE_MIME = "true" 123 | then 124 | MIME="-m" 125 | fi 126 | 127 | logger --id=$$ -s "weborf $2 $DAEMON_OPTS $VIRTUALS $CERT $CACHE_DIR $AUTH_SOCKET $MIME $CGI $CGI_BIN $PORT -u $USERID -g $GROUPID -b $BASEDIR $INDEXES" 128 | 129 | exec weborf $2 $DAEMON_OPTS $VIRTUALS $CERT $CACHE_DIR $AUTH_SOCKET $MIME $CGI $CGI_BIN $PORT -u $USERID -g $GROUPID -b $BASEDIR $INDEXES 130 | -------------------------------------------------------------------------------- /debian/NEWS: -------------------------------------------------------------------------------- 1 | weborf (0.16-1) unstable; urgency=medium 2 | 3 | CGI is disabled by default now. To enable it there is a -Y flag. 4 | 5 | Default directory is /srv/www 6 | 7 | -- Salvo 'LtWorf' Tomaselli Sun, 17 Feb 2019 13:36:08 +0100 8 | 9 | weborf (0.15-1) unstable; urgency=medium 10 | 11 | The configuration options for the .conf file are slightly different, so 12 | please make sure that your configuration still works. 13 | 14 | This version comes with .service files for systemd. 15 | It is now possible to run several instances of weborf, by creating a new 16 | .conf file in /etc/weborf.d 17 | 18 | So for example, to use both http and https, it is possible to copy 19 | /etc/weborf.d/weborf.conf into /etc/weborf.d/https.conf, change the port 20 | and add the path to the SSL certificate. 21 | 22 | The .service file removes some permissions to the executable, if your use 23 | case requires those permissions, you might experience failures. You can 24 | override the .service file locally. 25 | 26 | -- Salvo 'LtWorf' Tomaselli Sun, 23 Dec 2018 16:29:10 +0100 27 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | weborf (1.0-1) unstable; urgency=high 2 | 3 | * New upstream release, fixing CVE-2023-46586 4 | 5 | -- Salvo 'LtWorf' Tomaselli Thu, 12 Oct 2023 00:12:44 +0200 6 | 7 | weborf (0.20-1) unstable; urgency=low 8 | 9 | * New upstream release 10 | * Remove X-Python3-Version: >= 3.6 from control file 11 | * Added metadata file 12 | * Use setuptools since python intelligently dropped distutil 13 | * Bump Standards-Version: 4.6.2 14 | * Remove dependency on outdated lsb-base for weborf-daemon 15 | * Clean python egg to allow rebuild in place 16 | 17 | -- Salvo 'LtWorf' Tomaselli Wed, 04 Oct 2023 18:37:46 +0200 18 | 19 | weborf (0.19-2.1) unstable; urgency=medium 20 | 21 | * Non-maintainer upload. 22 | * No source change upload to rebuild with debhelper 13.10. 23 | 24 | -- Michael Biebl Sat, 15 Oct 2022 12:57:06 +0200 25 | 26 | weborf (0.19-2) unstable; urgency=high 27 | 28 | * Install weborf in autopkgtest, to test weborf 29 | 30 | -- Salvo 'LtWorf' Tomaselli Tue, 15 Mar 2022 09:08:11 +0100 31 | 32 | weborf (0.19-1) unstable; urgency=medium 33 | 34 | * New upstream release 35 | * Add autopkgtest suite. 36 | Calls the regular test suite but using the system 37 | installed version. 38 | 39 | -- Salvo 'LtWorf' Tomaselli Mon, 14 Mar 2022 23:36:58 +0100 40 | 41 | weborf (0.18-1) unstable; urgency=low 42 | 43 | * New upstream release 44 | * Bump Standards-Version: 4.6.0.1 45 | * Bump compat to 13 46 | 47 | -- Salvo 'LtWorf' Tomaselli Sun, 06 Mar 2022 13:31:12 +0100 48 | 49 | weborf (0.17-4) unstable; urgency=low 50 | 51 | * Fix d/watch 52 | 53 | -- Salvo 'LtWorf' Tomaselli Fri, 29 Oct 2021 17:01:04 +0200 54 | 55 | weborf (0.17-3) unstable; urgency=medium 56 | 57 | * Disable most of the test suite (flaky on debian builders) 58 | 59 | -- Salvo 'LtWorf' Tomaselli Thu, 31 Dec 2020 15:13:19 +0100 60 | 61 | weborf (0.17-2) unstable; urgency=medium 62 | 63 | * Added sleep to test that flaked on s390 64 | 65 | -- Salvo 'LtWorf' Tomaselli Thu, 31 Dec 2020 12:55:04 +0100 66 | 67 | weborf (0.17-1) unstable; urgency=low 68 | 69 | * build-depend on curl to run new test suite 70 | * New upstream release (LP: #1875194) 71 | * Fix debian/watch 72 | 73 | -- Salvo 'LtWorf' Tomaselli Tue, 29 Dec 2020 19:41:28 +0100 74 | 75 | weborf (0.16-1) unstable; urgency=medium 76 | 77 | * New upstream release 78 | * Bump compat to 12 79 | * Remove compat file 80 | * Pre-Depends in weborf-daemon 81 | * Rules-Requires-Root: no 82 | * Bump Standards-Version to 4.4.1 83 | 84 | -- Salvo 'LtWorf' Tomaselli Sun, 10 Nov 2019 13:49:18 +0100 85 | 86 | weborf (0.15-1) unstable; urgency=medium 87 | 88 | * New upstream release 89 | * Add libssl-dev to build depends to enable https 90 | * Add lintian override for possible-gpl-code-linked-with-openssl, since 91 | exception is provided in the license. 92 | * Bump python-version-field to 3.6 93 | * Bump Standards-Version to 4.2.1 94 | * Removed joke from qweborf (Closes: #892208) 95 | 96 | -- Salvo 'LtWorf' Tomaselli Sun, 09 Dec 2018 06:26:46 +0100 97 | 98 | weborf (0.14-2) unstable; urgency=high 99 | 100 | * Build-Depend on python3-distutils (Closes: #896795) 101 | * Fix typo in description 102 | * Remove trailing spaces in changelog and rules 103 | * Updated debian/copyright file 104 | * Bump compat from 9 to 11 105 | * Bump Standards-Version to 4.1.4 106 | * Clean the python install directory 107 | * Clean generated GUI python file 108 | 109 | -- Salvo 'LtWorf' Tomaselli Tue, 24 Apr 2018 22:12:59 +0200 110 | 111 | weborf (0.14-1) unstable; urgency=low 112 | 113 | * New upstream release 114 | * Suggest php-cgi instead of the non existing php5-cgi 115 | 116 | -- Salvo 'LtWorf' Tomaselli Tue, 19 Dec 2017 00:30:14 +0100 117 | 118 | weborf (0.13.5-1) unstable; urgency=low 119 | 120 | * New upstream release (Closes: #868181, #868182) 121 | * Remove patches from 0.13.4-2 122 | 123 | -- Salvo 'LtWorf' Tomaselli Sat, 11 Feb 2017 12:14:51 +0100 124 | 125 | weborf (0.13.4-3) unstable; urgency=low 126 | 127 | * Make weborf-daemon depend on lsb-base 128 | 129 | -- Salvo 'LtWorf' Tomaselli Thu, 03 Nov 2016 22:50:29 +0100 130 | 131 | weborf (0.13.4-2) unstable; urgency=low 132 | 133 | * Fix segmentation fault when opening extremely large directories 134 | 135 | -- Salvo 'LtWorf' Tomaselli Sun, 25 Sep 2016 17:04:34 +0200 136 | 137 | weborf (0.13.4-1) unstable; urgency=low 138 | 139 | * New upstream release 140 | * Bumped Standards-Version to 3.9.8 141 | * Removed decorator patch, now upstream 142 | 143 | -- Salvo 'LtWorf' Tomaselli Mon, 05 Sep 2016 21:46:49 +0200 144 | 145 | weborf (0.13.3-2) unstable; urgency=medium 146 | 147 | * Remove decorators to workaround a bug in PyQt 148 | 149 | -- Salvo 'LtWorf' Tomaselli Mon, 29 Aug 2016 22:53:03 +0200 150 | 151 | weborf (0.13.3-1) unstable; urgency=low 152 | 153 | * New upstream release 154 | * Bumped Standards-Version to 3.9.7 155 | * Added upstream's public key for verification 156 | 157 | -- Salvo 'LtWorf' Tomaselli Wed, 16 Mar 2016 13:45:15 +0100 158 | 159 | weborf (0.13.2-1) unstable; urgency=medium 160 | 161 | * New upstream release 162 | 163 | -- Salvo 'LtWorf' Tomaselli Tue, 09 Feb 2016 16:13:52 +0100 164 | 165 | weborf (0.13.1-2) unstable; urgency=medium 166 | 167 | * Don't hard-code the python version. (Closes: #802857) 168 | * Remove version from depends in stable 169 | * Copyright file in dep 5 (Closes: #802489) 170 | * Use all hardening flags 171 | 172 | -- Salvo 'LtWorf' Tomaselli Sun, 25 Oct 2015 13:36:21 +0100 173 | 174 | weborf (0.13.1-1) unstable; urgency=low 175 | 176 | * New upstream release 177 | * Recommends miniupnpc for NAT traversal 178 | * Typo fixed upstream (Closes: #773655) 179 | * Removed patch "miredo" (Now upstream) 180 | * Removed patch "mapped_addr" (Now upstream) 181 | * qweborf now uses Python3 and PyQt5 182 | * Drop python-support (Closes: #786147) 183 | * Bumped Standards-Version to 3.9.6 184 | * Bumped debhelper to 9 185 | * Change links to new upstream website 186 | 187 | -- Salvo 'LtWorf' Tomaselli Thu, 15 Oct 2015 08:43:41 +0200 188 | 189 | weborf (0.13-3) unstable; urgency=low 190 | 191 | * Fixed typo in the description (Closes: #677083) 192 | * Correctly handles IPv4 clients in log files when started by 193 | xinetd (Closes: #601253) 194 | * Updated Standards-Version 195 | * Build-depends on hardening-wrapper 196 | 197 | -- Salvo 'LtWorf' Tomaselli Thu, 21 Jun 2012 17:35:43 +0200 198 | 199 | weborf (0.13-2) unstable; urgency=low 200 | 201 | * Backport fix from upstream: qweborf doesn't crash when miredo is in use 202 | 203 | -- Salvo 'LtWorf' Tomaselli Mon, 19 Dec 2011 10:54:07 +0100 204 | 205 | weborf (0.13-1) unstable; urgency=low 206 | 207 | * New upstream release 208 | * Adds qweborf package, GUI for sharing files with HTTP 209 | * Uses GNU autotools (Closes: #611528) 210 | * Adds libmagic-dev in build-deps 211 | * Added more examples 212 | 213 | -- Salvo 'LtWorf' Tomaselli Sat, 26 Mar 2011 14:44:31 +0100 214 | 215 | weborf (0.12.5-1) unstable; urgency=high 216 | 217 | * New upstream release 218 | * Fixes DoS 219 | 220 | -- Salvo 'LtWorf' Tomaselli Fri, 28 Jan 2011 11:18:01 +0100 221 | 222 | weborf (0.12.4-1) unstable; urgency=high 223 | 224 | * New upstream release 225 | * Fixes DoS (Closes: #601585) 226 | 227 | -- Salvo 'LtWorf' Tomaselli Wed, 27 Oct 2010 16:01:35 +0200 228 | 229 | weborf (0.12.3-1) unstable; urgency=low 230 | 231 | * New upstream release 232 | * Fixes directory traversal (Closes: #596112) 233 | 234 | -- Salvo 'LtWorf' Tomaselli Wed, 08 Sep 2010 22:24:21 +0200 235 | 236 | weborf (0.12.2-1) unstable; urgency=low 237 | 238 | * New upstream release 239 | 240 | -- Salvo 'LtWorf' Tomaselli Tue, 22 Jun 2010 16:33:22 +0200 241 | 242 | weborf (0.12.1-1) unstable; urgency=low 243 | 244 | * New upstream release 245 | 246 | -- Salvo 'LtWorf' Tomaselli Thu, 03 Jun 2010 23:48:40 +0200 247 | 248 | weborf (0.12-2) unstable; urgency=low 249 | 250 | * Using quilt 251 | * Fixed error in Makefile that prevented building 252 | * Fixed date error in debian changelog 253 | 254 | -- Salvo 'LtWorf' Tomaselli Sat, 29 May 2010 18:30:22 +0200 255 | 256 | weborf (0.12-1) unstable; urgency=low 257 | 258 | * Corrected spelling mistake in manpage (Closes: #549652) 259 | * Builds weborf-daemon package 260 | * New upstream release 261 | * Added explicit format 1.0 262 | 263 | -- Salvo 'LtWorf' Tomaselli Thu, 27 May 2010 22:10:22 +0200 264 | 265 | weborf (0.11-2) unstable; urgency=low 266 | 267 | * Corrected name of upstream author Salvo Rinaldi in the copyright file. 268 | * Added name of upstream author Salvo Rinaldi in the manpages. 269 | * Edited description of the package 270 | 271 | -- Salvo 'LtWorf' Tomaselli Sat, 26 Sep 2009 18:46:22 +0200 272 | 273 | weborf (0.11-1) unstable; urgency=low 274 | 275 | * Initial release (Closes: #506771) 276 | 277 | -- Salvo 'LtWorf' Tomaselli Tue, 22 Sep 2009 15:13:55 +0200 278 | -------------------------------------------------------------------------------- /debian/clean: -------------------------------------------------------------------------------- 1 | qweborf/qweborf.egg-info/ 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: weborf 2 | Section: httpd 3 | Priority: optional 4 | Maintainer: Salvo 'LtWorf' Tomaselli 5 | Build-Depends: debhelper-compat (= 13), debhelper (>= 13), libmagic-dev, python3, dh-python, pyqt5-dev-tools, 6 | python3-setuptools, libssl-dev, curl 7 | Standards-Version: 4.6.2 8 | Rules-Requires-Root: no 9 | Homepage: https://ltworf.github.io/weborf/ 10 | 11 | Package: weborf 12 | Architecture: any 13 | Depends: ${shlibs:Depends}, ${misc:Depends} 14 | Suggests: php-cgi 15 | Description: Fast and small webserver meant to be run without root privileges 16 | Weborf is a configurationless webserver mainly meant to allow users to 17 | easily share their directories over the web. 18 | Has limited support to webdav, allowing its use by GNOME and KDE filemanagers. 19 | It also supports cgi. 20 | 21 | Package: weborf-daemon 22 | Architecture: all 23 | Pre-Depends: ${misc:Pre-Depends} 24 | Depends: ${misc:Depends}, weborf (>=${binary:Version}) 25 | Description: init script for weborf 26 | Weborf is a configurationless webserver mainly meant to allow users to 27 | easily share their directories over the web. 28 | Has limited support to webdav, allowing its use by GNOME and KDE filemanagers. 29 | It also supports cgi. 30 | . 31 | This package provides a SystemV daemon to start weborf using init. 32 | 33 | Package: qweborf 34 | Architecture: all 35 | Depends: ${misc:Depends}, ${python3:Depends}, weborf (>=${binary:Version}), python3-pyqt5 36 | Recommends: miniupnpc 37 | Description: Shares files using the HTTP protocol 38 | Qweborf provides an easy to use graphical interface to share local files using 39 | the HTTP protocol. 40 | It can enable writing on the server, webdav, authentication and sending 41 | directories as tar.gz. 42 | It can try to work across NAT. 43 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Author: Salvo "LtWorf" Tomaselli 3 | Source: https://ltworf.github.io/weborf/ 4 | 5 | Files: * 6 | Copyright: 2007-2018 Salvo "LtWorf" Tomaselli , 7 | 2007 Salvo Rinaldi 8 | License: GPL-3+ 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | . 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | . 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | . 22 | On Debian systems, the complete text of the GNU General Public License 23 | can be found in the /usr/share/common-licenses/GPL-3 file. 24 | . 25 | Additional permission under GNU GPL version 3 section 7 26 | . 27 | If you modify this Program, or any covered work, by linking or 28 | combining it with OpenSSL (or a modified version of that library), 29 | containing parts covered by the terms of OpenSSL License, the 30 | licensors of this Program grant you additional permission to 31 | convey the resulting work. Corresponding Source for a non-source 32 | form of such a combination shall include the source code for the 33 | parts of OpenSSL used as well as that of the covered work. 34 | -------------------------------------------------------------------------------- /debian/patches/series: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltworf/weborf/10bb70708c80533c505d721eca88bb17ea4c18c4/debian/patches/series -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | SHELL=sh -e 4 | 5 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 6 | # DPKG_EXPORT_BUILDFLAGS = 1 7 | # include /usr/share/dpkg/buildflags.mk 8 | 9 | export DH_VERBOSE=1 10 | 11 | %: 12 | dh $@ --with python3 13 | 14 | override_dh_installinit: 15 | dh_installinit -pweborf-daemon --onlyscripts --init-script=weborf 16 | 17 | override_dh_auto_install: 18 | make -C qweborf install DESTDIR=../debian/qweborf 19 | dh_auto_install 20 | 21 | override_dh_auto_clean: 22 | make -C qweborf clean 23 | dh_auto_clean 24 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/tests/control: -------------------------------------------------------------------------------- 1 | Test-Command: testsuite/version_and_help 2 | Restrictions: allow-stderr superficial 3 | Depends: weborf 4 | 5 | Test-Command: testsuite/site1http 6 | Restrictions: allow-stderr 7 | Depends: curl, weborf 8 | 9 | Test-Command: testsuite/site1https 10 | Restrictions: allow-stderr 11 | Depends: curl, weborf 12 | 13 | Test-Command: testsuite/ip_listener 14 | Restrictions: allow-stderr 15 | Depends: curl, weborf 16 | 17 | Test-Command: testsuite/vhost 18 | Restrictions: allow-stderr 19 | Depends: curl, weborf 20 | 21 | Test-Command: testsuite/etag 22 | Restrictions: allow-stderr 23 | Depends: curl, weborf 24 | 25 | Test-Command: testsuite/index_file 26 | Restrictions: allow-stderr 27 | Depends: curl, weborf 28 | 29 | Test-Command: testsuite/range 30 | Restrictions: allow-stderr 31 | Depends: curl, weborf 32 | 33 | Test-Command: testsuite/cgi 34 | Restrictions: allow-stderr 35 | Depends: curl, weborf 36 | 37 | Test-Command: testsuite/cachedir 38 | Restrictions: allow-stderr rw-build-tree 39 | Depends: curl, weborf 40 | 41 | Test-Command: testsuite/site1mimetype 42 | Restrictions: allow-stderr 43 | Depends: curl, weborf 44 | -------------------------------------------------------------------------------- /debian/upstream/metadata: -------------------------------------------------------------------------------- 1 | Donation: https://liberapay.com/ltworf 2 | Repository-Browse: https://github.com/ltworf/weborf 3 | Repository: https://github.com/ltworf/weborf.git 4 | Changelog: https://raw.githubusercontent.com/ltworf/weborf/master/CHANGELOG 5 | Bug-Database: https://github.com/ltworf/weborf/issues 6 | Bug-Submit: https://github.com/ltworf/weborf/issues/new 7 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=4 2 | 3 | opts=pgpmode=auto \ 4 | https://github.com/ltworf/weborf/tags (?:.*?/)?v?@ANY_VERSION@@ARCHIVE_EXT@ 5 | -------------------------------------------------------------------------------- /debian/weborf-daemon.install: -------------------------------------------------------------------------------- 1 | usr/share/man/man5/weborf.conf.5 2 | etc/weborf.conf 3 | etc/init.d/ 4 | etc/weborf.d/ 5 | usr/share/weborf/weborf_launcher 6 | lib/systemd/system/weborf.service 7 | lib/systemd/system/weborf@.service 8 | lib/systemd/system-generators/weborf-generator 9 | -------------------------------------------------------------------------------- /debian/weborf.examples: -------------------------------------------------------------------------------- 1 | examples/auth.py 2 | examples/weborf_auth.c 3 | examples/xinetd.conf 4 | examples/weborf_auth_dav.c 5 | examples/weborf_auth.service 6 | -------------------------------------------------------------------------------- /debian/weborf.install: -------------------------------------------------------------------------------- 1 | usr/bin/weborf 2 | usr/share/man/man1/weborf.1 3 | usr/share/doc/weborf/CHANGELOG 4 | usr/share/doc/weborf/Credits 5 | usr/share/doc/weborf/README.md 6 | usr/share/doc/weborf/TODOlist 7 | -------------------------------------------------------------------------------- /debian/weborf.lintian-overrides: -------------------------------------------------------------------------------- 1 | weborf: possible-gpl-code-linked-with-openssl 2 | -------------------------------------------------------------------------------- /do_debian: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir -p deb-pkg 3 | rm -rf deb-pkg/* 4 | 5 | autoreconf -f -i 6 | ./configure 7 | make -j 8 | 9 | PRJDIR=$(pwd) 10 | TMPDIR=/tmp/ 11 | VERSION=$(./weborf --version | head -n 1 | cut -d\ -f2) 12 | 13 | 14 | 15 | rm -rf $TMPDIR/weborf* 16 | make clean 17 | ./configure 18 | make -j dist 19 | mv weborf-$VERSION.tar.gz $TMPDIR/weborf_$VERSION.orig.tar.gz 20 | gpg --sign --armor --detach-sign $TMPDIR/weborf_$VERSION.orig.tar.gz 21 | cd $TMPDIR 22 | tar -xvvf weborf_$VERSION.orig.tar.gz 23 | cd weborf-$VERSION 24 | cp -r $PRJDIR/debian . 25 | dpkg-buildpackage --changes-option=-S 26 | cd .. 27 | mv /tmp/weborf*.* /tmp/qweborf* "$PRJDIR"/deb-pkg 28 | cd "$PRJDIR" 29 | lintian --pedantic -E --color auto -i -I deb-pkg/*changes deb-pkg/*deb 30 | -------------------------------------------------------------------------------- /embedded_auth.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | /** 22 | * This file contains user defined embedded autentication 23 | * to avoid the usage of an external daemon for authentication. 24 | * The use of this, will make things faster and parallel, at the cost 25 | * of needing to define it at compile time 26 | * 27 | * Everything in this file should be between the "#ifdef EMBEDDED_AUTH" 28 | * and its "#endif" to avoid the compilation of unused methods 29 | * */ 30 | 31 | //#define EMBEDDED_AUTH 32 | 33 | #ifdef EMBEDDED_AUTH 34 | 35 | /** 36 | * This function is just example code, can be changed or deleted 37 | */ 38 | static int emb_check_password(char *username, char *password) { 39 | char *user="gentoo"; 40 | char *pass="lalalala"; 41 | 42 | if (strncmp(username,user,strlen(user))==0 && strncmp(password,pass,strlen(pass))==0) 43 | return 0; 44 | return -1; 45 | } 46 | 47 | /** 48 | * This function will be used if EMBEDDED_AUTH is defined, do not modify its signature! 49 | * 50 | * page: URI of requested page 51 | * ip_addr: IP address of the client (it can be an IPv6, depending how weborf is compiled) 52 | * method: HTTP method of the request 53 | * username: Username, if provided, null otherwise 54 | * password: Password, if provided, null otherwise 55 | * http_param: Headers of the request 56 | * 57 | * RETURN VALUE: 58 | * Return 0 to allow the request, -1 to deny it. 59 | * 60 | * NOTES: 61 | * The actual content of the function must be regarded as an example, modify it according to your 62 | * own needs. 63 | * Only use reentrant calls in this function. Weborf is multithreaded. 64 | */ 65 | static int c_auth(char *page, char *ip_addr, char *method, char *username, char *password, char *http_param) { 66 | char *allowed_prefix="::ffff:10."; 67 | char *foto = "/foto/"; 68 | 69 | //Allow anything from 10.* 70 | if (strncmp(allowed_prefix,ip_addr,strlen(allowed_prefix))==0) return 0; 71 | 72 | //Allow PROPFIND and OPTIONS with authentication (to allow read only webdav from anywhere) 73 | if ((strncmp(method,"PROPFIND",strlen("PROPFIND"))==0) || (strncmp(method,"OPTIONS",strlen("OPTIONS"))==0)) 74 | return emb_check_password(username,password); 75 | 76 | //Deny all except GET and POST 77 | else if (!(strncmp(method,"GET",strlen("GET"))==0 || strncmp(method,"POST",strlen("POST"))==0)) { 78 | return -1; 79 | } 80 | 81 | //request authentication for photos 82 | if (strncmp(foto,page,strlen(foto))==0) 83 | return emb_check_password(username,password); 84 | 85 | 86 | return 0; 87 | 88 | } 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /examples/auth.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # This is an example authentication script. You can modify it to make it fit your needs 3 | 4 | # Weborf 5 | # Copyright (C) 2019-2023 Salvo "LtWorf" Tomaselli 6 | # 7 | # Weborf is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | # author Salvo "LtWorf" Tomaselli 21 | 22 | import asyncio 23 | import os 24 | from typing import NamedTuple 25 | from syslog import * 26 | 27 | 28 | class Request(NamedTuple): 29 | url: bytes 30 | addr: bytes 31 | method: bytes 32 | username: bytes 33 | password: bytes 34 | protocol: bytes 35 | 36 | SOCKET_PATH = "/run/weborf/weborf_auth.socket" 37 | 38 | async def main(): 39 | try: 40 | os.remove(SOCKET_PATH) 41 | except OSError: 42 | pass 43 | 44 | l = asyncio.get_running_loop() 45 | server = await l.create_unix_server(Proto, SOCKET_PATH) 46 | await server.serve_forever() 47 | 48 | 49 | class Proto(asyncio.Protocol): 50 | def allow(self): 51 | self.transport.close() 52 | 53 | def deny(self): 54 | self.transport.write(b' ') 55 | self.transport.close() 56 | 57 | def connection_made(self, transport): 58 | self.transport = transport 59 | 60 | def data_received(self, data: bytes) -> None: 61 | fields = data.split(b'\r\n') 62 | request = Request(*fields[:6]) 63 | headers = {k:v for k, v in(i.split(b': ', 1) for i in fields[6:] if i)} 64 | 65 | # Allow all from internal network 66 | if request.addr.startswith(b'::ffff:10.0.'): 67 | self.allow() 68 | return 69 | 70 | # Require a password for some content 71 | if request.url.startswith(b'/movies/') or request.url.startswith(b'/music/'): 72 | if request.username != b'user' and request.password != b'pass': 73 | self.deny() 74 | return 75 | else: 76 | self.allow() 77 | return 78 | # Require another password for all other content 79 | elif request.username == b'user2' and request.password == b'pass2': 80 | self.allow() 81 | return 82 | self.deny() 83 | 84 | 85 | asyncio.run(main()) 86 | -------------------------------------------------------------------------------- /examples/index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | This is an example of index file. 6 | It adds a "." to a session variable on every refresh, shows the informations and sets a cookie. 7 | ''' 8 | 9 | import os 10 | import sys 11 | from cgi_weborf import * #imports module cgi 12 | 13 | cgi.session_start() 14 | cgi.setcookie("id","33") 15 | 16 | cgi.finalize_headers() #will output the final \r\n\r\n and the content-type header 17 | 18 | if 'nome' in cgi.SESSION: 19 | cgi.SESSION['nome']+="." 20 | else: 21 | cgi.SESSION['nome']="." 22 | 23 | sys.stdout.write( "") 24 | sys.stdout.write( "") 25 | 26 | sys.stdout.write( "

example

") 27 | cgi.pyinfo() 28 | sys.stdout.write( "") 29 | sys.stdout.write( "") 30 | 31 | cgi.savesession() 32 | -------------------------------------------------------------------------------- /examples/weborf_auth.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2009 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | //Example of authentication program 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define SOCK_PATH "/tmp/weborf_auth.socket" 32 | #define SIZE 1024 33 | 34 | int main(void) { 35 | int s,s2, t, len; 36 | struct sockaddr_un local, remote; 37 | char str[SIZE]; 38 | 39 | if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 40 | perror("socket"); 41 | exit(1); 42 | } 43 | 44 | local.sun_family = AF_UNIX; 45 | strcpy(local.sun_path, SOCK_PATH); 46 | unlink(SOCK_PATH); 47 | len = strlen(local.sun_path) + sizeof(local.sun_family); 48 | 49 | if (bind(s, (struct sockaddr *)&local, len) == -1) { 50 | perror("bind"); 51 | exit(1); 52 | } 53 | 54 | if (listen(s, 5) == -1) { 55 | perror("listen"); 56 | exit(1); 57 | } 58 | 59 | for (;;) { 60 | t = sizeof(remote); 61 | if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) { 62 | perror("accept"); 63 | exit(1); 64 | } 65 | 66 | t = recv(s2, str, SIZE, 0); 67 | str[t] = '\0'; 68 | 69 | if (str[1]=='f' && str[2]=='i' && str[3]=='l' && str[4]=='m') { 70 | if (strstr(str,"::ffff:10.0.")==NULL) { 71 | send(s2,"c", 1,0); 72 | } 73 | 74 | } 75 | 76 | close(s2); 77 | } 78 | 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /examples/weborf_auth.service: -------------------------------------------------------------------------------- 1 | [Install] 2 | WantedBy=multi-user.target 3 | 4 | [Unit] 5 | Description=Weborf auth daemon 6 | 7 | [Service] 8 | InaccessiblePaths=/var 9 | InaccessiblePaths=-/srv 10 | ProtectSystem=strict 11 | ProtectHome=true 12 | PrivateDevices=true 13 | PrivateUsers=true 14 | NoNewPrivileges=true 15 | RestrictAddressFamilies=AF_UNIX 16 | ProtectKernelTunables=true 17 | ProtectKernelModules=true 18 | ProtectControlGroups=true 19 | PrivateTmp=true 20 | Type=simple 21 | Restart=always 22 | StandardOutput=syslog 23 | StandardError=syslog 24 | SyslogIdentifier=weborf_auth 25 | ExecStart=/usr/local/bin/auth.py 26 | RuntimeDirectory=weborf 27 | User=www-data 28 | Group=www-data 29 | -------------------------------------------------------------------------------- /examples/weborf_auth_dav.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | /*Example of authentication program 22 | 23 | This program will allow all GET and POST methods, 24 | will allow PROPFIND MKCOL and PUT only from 10.0.* 25 | And will deny the rest. 26 | 27 | For avoiding trouble, also the OPTIONS method is always 28 | enabled 29 | */ 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #define SOCK_PATH "/tmp/weborf_auth.socket" 42 | #define SIZE 1024 43 | 44 | int main(void) { 45 | int s,s2, t, len; 46 | struct sockaddr_un local, remote; 47 | char str[SIZE]; 48 | 49 | //Removes the socket if already exists 50 | unlink(SOCK_PATH); 51 | 52 | if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 53 | perror("socket"); 54 | exit(1); 55 | } 56 | 57 | local.sun_family = AF_UNIX; 58 | strcpy(local.sun_path, SOCK_PATH); 59 | unlink(SOCK_PATH); 60 | len = strlen(local.sun_path) + sizeof(local.sun_family); 61 | 62 | if (bind(s, (struct sockaddr *)&local, len) == -1) { 63 | perror("bind"); 64 | exit(1); 65 | } 66 | 67 | if (listen(s, 5) == -1) { 68 | perror("listen"); 69 | exit(1); 70 | } 71 | 72 | 73 | //Cycle to accept connections 74 | for (;;) { 75 | t = sizeof(remote); 76 | if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) { 77 | perror("accept"); 78 | exit(1); 79 | } 80 | 81 | t = recv(s2, str, SIZE, 0); 82 | str[t] = '\0'; 83 | 84 | 85 | //Parse string to get the things we need 86 | char *uri = strtok(str,"\r\n"); 87 | char *ip = strtok(NULL,"\r\n"); 88 | char *method = strtok(NULL,"\r\n"); 89 | 90 | 91 | //Allow GET, POST, and OPTIONS 92 | if (strncmp(method,"GET",3)==0 || strncmp(method,"POST",4)==0 || strncmp(method,"OPTIONS",7)) { 93 | close(s2); //Closing the connection without sending anything will result in weborf accept the request 94 | } 95 | //Allow PROPFIND MKCOL PUT from local network 96 | else if (strncmp(method,"PROPFIND",8)==0 || strncmp(method,"PUT",3)==0 || strncmp(method,"MKCOL",5)==0) { 97 | if (strncmp(ip,"::ffff:10.0.",12)!=0) 98 | send(s2,"c",1,0); 99 | close(s2); 100 | } 101 | 102 | //Disallow the rest (DELETE, MOVE, COPY) 103 | else { 104 | send(s2,"c", 1,0); 105 | close(s2); 106 | } 107 | 108 | } 109 | 110 | return 0; 111 | } 112 | 113 | -------------------------------------------------------------------------------- /examples/xinetd.conf: -------------------------------------------------------------------------------- 1 | service www 2 | { 3 | socket_type = stream 4 | wait = no 5 | user = www-data 6 | instances = 100 7 | server = /usr/bin/weborf 8 | server_args = -T 9 | port = 80 10 | cps = 100 4 11 | flags = IPv6 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /instance.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007-2020 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | @author Salvo Rinaldi 20 | */ 21 | 22 | #ifndef WEBORF_INSTANCE_H 23 | #define WEBORF_INSTANCE_H 24 | 25 | #ifndef O_LARGEFILE //Needed to compile on Mac, where this doesn't exist 26 | #define O_LARGEFILE 0 27 | #endif 28 | 29 | #include "types.h" 30 | #include "buffered_reader.h" 31 | 32 | #ifdef WEBDAV 33 | #include "webdav.h" 34 | #endif 35 | 36 | 37 | //Request 38 | #define INVALID -1 39 | #define GET 0 40 | #define POST 1 41 | #define PUT 2 42 | #define DELETE 3 43 | #define OPTIONS 8 44 | 45 | #ifdef WEBDAV 46 | #define PROPFIND 4 47 | #define COPY 5 48 | #define MOVE 6 49 | #define MKCOL 7 50 | #endif 51 | 52 | 53 | #define NO_ACTION -120 54 | 55 | //Errors 56 | #define ERR_RANGE_NOT_SATISFIABLE -15 57 | #define ERR_PRECONDITION_FAILED -14 58 | #define ERR_NOT_ALLOWED -13 59 | #define ERR_INSUFFICIENT_STORAGE -12 60 | #define ERR_CONFLICT -11 61 | #define ERR_SERVICE_UNAVAILABLE -10 62 | #define ERR_FORBIDDEN -9 63 | #define ERR_NOTIMPLEMENTED -8 64 | #define ERR_NODATA -7 65 | #define ERR_NOTHTTP -6 66 | #define ERR_NOAUTH -5 67 | #define ERR_SOCKWRITE -4 68 | #define ERR_NOMEM -3 69 | #define ERR_FILENOTFOUND -2 70 | #define ERR_BRKPIPE -1 71 | 72 | //Ok 73 | #define OK_CREATED 1 74 | #define OK_NOCONTENT 2 75 | 76 | //Protocol version 77 | #define HTTP_0_9 57 78 | #define HTTP_1_0 48 79 | #define HTTP_1_1 2 80 | 81 | void inetd(); 82 | void *instance(void *); 83 | int write_file(connection_t * connection_prop); 84 | int send_err(connection_t *connection_prop,int err,char* descr); 85 | string_t read_post_data(connection_t * connection_prop, buffered_read_t * read_b); 86 | char *get_basedir(char *http_param); 87 | int send_http_header(int code, unsigned long long int *size, char *headers, bool content, time_t timestamp, connection_t * connection_prop); 88 | int delete_file(connection_t* connection_prop); 89 | int read_file(connection_t* connection_prop,buffered_read_t* read_b); 90 | #endif 91 | -------------------------------------------------------------------------------- /listener.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | @author Giuseppe Pappalardo 20 | @author Salvo Rinaldi 21 | */ 22 | #include "options.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | 40 | #include "listener.h" 41 | #include "instance.h" 42 | #include "queue.h" 43 | #include "utils.h" 44 | #include "mystring.h" 45 | #include "types.h" 46 | #include "cachedir.h" 47 | #include "configuration.h" 48 | #include "mynet.h" 49 | 50 | #define _GNU_SOURCE 51 | 52 | syn_queue_t queue; //Queue for opened sockets 53 | 54 | t_thread_info thread_info; 55 | 56 | extern weborf_configuration_t weborf_conf; 57 | 58 | pthread_attr_t t_attr; //thread's attributes 59 | 60 | pthread_key_t thread_key; //key for pthread_setspecific 61 | 62 | /** 63 | Sets t_attr to make detached threads 64 | and initializes pthread_keys 65 | */ 66 | static void init_thread_attr() { 67 | pthread_attr_init(&t_attr); 68 | pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED); 69 | pthread_key_create(&thread_key,NULL); 70 | 71 | } 72 | 73 | /** 74 | Starts threads 75 | Specify how many threads start. 76 | */ 77 | void init_threads(unsigned int count) { 78 | static long int id = 1; 79 | //t_free=MAXTHREAD; 80 | int effective=0,i; 81 | 82 | pthread_t t_id;//Unused var, thread's system id 83 | 84 | pthread_mutex_lock(&thread_info.mutex); 85 | //Check condition within the lock 86 | if (thread_info.count + count < MAXTHREAD) { 87 | 88 | //Start 89 | for (i = 1; i <= count; i++) 90 | if (pthread_create(&t_id, &t_attr, instance, (void *) (id++))==0) effective++; 91 | 92 | thread_info.count+=effective; // increases the count of started threads 93 | #ifdef THREADDBG 94 | syslog(LOG_DEBUG, "There are %d free threads", thread_info.free); 95 | #endif 96 | 97 | #ifdef SERVERDBG 98 | if (effective!=count) 99 | syslog(LOG_CRIT,"Unable to launch the required threads"); 100 | #endif 101 | 102 | 103 | } 104 | pthread_mutex_unlock(&thread_info.mutex); 105 | } 106 | 107 | /** 108 | This function inits the logger. 109 | Will use syslogd 110 | */ 111 | static void init_logger() { 112 | openlog("weborf", LOG_ODELAY, LOG_DAEMON); 113 | #ifdef SERVERDBG 114 | syslog(LOG_INFO, "Starting server..."); 115 | #endif 116 | 117 | } 118 | 119 | 120 | static void init_thread_info() { 121 | //Init thread_info 122 | pthread_mutex_init(&thread_info.mutex, NULL); 123 | thread_info.count=0; 124 | thread_info.free=0; 125 | } 126 | 127 | 128 | /** 129 | This function, terminates threads if there are too many free threads. 130 | 131 | It only takes action every THREADCONTROL seconds. 132 | */ 133 | static void t_shape() { 134 | static time_t last_action = 0; 135 | 136 | if (last_action + 10 > time(NULL)) { 137 | return; 138 | } 139 | last_action = time(NULL); 140 | 141 | if (thread_info.free > MAXFREETHREAD) { //Too many free threads, terminates one of them 142 | //Write the termination order to the queue, the thread who will read it, will terminate 143 | q_put(&queue,-1); 144 | } 145 | } 146 | 147 | 148 | /** 149 | * Set quit action on SIGTERM and SIGINT 150 | * and prints the internal status on SIGUSR1 151 | * */ 152 | static void init_signals() { 153 | //Handle SIGINT and SIGTERM 154 | signal(SIGINT, quit); 155 | signal(SIGTERM, quit); 156 | 157 | //Prints queue status with this signal 158 | signal(SIGUSR1, print_queue_status); 159 | } 160 | 161 | int main(int argc, char *argv[]) { 162 | int s, s1; //Socket descriptors 163 | 164 | init_logger(); 165 | init_thread_info(); 166 | 167 | configuration_load(argc,argv); 168 | 169 | if (weborf_conf.is_inetd) inetd(); 170 | 171 | print_start_disclaimer(argc,argv); 172 | 173 | s = net_create_server_socket(); 174 | net_bind_and_listen(s); 175 | 176 | set_new_gid(weborf_conf.gid); 177 | set_new_uid(weborf_conf.uid); 178 | 179 | if (weborf_conf.daemonize) 180 | daemonize(); 181 | 182 | //init the queue for opened sockets 183 | if (q_init(&queue, MAXTHREAD + 1) != 0) 184 | exit(NOMEM); 185 | 186 | //Starts the 1st group of threads 187 | init_thread_attr(); 188 | init_threads(INITIALTHREAD); 189 | init_signals(); 190 | 191 | struct pollfd poll_fds[1]; 192 | poll_fds[0].fd = s; 193 | poll_fds[0].events = POLLIN; 194 | 195 | while (1) { 196 | if (poll(poll_fds, 1, 1000 * THREADCONTROL) == -1) { 197 | #ifdef SERVERDBG 198 | syslog(LOG_ERR, "Error polling server socket: %d", errno); 199 | #endif 200 | exit(11); 201 | } 202 | 203 | 204 | t_shape(); 205 | 206 | s1 = accept(s, NULL,NULL); 207 | 208 | if (s1 >= 0 && q_put(&queue, s1)!=0) { //Adds s1 to the queue 209 | #ifdef REQUESTDBG 210 | syslog(LOG_ERR,"Not enough resources, dropping connection..."); 211 | #endif 212 | close(s1); 213 | } 214 | 215 | //Start new thread if needed 216 | if (thread_info.free <= LOWTHREAD && thread_info.free. 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | @author Giuseppe Pappalardo 20 | 21 | */ 22 | 23 | #ifndef WEBORF_LISTENER_H 24 | #define WEBORF_LISTENER_H 25 | 26 | 27 | #define NOMEM 7 28 | 29 | void init_threads(unsigned int count); 30 | void quit(); 31 | void print_queue_status(); 32 | void set_authsocket(char *); 33 | void chn_thread_count(int val); 34 | void set_new_uid(int uid); 35 | void set_new_gid(int gid); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /manage: -------------------------------------------------------------------------------- 1 | # Weborf 2 | # Copyright (C) 2019 Salvo "LtWorf" Tomaselli 3 | # 4 | # Weborf is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | #CC=gcc 18 | #DEFS=-Ddebug 19 | OFLAGS=-O2 20 | #-pedantic -Wextra 21 | DEFINES=-D_FILE_OFFSET_BITS=64 22 | 23 | CFLAGS=-Wall $(DEFS) $(ARCHFLAGS) -Wformat -g $(OFLAGS) $(DEFINES) 24 | LDFLAGS=-lpthread -lmagic 25 | 26 | 27 | #Opensolaris flags 28 | #CFLAGS=-D_POSIX_PTHREAD_SEMANTICS -Wall $(DEFS) $(ARCHFLAGS) -Wformat 29 | #LDFLAGS=-lpthread -lsocket -lnsl 30 | #ARCHFLAGS=-m64 31 | 32 | MANDIR=/usr/share/man/ 33 | BINDIR=/usr/bin/ 34 | DAEMONDIR=/etc/init.d/ 35 | CONFDIR=/etc/ 36 | CGIDIR=/usr/lib/cgi-bin/ 37 | #PYDIR=/usr/lib/python$(PYVERSION)/cgi_weborf 38 | 39 | all: weborf cgi 40 | 41 | weborf: debug 42 | strip weborf 43 | 44 | combined: 45 | $(CC) $(CFLAGS) $(LDFLAGS) $(ARCHFLAGS) -fwhole-program -combine *.c -o weborf 46 | strip weborf 47 | 48 | %.c: %.h 49 | 50 | debug: cgi.o listener.o queue.o configuration.o auth.o mynet.o instance.o mystring.o utils.o base64.o buffered_reader.o webdav.o mime.o cachedir.o myio.o 51 | $(CC) -g $(LDFLAGS) $(ARCHFLAGS) $+ -o weborf 52 | 53 | clean: 54 | rm -f *.o weborf debug *.orig *~ *.gz 55 | 56 | cleanall: clean 57 | rm -rf `find | fgrep .svn` 58 | rm -rf `find | fgrep ~` 59 | 60 | purge: uninstall 61 | rm -f $(CONFDIR)/weborf.conf 62 | 63 | source: clean style 64 | cd ..; tar cvzf weborf-`date +\%F | tr -d -`.tar.gz weborf/ 65 | 66 | style: 67 | #‑‑align‑pointer=name To use when will really work 68 | astyle --indent=spaces=4 -a *.c *.h 69 | 70 | memcheck: debug 71 | valgrind -v --track-origins=yes --tool=memcheck --leak-check=yes --leak-resolution=high --show-reachable=yes --num-callers=20 --track-fds=yes ./weborf || echo "Valgrind doesn't appear to be installed on this system" 72 | 73 | clangstaticcheck: 74 | scan-build gcc -c *.c 75 | -------------------------------------------------------------------------------- /mime.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | 23 | #include 24 | #include 25 | 26 | 27 | #include "mime.h" 28 | 29 | #ifdef SEND_MIMETYPES 30 | #include 31 | #endif 32 | 33 | /** 34 | Returns a token for the libmagic. 35 | buffer must NOT be shared amongst threads. 36 | The size of buffer is assumed to be at least MIMETYPELEN 37 | */ 38 | int mime_init(magic_t *token) { 39 | #ifdef SEND_MIMETYPES 40 | *token=magic_open(MAGIC_SYMLINK | MAGIC_MIME_TYPE); 41 | if (*token==NULL) return 1; 42 | return magic_load(*token,NULL); //Load the database 43 | #else 44 | *token=NULL; 45 | return 0; 46 | #endif 47 | 48 | } 49 | 50 | /** 51 | Releases the token for libmagic 52 | If the token is null, it will do nothing. 53 | */ 54 | void mime_release(magic_t token) { 55 | if (token==NULL) return; 56 | #ifdef SEND_MIMETYPES 57 | magic_close(token); 58 | #endif 59 | } 60 | 61 | /** 62 | returns mimetype of an opened file descriptor 63 | the cursor can be located at any position 64 | 65 | fd is the descriptor to an open file 66 | sb is the stat to the same file 67 | */ 68 | const char* mime_get_fd (magic_t token,int fd,struct stat *sb) { 69 | 70 | #ifdef SEND_MIMETYPES 71 | if (token==NULL) return NULL; 72 | 73 | /*If fd is a directory, send the mimetype without attempting to read it*/ 74 | 75 | if (sb->st_mode & S_IFREG) { 76 | /* 77 | * Seek file to 0 and read its header to know its mime type 78 | * then seek again to the previous position 79 | */ 80 | char buf[64]; 81 | 82 | //Get the current cursor position 83 | off_t prev_pos=lseek(fd,0,SEEK_CUR); 84 | 85 | //Set the cursor to the beginning of the file 86 | lseek(fd,0,SEEK_SET); 87 | 88 | //Reads 64 bytes to determine the type 89 | int r=read(fd,&buf,64); 90 | 91 | //Reset the position 92 | lseek(fd,prev_pos,SEEK_SET); 93 | 94 | const char* mime=magic_buffer(token,&buf,r); 95 | 96 | return mime; 97 | } else if (sb->st_mode & S_IFDIR) 98 | return "application/x-directory"; 99 | else if (sb->st_mode & S_IFSOCK) 100 | return "application/x-socket"; 101 | else if (sb->st_mode & S_IFLNK) 102 | return "application/x-symlink"; 103 | else if (sb->st_mode & S_IFBLK) 104 | return "application/x-block-device"; 105 | else if (sb->st_mode & S_IFCHR) 106 | return "application/x-character-device"; 107 | //else if (sb->st_mode & S_IFIFO) 108 | return "application/x-fifo"; 109 | 110 | #else 111 | return NULL; 112 | #endif 113 | } 114 | -------------------------------------------------------------------------------- /mime.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_MIME_H 22 | #define WEBORF_MIME_H 23 | 24 | 25 | #include "options.h" 26 | #include "types.h" 27 | 28 | 29 | int mime_init(magic_t *token); 30 | void mime_release(magic_t token); 31 | const char* mime_get_fd (magic_t token,int fd,struct stat *sb); 32 | 33 | #endif -------------------------------------------------------------------------------- /myio.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2020 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "instance.h" 33 | #include "types.h" 34 | #include "myio.h" 35 | 36 | #ifdef HAVE_LIBSSL 37 | /* 38 | * Does a write to an fd_t 39 | * 40 | * If there is an ssl object attached, it will do an ssl write, 41 | * otherwise it will do a normal write. 42 | */ 43 | int myio_write(fd_t fd, const void *buf, size_t count) { 44 | if (fd.ssl) 45 | return SSL_write(fd.ssl, buf, count); 46 | return write(fd.fd, buf, count); 47 | } 48 | 49 | /** 50 | * Does a read from an fd_t. 51 | * 52 | * If there is an ssl object attached, it will do an ssl read, 53 | * otherwise it will do a normal read. 54 | */ 55 | int myio_read(fd_t fd, void *buf, size_t count) { 56 | if (fd.ssl) 57 | return SSL_read(fd.ssl, buf, count); 58 | return read(fd.fd, buf, count); 59 | } 60 | #endif 61 | 62 | /** 63 | Copies count bytes from the file descriptor "from" to the 64 | file descriptor "to". 65 | It is possible to use lseek on the descriptors before calling 66 | this function. 67 | Will not close any descriptor 68 | */ 69 | int fd_copy(fd_t from, fd_t to, off_t count) { 70 | char *buf=malloc(FILEBUF);//Buffer to read from file 71 | int reads,wrote; 72 | 73 | if (buf==NULL) { 74 | #ifdef SERVERDBG 75 | syslog(LOG_CRIT,"Not enough memory to allocate buffers"); 76 | #endif 77 | return ERR_NOMEM; //If no memory is available 78 | } 79 | 80 | //Sends file 81 | while (count>0 && (reads=myio_read(from, buf, FILEBUF 0) { 82 | if (reads == 0) { // Descriptor is over 83 | return ERR_NODATA; 84 | } 85 | count -= reads; 86 | wrote = myio_write(to, buf, reads); 87 | if (wrote != reads) { //Error writing to the descriptor 88 | #ifdef SOCKETDBG 89 | syslog(LOG_ERR, "error writing to the file descriptor"); 90 | #endif 91 | break; 92 | } 93 | } 94 | 95 | free(buf); 96 | return 0; 97 | } 98 | 99 | 100 | /** 101 | Returns true if the specified file exists 102 | */ 103 | bool file_exists(char *file) { 104 | return access(file, R_OK) == 0; 105 | } 106 | 107 | /** 108 | Deletes a directory and its content. 109 | This function is something like rm -rf 110 | 111 | dir is the directory to delete 112 | file is a buffer. Allocated outside because it 113 | will be reused by every recoursive call. 114 | Its size is file_s 115 | 116 | Returns 0 on success 117 | */ 118 | int dir_remove(char * dir) { 119 | /* 120 | If it is a file, removes it 121 | Otherwise list the directory's content, 122 | then do a recoursive call and do 123 | rmdir on self 124 | */ 125 | if (unlink(dir)==0) 126 | return 0; 127 | 128 | DIR *dp = opendir(dir); //Open dir 129 | struct dirent *entry; 130 | 131 | if (dp == NULL) { 132 | return 1; 133 | } 134 | 135 | char*file=malloc(PATH_LEN);//Buffer for path 136 | if (file==NULL) 137 | return ERR_NOMEM; 138 | 139 | //Cycles trough dir's elements 140 | while ((entry=readdir(dp)) != NULL) { //Cycles trough dir's elements 141 | 142 | //skips dir . and .. but not all hidden files 143 | if (entry->d_name[0]=='.' && (entry->d_name[1]==0 || (entry->d_name[1]=='.' && entry->d_name[2]==0))) 144 | continue; 145 | 146 | snprintf(file, PATH_LEN, "%s/%s", dir, entry->d_name); 147 | dir_remove(file); 148 | } 149 | 150 | closedir(dp); 151 | free(file); 152 | return rmdir(dir); 153 | } 154 | 155 | #ifdef WEBDAV 156 | /** 157 | Moves a file. If it is on the same partition it will create a new link and delete the previous link. 158 | Otherwise it will create a new copy and delete the old one. 159 | 160 | Returns 0 on success. 161 | */ 162 | int file_move(char* source, char* dest) { 163 | int retval=rename(source,dest); 164 | 165 | //Not the same device, doing a normal copy 166 | if (retval==-1 && errno==EXDEV) { 167 | retval=file_copy(source,dest); 168 | if (retval==0) 169 | unlink(source); 170 | } 171 | return retval; 172 | } 173 | 174 | /** 175 | Copies a file into another file 176 | 177 | Returns 0 on success 178 | */ 179 | int file_copy(char* source, char* dest) { 180 | int fd_from=-1; 181 | int fd_to=-1; 182 | ssize_t read_,write_; 183 | int retval=0; 184 | char *buf=NULL; 185 | 186 | //Open destination file 187 | if ((fd_to=open(dest,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))<0) { 188 | retval=ERR_FORBIDDEN; 189 | goto escape; 190 | } 191 | 192 | if ((fd_from=open(source,O_RDONLY | O_LARGEFILE))<0) { 193 | retval = ERR_FILENOTFOUND; 194 | goto escape; 195 | } 196 | 197 | buf=malloc(FILEBUF);//Buffer to read from file 198 | if (buf==NULL) { 199 | retval= ERR_NOMEM; 200 | goto escape; 201 | } 202 | 203 | while ((read_=read(fd_from,buf,FILEBUF))>0) { 204 | write_=write(fd_to,buf,read_); 205 | 206 | if (write_!=read_) { 207 | retval= ERR_BRKPIPE; 208 | break; 209 | } 210 | } 211 | 212 | escape: 213 | free(buf); 214 | if (fd_from>=0) close(fd_from); 215 | if (fd_to>=0) close(fd_to); 216 | return retval; 217 | } 218 | 219 | /**This function copies a directory. 220 | The destination directory will be created and 221 | will be filled with the same content of the source directory 222 | 223 | Returns 0 on success 224 | */ 225 | int dir_copy (char* source, char* dest) { 226 | return dir_move_copy(source,dest,COPY); 227 | } 228 | 229 | /**This function moves a directory. 230 | The destination directory will be created and 231 | will be filled with the same content of the source directory. 232 | Then, the source directory will be deleted. 233 | 234 | Returns 0 on success 235 | */ 236 | int dir_move(char* source, char* dest) { 237 | int retval; 238 | 239 | if ((retval=rename(source,dest))==0) { 240 | return 0; 241 | } else if (retval==-1 && errno==EXDEV) { 242 | return dir_move_copy(source,dest,MOVE); 243 | } else { 244 | return 1; 245 | } 246 | 247 | } 248 | 249 | /** 250 | Moves or copies a directory, depending on the method used 251 | 252 | Returns 0 on success 253 | */ 254 | int dir_move_copy (char* source, char* dest,int method) { 255 | struct stat f_prop; //File's property 256 | int retval=0; 257 | 258 | if (mkdir(dest,S_IRWXU | S_IRWXG | S_IRWXO)!=0) {//Attemps to create destination directory 259 | return ERR_FORBIDDEN; 260 | } 261 | 262 | DIR *dp = opendir(source); //Open dir 263 | struct dirent *entry; 264 | int return_code; 265 | 266 | 267 | if (dp == NULL) { 268 | return ERR_FILENOTFOUND; 269 | } 270 | 271 | char*src_file=malloc(PATH_LEN*2);//Buffer for path 272 | if (src_file==NULL) 273 | return ERR_NOMEM; 274 | char* dest_file=src_file+PATH_LEN; 275 | 276 | //Cycles trough dir's elements 277 | while ((entry=readdir(dp)) != NULL) { 278 | 279 | //skips dir . and .. but not all hidden files 280 | if (entry->d_name[0]=='.' && (entry->d_name[1]==0 || (entry->d_name[1]=='.' && entry->d_name[2]==0))) 281 | continue; 282 | 283 | snprintf(src_file,PATH_LEN,"%s/%s",source, entry->d_name); 284 | snprintf(dest_file,PATH_LEN,"%s/%s",dest, entry->d_name); 285 | 286 | stat(src_file, &f_prop); 287 | if (S_ISDIR(f_prop.st_mode)) {//Directory 288 | retval=dir_move_copy(src_file,dest_file,method); 289 | } else {//File 290 | if (method==MOVE) { 291 | retval=file_move(src_file,dest_file); 292 | } else { 293 | retval=file_copy(src_file,dest_file); 294 | } 295 | } 296 | 297 | if (retval!=0) 298 | goto escape; 299 | } 300 | 301 | escape: 302 | closedir(dp); 303 | free(src_file); 304 | 305 | //Removing directory after that its content has been moved 306 | if (retval==0 && method==MOVE) { 307 | return rmdir(source); 308 | } 309 | return retval; 310 | } 311 | #endif 312 | -------------------------------------------------------------------------------- /myio.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2018 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_MYIO_H 22 | #define WEBORF_MYIO_H 23 | 24 | #include "types.h" 25 | #include "options.h" 26 | 27 | #ifdef HAVE_LIBSSL 28 | int myio_write(fd_t fd, const void *buf, size_t count); 29 | int myio_read(fd_t fd, void *buf, size_t count); 30 | static inline int myio_getfd(fd_t fd) { return fd.fd; } 31 | static inline fd_t fd2fd_t(int fd) { 32 | fd_t r; 33 | r.ssl = NULL; 34 | r.fd = fd; 35 | return r; 36 | } 37 | #else 38 | #define myio_read read 39 | #define myio_write write 40 | static inline int myio_getfd(fd_t fd) { return fd; } 41 | static inline fd_t fd2fd_t(int fd) { return fd; } 42 | #endif 43 | 44 | int fd_copy(fd_t from, fd_t to, off_t count); 45 | int dir_remove(char * dir); 46 | bool file_exists(char *file); 47 | 48 | #ifdef WEBDAV 49 | int dir_move_copy (char* source, char* dest,int method); 50 | int file_copy(char* source, char* dest); 51 | int file_move(char* source, char* dest); 52 | int dir_move (char* source, char* dest); 53 | int dir_copy (char* source, char* dest); 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /mynet.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | #include "options.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "types.h" 34 | #include "mynet.h" 35 | 36 | extern weborf_configuration_t weborf_conf; 37 | 38 | 39 | /** 40 | * Creates the server socket and performs some setsockopt 41 | * on it. 42 | * */ 43 | int net_create_server_socket() { 44 | int s; 45 | int val; 46 | 47 | //Creates the socket 48 | #ifdef IPV6 49 | s = socket(PF_INET6, SOCK_STREAM, 0); 50 | #else 51 | s = socket(PF_INET, SOCK_STREAM, 0); 52 | #endif 53 | 54 | 55 | /* 56 | This futile system call is here just because a debian mantainer decided 57 | that the default behavior must be to listen only to IPv6 connections 58 | excluding IPv4 ones. 59 | So this restores the logic and normal behavior of accepting connections 60 | without being racist about the client's address. 61 | */ 62 | 63 | #ifdef IPV6 64 | val=0; 65 | setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val)); 66 | #endif 67 | 68 | val = 1; 69 | //Makes port reusable immediately after termination. 70 | if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) { 71 | perror("ruseaddr(any)"); 72 | syslog(LOG_ERR, "reuseaddr(any)"); 73 | #ifdef IPV6 74 | dprintf(2, "If you don't have IPv6 support in kernel, try recompiling weborf, removing the line '#define IPV6' from options.h\n"); 75 | #endif 76 | return -1; 77 | } 78 | 79 | int flags = fcntl(s, F_GETFL, 0); 80 | flags |= O_NONBLOCK | O_CLOEXEC; 81 | fcntl(s, F_SETFL, flags); 82 | 83 | return s; 84 | } 85 | 86 | #ifdef IPV6 87 | /** 88 | * Accepts an ip address. 89 | * 90 | * Returns a new buffer that needs to be freed by the 91 | * caller of this function. 92 | * 93 | * If addr is an ipv6 address, it is just copied into 94 | * the returned buffer. 95 | * 96 | * If addr is an ipv4 address, the string "::ffff:" is 97 | * prepended to it, turning it into an ipv6 mapped address. 98 | **/ 99 | char* net_map_ipv4(char* addr) { 100 | size_t len = strlen(addr); 101 | char *r; 102 | if (strstr(addr, ":")) { 103 | r = malloc(len + 1); 104 | memcpy(r, addr, len + 1); 105 | } else { 106 | char * prefix = "::ffff:"; 107 | r = malloc(len + strlen(prefix) + 1); 108 | memcpy(r, prefix, strlen(prefix)); 109 | memcpy(r + strlen(prefix), addr, len + 1); 110 | } 111 | return r; 112 | } 113 | #endif 114 | 115 | 116 | void net_bind_and_listen(int s) { 117 | 118 | // Check port number 119 | unsigned int port = strtol(weborf_conf.port, NULL, 0); 120 | if (port < 1 || port > 65535) { 121 | dprintf(2, "Invalid port number: %u\n", port); 122 | exit(4); 123 | } 124 | 125 | // Create socket and set port number 126 | #ifdef IPV6 127 | struct sockaddr_in6 locAddr; //Local and remote address 128 | memset(&locAddr, 0, sizeof(locAddr)); 129 | locAddr.sin6_family = AF_INET6; 130 | locAddr.sin6_port = htons(port); 131 | #else 132 | struct sockaddr_in locAddr; 133 | int ipAddrL = sizeof(struct sockaddr_in); 134 | locAddr.sin_family = AF_INET; 135 | locAddr.sin_port = htons(port); 136 | #endif 137 | 138 | // Set IP address 139 | if (weborf_conf.ip) { 140 | #ifdef IPV6 141 | char * ip = net_map_ipv4(weborf_conf.ip); 142 | int rpt = inet_pton(AF_INET6, ip, &locAddr.sin6_addr); 143 | free(ip); 144 | #else 145 | int rpt = inet_pton(AF_INET, weborf_conf.ip, &locAddr.sin_addr); 146 | #endif 147 | if (rpt == 0) { 148 | dprintf(2, "Invalid IPv%c address: %s\n", IPVERSION, weborf_conf.ip); 149 | exit(2); 150 | } 151 | } else { 152 | weborf_conf.ip = "any"; 153 | #ifdef IPV6 154 | locAddr.sin6_addr = in6addr_any; 155 | #else 156 | inet_pton(AF_INET, "0.0.0.0", &locAddr.sin_addr); 157 | #endif 158 | } 159 | 160 | syslog(LOG_INFO, "Listening on address: %s:%u", weborf_conf.ip, port); 161 | 162 | if (bind(s, (struct sockaddr *) &locAddr, sizeof(locAddr)) < 0) { 163 | perror("trying to bind"); 164 | syslog(LOG_ERR, "Port %u already in use", port); 165 | exit(3); 166 | } 167 | listen(s, MAXQ); //Listen to the socket 168 | } 169 | 170 | 171 | void net_getpeername(int socket,char* buffer) { 172 | 173 | #ifdef IPV6 174 | 175 | struct sockaddr_storage t_addr; 176 | socklen_t addr_l=sizeof(t_addr); 177 | 178 | getpeername(socket, (struct sockaddr *)&t_addr, &addr_l); 179 | 180 | if (t_addr.ss_family==AF_INET) { 181 | struct sockaddr_in *addr =(struct sockaddr_in *)&t_addr; 182 | char temp_buffer[INET_ADDRSTRLEN]; 183 | inet_ntop(AF_INET, &(addr->sin_addr), temp_buffer, INET_ADDRSTRLEN); 184 | snprintf(buffer,INET6_ADDRSTRLEN,"::ffff:%s",temp_buffer); 185 | } else { 186 | struct sockaddr_in6 *addr =(struct sockaddr_in6 *)&t_addr; 187 | inet_ntop(AF_INET6, &(addr->sin6_addr), buffer, INET6_ADDRSTRLEN); 188 | } 189 | #else 190 | struct sockaddr_in addr; 191 | socklen_t addr_l=sizeof(struct sockaddr_in); 192 | 193 | getpeername(socket, (struct sockaddr *)&addr,&addr_l); 194 | inet_ntop(AF_INET, &addr.sin_addr, buffer, INET_ADDRSTRLEN); 195 | #endif 196 | } 197 | -------------------------------------------------------------------------------- /mynet.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_MYNET_H 22 | #define WEBORF_MYNET_H 23 | 24 | #include "types.h" 25 | #include "options.h" 26 | 27 | int net_create_server_socket(); 28 | void net_bind_and_listen(int s); 29 | void net_getpeername(int,char*); 30 | 31 | #ifdef IPV6 32 | char* ip4to6(char*); 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /mystring.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #include "options.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "mystring.h" 29 | 30 | /** 31 | This function converts a string to upper case 32 | */ 33 | void strToUpper(char *str) { 34 | int i = -1; 35 | while (str[++i]) { 36 | str[i] = toupper(str[i]); 37 | } 38 | } 39 | 40 | /** 41 | This function splits the page name from the GET params. 42 | It also sets the value for the page_len field 43 | */ 44 | void split_get_params(connection_t* connection_prop) { 45 | char *separator=strstr(connection_prop->page,"?"); 46 | 47 | if (separator==NULL) { 48 | connection_prop->get_params=NULL; 49 | connection_prop->page_len=strlen(connection_prop->page); 50 | } else { 51 | separator[0]=0; 52 | connection_prop->get_params=separator+1; 53 | connection_prop->page_len=separator-connection_prop->page; 54 | } 55 | } 56 | 57 | 58 | /** 59 | Replaces escape sequences in the form %HEXCODE with the correct char 60 | This is used for URLs, after the transformation the URL will probably 61 | represent a file that exists on filesystem. 62 | Since after this replace the string will be unchanged or shorter, no 63 | additional buffer will be needed. 64 | 65 | This function is in-place, doesn't create copies but changes the original string. 66 | */ 67 | void replaceEscape(char *string) { 68 | char e_seq[3]; 69 | e_seq[2] = 0; 70 | 71 | if (string == NULL) 72 | return; 73 | 74 | //Parses the string 75 | while ((string=strstr(string,"%"))!=NULL) { 76 | e_seq[0] = string[1]; 77 | e_seq[1] = string[2]; 78 | 79 | delChar(string, 0, 2); //Deletes 2 chars from the url 80 | 81 | //Replaces the 3rd character with the char corresponding to the escape 82 | string[0] = strtol(e_seq, NULL, 16); 83 | string++; 84 | } 85 | } 86 | 87 | /** 88 | This function replaces, within the string string, the substring substr with the char with. 89 | 90 | This function is in-place, doesn't create copies but changes the original string. 91 | */ 92 | void strReplace(char *string, char *substr, char with) { 93 | char *pointer; 94 | int substrlen = strlen(substr); 95 | 96 | while ((pointer = strstr(string, substr)) != NULL) { 97 | delChar(pointer, 0, substrlen - 1); 98 | pointer[0] = with; 99 | string=pointer; 100 | } 101 | } 102 | 103 | /** 104 | This function deletes n chars from the string, starting from the position pos. 105 | In case deleting of more chars than the string's len itself, the string will be returned unchanged. 106 | 107 | This function doesn't create copies but changes the original string. 108 | */ 109 | void delChar(char *string, int pos, int n) { 110 | size_t l = strlen(string + pos); 111 | 112 | if (l < n) 113 | return; 114 | l -= n; 115 | memmove(string + pos, string + pos + n, l); 116 | string[l] = 0; 117 | 118 | return; 119 | } 120 | 121 | /** 122 | Returns true if str ends with end 123 | 124 | str String to compare 125 | end second string 126 | size of str 127 | size of end 128 | 129 | If str ends with end, true is returned 130 | false otherwise 131 | */ 132 | bool endsWith(char *str, char *end, size_t len_str, size_t len_end) { 133 | return strcmp(str+len_str-len_end,end)==0; 134 | } 135 | -------------------------------------------------------------------------------- /mystring.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_MYSTRING_H 22 | #define WEBORF_MYSTRING_H 23 | 24 | #include "types.h" 25 | 26 | void split_get_params(connection_t* connection_prop); 27 | bool endsWith(char *str, char *end, size_t len_str, size_t len_end); 28 | void delChar(char *string, int pos, int n); 29 | void strReplace(char *string, char *substr, char with); 30 | void replaceEscape(char *string); 31 | void strToUpper(char *str); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /options.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007-2019 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #include "config.h" 22 | #include //Needed because it defines the _POSIX_IPV6 23 | 24 | #ifndef WEBORF_OPTIONS_H 25 | #define WEBORF_OPTIONS_H 26 | 27 | #define NAME PACKAGE 28 | //#define VERSION PACKAGE_VERSION 29 | #define SIGNATURE NAME "/" VERSION " (GNU/Linux)" 30 | 31 | //----------System 32 | #define ROOTUID 0 //Uid for superuser 33 | #define ROOTGID 0 34 | 35 | //----------Network 36 | #define MAXQ 40 //Queue for connect requests 37 | #define PORT "8080" //Default port 38 | 39 | #ifdef _POSIX_IPV6 //Enables ipv6 if supported 40 | //Delete the following line to use IPv4 instead. 41 | #define IPV6 42 | #endif 43 | 44 | #ifdef IPV6 45 | #define IPVERSION '6' 46 | #else 47 | #define IPVERSION '4' 48 | #endif 49 | 50 | //-----------Threads 51 | #define MAXTHREAD 300 //Max threads 52 | #define INITIALTHREAD 6 //Thread started when free threads are low and when starting 53 | #define LOWTHREAD 3 //Minimum number of free threads, before starting new ones 54 | #define MAXFREETHREAD 6 //Maximum number of free threads, before starting to slowly close them 55 | #define THREADCONTROL 10 //Polling frequence in seconds 56 | 57 | //------------Server 58 | #define INDEX "index.html" //Default index file that weborf will search 59 | #define BASEDIR "/srv/www" //Default basedir 60 | #define READ_TIMEOUT 5000 //Timeout before closing inactive keep-alive connections, in milliseconds 61 | 62 | //------------Buffers 63 | #define INBUFFER 1024 //Size for buffer with the HTTP request 64 | #define FILEBUF 4096 //Size of reads 65 | #define MAXSCRIPTOUT 512000 //Maximum size for a page generated by a script or internally 66 | #define HEADBUF 1024 //Buffer for headers 67 | #define PWDLIMIT 300 //Max size for password 68 | #define INDEXMAXLEN 30 69 | #define NBUFFER 15 //Buffer to contain the string representation of an integer 70 | #define RBUFFER 128 //Buffer to contain a range 71 | #define BUFFERED_READER_SIZE 2048 72 | #define DATEBUFFER 50 //Buffer for text date 73 | #define URI_LEN 256 74 | #define ESCAPED_FNAME_LEN 256 * 3 //To contain escaped filenames, d_name size is 256 on linux 75 | #define PATH_LEN 1024 76 | #define MIMETYPELEN 15 //Size of mimetype string 77 | 78 | //Number of index pages allowed to search 79 | #define MAXINDEXCOUNT 10 80 | 81 | //-------------LIMITS 82 | #define POST_MAX_SIZE 2000000 //Maximum allowed size for POST data 83 | 84 | //-------------HTML 85 | #define HTMLHEAD "\n" \ 86 | "" \ 87 | "" NAME "" \ 88 | "" \ 94 | "

" NAME "

" 95 | #define HTMLFOOT "
" SIGNATURE "
" 96 | #define HTMLLIGHT "white" 97 | #define HTMLDARK "#EAEAEA" 98 | #define HTMLPARENT "#DFDFDF" 99 | 100 | //-------------SCRIPTS 101 | #define SCRPT_TIMEOUT 30 //Timeout for the scripts, in seconds 102 | #define HIDE_CGI_ERRORS //Hides all the errors. 103 | 104 | #define CGI_PHP "/usr/lib/cgi-bin/php" 105 | #define CGI_PY "" 106 | 107 | //-------------COMPRESSING PAGES 108 | //#define __COMPRESSION //enables support for compressing pages, comment to disable 109 | #ifdef __COMPRESSION 110 | #define SIZE_COMPRESS_MIN 512 111 | #define SIZE_COMPRESS_MAX 4000000000 112 | #define GZIPNICE 4 //Nice value for gzip process 113 | #endif 114 | 115 | //The following header can be disabled to increase a little the speed 116 | //#define SEND_LAST_MODIFIED_HEADER 117 | 118 | #ifdef HAVE_LIBMAGIC 119 | #define SEND_MIMETYPES //Enables support to sending the mimetype to the client 120 | #endif 121 | 122 | 123 | //-------------RANGE 124 | #define __RANGE //Enables support to range (partial download) 125 | 126 | //-------------WEBDAV 127 | #define WEBDAV //Enables webdav support 128 | #ifdef WEBDAV 129 | #define MAXPROPCOUNT 40 //Number of supported properties 130 | #define HIDE_HIDDEN_FILES //Hides hidden files 131 | #endif 132 | 133 | //-------------Logging options 134 | //#define THREADDBG 135 | //#define SOCKETDBG 136 | //#define SENDINGDBG 137 | #define SERVERDBG 138 | #define REQUESTDBG 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Giuseppe Pappalardo 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Giuseppe Pappalardo 19 | @author Salvo "LtWorf" Tomaselli 20 | @author Salvo Rinaldi 21 | */ 22 | 23 | #include "options.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "queue.h" 30 | 31 | /** 32 | Inits the syncronized queue, allocating memory. 33 | Requires the syn_queue_t struct and the size of the queue itself. 34 | To deallocate the queue, use the q_free function. 35 | */ 36 | int q_init(syn_queue_t * q, int size) { 37 | q->num = q->head = q->tail = 0; 38 | q->size = size; 39 | 40 | q->data = (int *) malloc(sizeof(int) * size); 41 | 42 | if (q->data == NULL) { //Error, unable to allocate memory 43 | return 1; 44 | } 45 | 46 | pthread_mutex_init(&q->mutex, NULL); 47 | pthread_cond_init(&q->for_space, NULL); 48 | pthread_cond_init(&q->for_data, NULL); 49 | q->n_wait_dt = q->n_wait_sp = 0; 50 | 51 | return 0; 52 | } 53 | 54 | /** Frees the memory taken by the queue. 55 | Requires the pointer to the queue struct 56 | */ 57 | void q_free(syn_queue_t * q) { 58 | free(q->data); 59 | } 60 | 61 | int q_get(syn_queue_t * q, int *val) { 62 | pthread_mutex_lock(&q->mutex); 63 | while (q->num == 0) { 64 | q->n_wait_dt++; 65 | pthread_cond_wait(&q->for_data, &q->mutex); 66 | } 67 | *val = q->data[q->head]; //Sets the value 68 | 69 | q->head = (q->head + 1) % q->size; //Moves the head 70 | q->num--; //Reduces count of the queue 71 | 72 | /*if ((q->num == q->size) && (q->n_wait_sp > 0)) { 73 | q->n_wait_sp--; 74 | pthread_cond_signal(&q->for_space); 75 | } // unlock also needed after signal*/ 76 | 77 | pthread_mutex_unlock(&q->mutex); // or threads blocked on wait 78 | return 0; // will not proceed 79 | } 80 | 81 | 82 | int q_put(syn_queue_t * q, int val) { 83 | pthread_mutex_lock(&q->mutex); 84 | 85 | //Wakes up a sleeping thread 86 | if (q->n_wait_dt > 0) { 87 | q->n_wait_dt--; 88 | pthread_cond_signal(&q->for_data); 89 | } // unlock also needed after signal 90 | 91 | //Fails if queue is full 92 | if (q->num == q->size) { 93 | pthread_mutex_unlock(&q->mutex); // or threads blocked on wait 94 | return 1; // will not proceed 95 | //while (q->num == q->size) { 96 | //q->n_wait_sp++; 97 | //pthread_cond_wait(&q->for_space, &q->mutex); 98 | } 99 | q->data[q->tail] = val; //Set the data in position 100 | 101 | q->tail = (q->tail + 1) % q->size; //Moves the tail 102 | 103 | q->num++; //Increases count of filled positions 104 | 105 | pthread_mutex_unlock(&q->mutex); // or threads blocked on wait 106 | return 0; // will not proceed 107 | } 108 | -------------------------------------------------------------------------------- /queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Giuseppe Pappalardo 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Giuseppe Pappalardo 19 | @author Salvo "LtWorf" Tomaselli 20 | */ 21 | 22 | #ifndef WEBORF_QUEUE_H 23 | #define WEBORF_QUEUE_H 24 | 25 | #include "types.h" 26 | 27 | int q_init(syn_queue_t * q, int size); 28 | 29 | int q_put(syn_queue_t * q, int val); 30 | int q_get(syn_queue_t * q, int *val); 31 | 32 | void q_free(syn_queue_t * q); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /qweborf/.gitignore: -------------------------------------------------------------------------------- 1 | qweborf/main.py 2 | .mypy_cache/ 3 | -------------------------------------------------------------------------------- /qweborf/Makefile: -------------------------------------------------------------------------------- 1 | # Weborf 2 | # Copyright (C) 2019-2022 Salvo "LtWorf" Tomaselli 3 | # 4 | # Weborf is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | # 17 | # author Salvo "LtWorf" Tomaselli 18 | 19 | qweborf/main.py: qweborf/main.ui 20 | pyuic5 qweborf/main.ui > qweborf/main.py 21 | 22 | .PHONY: clean 23 | clean: 24 | $(RM) qweborf/main.py 25 | $(RM) -r build/ 26 | $(RM) -r .mypy_cache/ 27 | 28 | .PHONY: install 29 | install: qweborf/main.py 30 | python3 setup.py install --root=$${DESTDIR:-/} --install-layout=deb 31 | install -D qweborf/qweborf $${DESTDIR:-/}/bin/qweborf 32 | install -D -m644 man/qweborf.1 $${DESTDIR:-/}/usr/share/man/man1/qweborf.1 33 | install -D -m644 integration/qweborf.desktop $${DESTDIR:-/}/usr/share/applications/qweborf.desktop 34 | install -D -m644 integration/qweborf_servicemenu.desktop $${DESTDIR:-/}/usr/share/kservices5/ServiceMenus/qweborf_servicemenu.desktop 35 | install -D -m644 integration/qweborf.png $${DESTDIR:-/}/usr/share/icons/hicolor/256x256/apps/qweborf.png 36 | install -D -m644 integration/qweborf.metainfo.xml $${DESTDIR:-/}/usr/share/metainfo/qweborf.metainfo.xml 37 | 38 | .PHONY: mypy 39 | mypy: 40 | mypy --config-file mypy.conf qweborf 41 | -------------------------------------------------------------------------------- /qweborf/integration/qweborf.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=qweborf 3 | GenericName=qweborf 4 | Keywords=http;NAT;network;share 5 | Comment=Shares files using the HTTP protocol 6 | Comment[it]=Condivide file usando il protocollo HTTP 7 | Exec=qweborf %f 8 | Icon=qweborf 9 | Terminal=0 10 | Type=Application 11 | Categories=Network; 12 | MimeType=inode/directory 13 | X-Purism-FormFactor=Workstation;Mobile; 14 | StartupNotify=true 15 | -------------------------------------------------------------------------------- /qweborf/integration/qweborf.metainfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.ltworf.qweborf 4 | GPL-3+ 5 | GPL-3+ 6 | qweborf 7 | qweborf 8 | qweborf 9 | Shares files using the HTTP protocol 10 | condivide file usando il protocollo HTTP 11 | 12 | 13 |

Qweborf provides an easy to use graphical interface to share local files using the HTTP protocol.

14 |

It can enable writing on the server, webdav, authentication and sending directories as tar.gz.

15 |

It can try to work across NAT.

16 |
17 | 18 | 19 |

Qweborf fornisce un'interfaccia grafica facile da usare per condividere file locali usando il protocollo HTTP.

20 |

Può abilitare la scrittura sul server, WebDAV, l'autenticazione e l'invio di directory come tar.gz.

21 |

Può provare a funzionare attraverso NAT.

22 |
23 | 24 | qweborf 25 | 26 | qweborf.desktop 27 | tiposchi@tiscali.it 28 | Salvo 'LtWorf' Tomaselli 29 | 30 | https://ltworf.github.io/weborf/qweborf.html 31 | https://github.com/ltworf/weborf/issues/ 32 | https://ltworf.github.io/weborf/qweborf.html 33 | https://liberapay.com/ltworf 34 | 35 | 36 | 37 | https://ltworf.github.io/weborf/images/qweborf.png 38 | 39 | 40 | 41 | 42 | Utility 43 | Qt 44 | 45 | 46 | 47 | http 48 | webdav 49 | share 50 | directory 51 | 52 |
53 | -------------------------------------------------------------------------------- /qweborf/integration/qweborf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltworf/weborf/10bb70708c80533c505d721eca88bb17ea4c18c4/qweborf/integration/qweborf.png -------------------------------------------------------------------------------- /qweborf/integration/qweborf_servicemenu.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Service 3 | ServiceTypes=KonqPopupMenu/Plugin 4 | MimeType=inode/directory; 5 | Actions=share; 6 | X-KDE-Priority=TopLevel 7 | X-KDE-StartupNotify=false 8 | 9 | [Desktop Action share] 10 | Name=Share directory via HTTP… 11 | Name[it]=Condividi cartella con HTTP… 12 | Icon=qweborf 13 | Exec=qweborf %f 14 | 15 | [Nemo Action] 16 | Active=true 17 | Name=Share directory via HTTP… 18 | Comment=share local files using the HTTP protocol. 19 | Exec=qweborf %F 20 | Icon-Name=qweborf 21 | Selection=notnone 22 | Extensions=dir; 23 | Quote=double 24 | -------------------------------------------------------------------------------- /qweborf/man/qweborf.1: -------------------------------------------------------------------------------- 1 | .TH "qweborf" "1" 2 | .SH "NAME" 3 | qweborf \(em Shares files using the HTTP protocol. 4 | .SH "SYNOPSIS" 5 | .PP 6 | \fBqweborf\fR 7 | 8 | .SH "DESCRIPTION" 9 | .PP 10 | Qweborf provides an easy to use interface to share local files using the HTTP protocol. 11 | It can enable writing on the server, webdav and authentication. 12 | 13 | .SH "AUTHOR" 14 | .PP 15 | This manual page was written by Salvo 'LtWorf' Tomaselli for 16 | the \fBDebian GNU/Linux\fP system (but may be used by others). Permission is 17 | granted to copy, distribute and/or modify this document under 18 | the terms of the GNU General Public License 19 | version 3 or any later version published by the Free Software Foundation. 20 | -------------------------------------------------------------------------------- /qweborf/mypy.conf: -------------------------------------------------------------------------------- 1 | [mypy] 2 | python_version=3.8 3 | warn_unused_ignores=True 4 | warn_redundant_casts=True 5 | strict_optional=True 6 | scripts_are_modules=True 7 | check_untyped_defs=True 8 | -------------------------------------------------------------------------------- /qweborf/qweborf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltworf/weborf/10bb70708c80533c505d721eca88bb17ea4c18c4/qweborf/qweborf/__init__.py -------------------------------------------------------------------------------- /qweborf/qweborf/__main__.py: -------------------------------------------------------------------------------- 1 | from . import qweborf 2 | if __name__ == "__main__": 3 | qweborf.q_main() 4 | -------------------------------------------------------------------------------- /qweborf/qweborf/nhelper.py: -------------------------------------------------------------------------------- 1 | # Weborf 2 | # Copyright (C) 2011-2020 Salvo "LtWorf" Tomaselli 3 | # 4 | # Weborf is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | # 17 | # original code http://carnivore.it/2010/07/22/python_-_getifaddrs 18 | # edited Salvo "LtWorf" Tomaselli 19 | 20 | from ctypes import * 21 | from socket import AF_INET, AF_INET6, AF_PACKET, inet_ntop 22 | from sys import platform 23 | import subprocess 24 | import re 25 | from typing import List, NamedTuple, Optional 26 | 27 | 28 | def getifaddrs(): 29 | # getifaddr structs 30 | class ifa_ifu_u(Union): 31 | _fields_ = [ 32 | ("ifu_broadaddr", c_void_p), 33 | ("ifu_dstaddr", c_void_p) 34 | ] 35 | 36 | class ifaddrs(Structure): 37 | _fields_ = [ 38 | ("ifa_next", c_void_p), 39 | ("ifa_name", c_char_p), 40 | ("ifa_flags", c_uint), 41 | ("ifa_addr", c_void_p), 42 | ("ifa_netmask", c_void_p), 43 | ("ifa_ifu", ifa_ifu_u), 44 | ("ifa_data", c_void_p) 45 | ] 46 | 47 | # AF_UNKNOWN / generic 48 | class sockaddr(Structure): 49 | if platform.startswith("darwin") or platform.startswith("freebsd"): 50 | _fields_ = [ 51 | ("sa_len", c_uint8), 52 | ("sa_family", c_uint8), 53 | ("sa_data", (c_uint8 * 14))] 54 | else: 55 | _fields_ = [ 56 | ("sa_family", c_uint16), 57 | ("sa_data", (c_uint8 * 14)) 58 | ] 59 | 60 | # AF_INET / IPv4 61 | class in_addr(Union): 62 | _fields_ = [ 63 | ("s_addr", c_uint32), 64 | ] 65 | 66 | class sockaddr_in(Structure): 67 | _fields_ = [ 68 | ("sin_family", c_short), 69 | ("sin_port", c_ushort), 70 | ("sin_addr", in_addr), 71 | ("sin_zero", (c_char * 8)), # padding 72 | ] 73 | 74 | # AF_INET6 / IPv6 75 | class in6_u(Union): 76 | _fields_ = [ 77 | ("u6_addr8", (c_uint8 * 16)), 78 | ("u6_addr16", (c_uint16 * 8)), 79 | ("u6_addr32", (c_uint32 * 4)) 80 | ] 81 | 82 | class in6_addr(Union): 83 | _fields_ = [ 84 | ("in6_u", in6_u), 85 | ] 86 | 87 | class sockaddr_in6(Structure): 88 | _fields_ = [ 89 | ("sin6_family", c_short), 90 | ("sin6_port", c_ushort), 91 | ("sin6_flowinfo", c_uint32), 92 | ("sin6_addr", in6_addr), 93 | ("sin6_scope_id", c_uint32), 94 | ] 95 | 96 | # AF_PACKET / Linux 97 | class sockaddr_ll(Structure): 98 | _fields_ = [ 99 | ("sll_family", c_uint16), 100 | ("sll_protocol", c_uint16), 101 | ("sll_ifindex", c_uint32), 102 | ("sll_hatype", c_uint16), 103 | ("sll_pktype", c_uint8), 104 | ("sll_halen", c_uint8), 105 | ("sll_addr", (c_uint8 * 8)) 106 | ] 107 | 108 | # AF_LINK / BSD|OSX 109 | class sockaddr_dl(Structure): 110 | _fields_ = [ 111 | ("sdl_len", c_uint8), 112 | ("sdl_family", c_uint8), 113 | ("sdl_index", c_uint16), 114 | ("sdl_type", c_uint8), 115 | ("sdl_nlen", c_uint8), 116 | ("sdl_alen", c_uint8), 117 | ("sdl_slen", c_uint8), 118 | ("sdl_data", (c_uint8 * 46)) 119 | ] 120 | 121 | libc = CDLL("libc.so.6") 122 | ptr = c_void_p(None) 123 | result = libc.getifaddrs(pointer(ptr)) 124 | if result: 125 | return None 126 | ifa = ifaddrs.from_address(ptr.value) 127 | result = {} 128 | 129 | while True: 130 | # name = ifa.ifa_name 131 | name = ifa.ifa_name.decode('ascii') # use this for python3 132 | 133 | if name not in result: 134 | result[name] = {} 135 | 136 | if ifa.ifa_addr != None: 137 | sa = sockaddr.from_address(ifa.ifa_addr) 138 | 139 | if sa.sa_family not in result[name]: 140 | result[name][sa.sa_family] = [] 141 | 142 | data = {} 143 | 144 | if sa.sa_family == AF_INET: 145 | if ifa.ifa_addr is not None: 146 | si = sockaddr_in.from_address(ifa.ifa_addr) 147 | data['addr'] = inet_ntop(si.sin_family, si.sin_addr) 148 | if ifa.ifa_netmask is not None: 149 | si = sockaddr_in.from_address(ifa.ifa_netmask) 150 | data['netmask'] = inet_ntop(si.sin_family, si.sin_addr) 151 | 152 | if sa.sa_family == AF_INET6: 153 | if ifa.ifa_addr is not None: 154 | si = sockaddr_in6.from_address(ifa.ifa_addr) 155 | data['addr'] = inet_ntop(si.sin6_family, si.sin6_addr) 156 | if data['addr'].startswith('fe80:'): 157 | data['scope'] = si.sin6_scope_id 158 | if ifa.ifa_netmask is not None: 159 | si = sockaddr_in6.from_address(ifa.ifa_netmask) 160 | data['netmask'] = inet_ntop(si.sin6_family, si.sin6_addr) 161 | 162 | if sa.sa_family == AF_PACKET: 163 | if ifa.ifa_addr is not None: 164 | si = sockaddr_ll.from_address(ifa.ifa_addr) 165 | addr = "" 166 | for i in range(si.sll_halen): 167 | addr += "%02x:" % si.sll_addr[i] 168 | addr = addr[:-1] 169 | data['addr'] = addr 170 | 171 | if len(data) > 0: 172 | result[name][sa.sa_family].append(data) 173 | 174 | if ifa.ifa_next: 175 | ifa = ifaddrs.from_address(ifa.ifa_next) 176 | else: 177 | break 178 | 179 | libc.freeifaddrs(ptr) 180 | return result 181 | 182 | 183 | class Redirection(NamedTuple): 184 | '''This class represents a NAT redirection''' 185 | lport: int 186 | eport: int 187 | ip: str 188 | proto: str 189 | description: str 190 | 191 | def __str__(self) -> str: 192 | return '%s %d->%s:%d\t\'%s\'' % (self.proto, self.eport, self.ip, self.lport, self.description) 193 | 194 | def create_redirection(self) -> bool: 195 | '''Activates the redirection. 196 | Returns true if the redirection becomes active''' 197 | try: 198 | subprocess.check_call( 199 | ['upnpc', '-a', self.ip, str(self.lport), str(self.eport), self.proto] 200 | ) 201 | except: 202 | return False 203 | 204 | for i in get_redirections(): 205 | if i == self: 206 | return True 207 | return False 208 | 209 | def remove_redirection(self) -> None: 210 | subprocess.check_call(['upnpc', '-d', str(self.eport), self.proto]) 211 | 212 | 213 | def getaddrs(ipv6: bool=True) -> List[str]: 214 | '''Returns the list of the IP addresses it is possible to bind to 215 | 216 | ipv6: if true, ONLY ipv6 addresses will be returned (ipv4 will be mapped to ipv6) 217 | ''' 218 | ifaces = getifaddrs() 219 | l_ipv4 = [] 220 | l_ipv6 = [] 221 | 222 | # Cycle the interfaces 223 | for iface in ifaces: 224 | 225 | # Cycle address family 226 | for family in ifaces[iface]: 227 | # Cycle addresses 228 | for addr in ifaces[iface][family]: 229 | if 'addr' in addr: 230 | if family == AF_INET: 231 | l_ipv4.append(str(addr['addr'])) 232 | elif family == AF_INET6: 233 | l_ipv6.append(str(addr['addr'])) 234 | 235 | if ipv6 == True: 236 | # Transforming ipv4 into ipv6-mapped 237 | for i in range(len(l_ipv4)): 238 | l_ipv4[i] = '::ffff:%s' % l_ipv4[i] 239 | return l_ipv4 + l_ipv6 240 | else: 241 | return l_ipv4 242 | 243 | 244 | def open_nat(port: int) -> Optional[Redirection]: 245 | '''Tries to open a port in the nat device 246 | directing it to the current host. 247 | ''' 248 | # Chooses the external port 249 | eport = port 250 | used_ports = {i.eport for i in get_redirections()} 251 | 252 | while True: 253 | if eport in used_ports: 254 | eport += 1 255 | else: 256 | break 257 | 258 | # Chooses the local ip 259 | ip = [i for i in getaddrs(False) if re.match( 260 | r'^10\..*', i) != None or re.match(r'^192\.168\..*', i) != None][0] 261 | 262 | r = Redirection(port, eport, ip, "TCP", "weborf") 263 | 264 | if r.create_redirection(): 265 | return r 266 | return None 267 | 268 | 269 | def externaladdr() -> Optional[str]: 270 | '''Returns the public IP address. 271 | none in case of error''' 272 | out = subprocess.check_output(['external-ip']).decode('ascii').strip() 273 | 274 | if re.match(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', out) == None: 275 | return None 276 | return out 277 | 278 | 279 | def can_redirect() -> bool: 280 | '''Returns true if upnpc is installed and NAT traversal can 281 | be attempted''' 282 | 283 | try: 284 | subprocess.call(['upnpc'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) 285 | return True 286 | except: 287 | return False 288 | 289 | 290 | def get_redirections() -> List[Redirection]: 291 | '''Returns a list of current NAT redirections''' 292 | out = subprocess.check_output(['upnpc', '-l']).decode('ascii').strip().split('\n') 293 | 294 | redirections = [] 295 | 296 | for i in out: 297 | m = re.match( 298 | r'[ ]*([0-9]+)[ ]+(UDP|TCP)[ ]+([0-9]+)->([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):([0-9]+)[ ]+\'(.*)\' \'\'', i) 299 | if m is not None: 300 | redirect = m.groups() 301 | r = Redirection( 302 | int(redirect[4]), 303 | int(redirect[2]), 304 | redirect[3], 305 | redirect[1], 306 | redirect[5], 307 | ) 308 | redirections.append(r) 309 | return redirections 310 | 311 | 312 | def printifconfig() -> None: 313 | ifaces = getifaddrs() 314 | for iface in ifaces: 315 | print(iface) 316 | for family in ifaces[iface]: 317 | print("\t%s" % 318 | {AF_INET: 'IPv4', AF_INET6: 'IPv6', AF_PACKET: 'HW'}[family]) 319 | for addr in ifaces[iface][family]: 320 | for i in ['addr', 'netmask', 'scope']: 321 | if i in addr: 322 | print("\t\t%s %s" % (i, str(addr[i]))) 323 | print("") 324 | -------------------------------------------------------------------------------- /qweborf/qweborf/qweborf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # Weborf 4 | # Copyright (C) 2010 Salvo "LtWorf" Tomaselli 5 | # 6 | # Relational is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | # 19 | # author Salvo "LtWorf" Tomaselli 20 | 21 | import qweborf.qweborf 22 | qweborf.qweborf.q_main() 23 | -------------------------------------------------------------------------------- /qweborf/qweborf/qweborf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Weborf 4 | # Copyright (C) 2010-2023 Salvo "LtWorf" Tomaselli 5 | # 6 | # Weborf is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | # 19 | # author Salvo "LtWorf" Tomaselli 20 | 21 | from PyQt5 import QtGui, QtWidgets, QtCore 22 | import sys 23 | import os 24 | 25 | import qweborf.main as main 26 | import qweborf.whelper as whelper 27 | import qweborf.nhelper as nhelper 28 | 29 | 30 | class qweborfForm (QtWidgets.QWidget): 31 | 32 | DBG_DEFAULT = 0 33 | DBG_WARNING = 1 34 | DBG_ERROR = 2 35 | DBG_NOTICE = 3 36 | 37 | def setUi(self, ui) -> None: 38 | self.settings = QtCore.QSettings() 39 | self.ui = ui 40 | self.weborf = whelper.weborf_runner(self) 41 | self.started = False 42 | 43 | if self.weborf.version < '0.13': 44 | sys.exit('Ancient version of weborf detected') 45 | 46 | if not self.weborf.webdav: 47 | self.ui.chkDav.setEnabled(False) 48 | self.ui.chkWrite.setEnabled(False) 49 | 50 | if not self.weborf.https: 51 | self.ui.txtKey.setEnabled(False) 52 | self.ui.txtCert.setEnabled(False) 53 | self.ui.cmdOpenCert.setEnabled(False) 54 | self.ui.cmdOpenKey.setEnabled(False) 55 | 56 | # Listing addresses 57 | for i in nhelper.getaddrs(self.weborf.ipv6): 58 | self.ui.cmbAddress.addItem(i, None) 59 | 60 | self.ui.chkNAT.setEnabled(nhelper.can_redirect()) 61 | 62 | self.defaultdir = QtCore.QStandardPaths.writableLocation( 63 | QtCore.QStandardPaths.HomeLocation) 64 | 65 | initialdir = self.settings.value('main/defaultdir', self.defaultdir) 66 | 67 | self.ui.chkDav.setChecked(self.settings.value('dav/dav', 'false') == 'true') 68 | self.ui.chkWrite.setChecked(self.settings.value('dav/dav_write', 'false') == 'true') 69 | self.ui.chkEnableAuth.setChecked(self.settings.value('auth/auth', 'false') == 'true') 70 | self.ui.txtPassword.setText(self.settings.value('auth/password', '')) 71 | self.ui.txtUsername.setText(self.settings.value('auth/username', '')) 72 | 73 | self.ui.chkTar.setChecked(self.settings.value('tar/tar', 'false') == 'true') 74 | 75 | self.ui.txtCert.setText(self.settings.value('ssl/cert', '')) 76 | self.ui.txtKey.setText(self.settings.value('ssl/key', '')) 77 | 78 | self.ui.chkNAT.setChecked(self.settings.value('net/nat', 'false') == 'true') 79 | self.ui.cmbAddress.setCurrentIndex(int(self.settings.value('net/address', 0))) 80 | self.ui.spinPort.setValue(int(self.settings.value('net/port', 8080))) 81 | 82 | if len(sys.argv) > 1 and os.path.exists(sys.argv[1]): 83 | initialdir = sys.argv[1] 84 | 85 | self.ui.txtPath.setText(initialdir) 86 | self.stop_sharing() 87 | 88 | def logger(self, data, level=DBG_DEFAULT): 89 | '''logs an entry, showing it in the GUI''' 90 | if level == self.DBG_WARNING: 91 | data = 'WARNING: %s' % data 92 | elif level == self.DBG_ERROR: 93 | data = 'ERROR: %s' % data 94 | elif level == self.DBG_NOTICE: 95 | data = 'NOTICE: %s' % data 96 | self.ui.txtLog.moveCursor(QtGui.QTextCursor.End) 97 | self.ui.txtLog.insertHtml(data + '
') 98 | self.ui.txtLog.moveCursor(QtGui.QTextCursor.End) 99 | 100 | def setDefaultValues(self): 101 | '''Sets default values into the form GUI. It has to be 102 | called after the form has been initialized''' 103 | pass 104 | 105 | def stop_sharing(self): 106 | self.weborf.stop() 107 | self.ui.cmdStart.setVisible(True) 108 | self.ui.cmdStop.setVisible(False) 109 | self.ui.tabWidget.setVisible(True) 110 | self.ui.LogLayout.setVisible(False) 111 | self.started = False 112 | 113 | def save_settings(self): 114 | self.settings.setValue('main/defaultdir', self.ui.txtPath.text()) 115 | self.settings.setValue('dav/dav', self.ui.chkDav.isChecked()) 116 | self.settings.setValue('dav/dav_write', self.ui.chkWrite.isChecked()) 117 | self.settings.setValue('auth/auth', self.ui.chkEnableAuth.isChecked()) 118 | self.settings.setValue('auth/password', self.ui.txtPassword.text()) 119 | self.settings.setValue('auth/username', self.ui.txtUsername.text()) 120 | self.settings.setValue('tar/tar', self.ui.chkTar.isChecked()) 121 | self.settings.setValue('ssl/cert', self.ui.txtCert.text()) 122 | self.settings.setValue('ssl/key', self.ui.txtKey.text()) 123 | self.settings.setValue('net/nat', self.ui.chkNAT.isChecked()) 124 | self.settings.setValue('net/address', self.ui.cmbAddress.currentIndex()) 125 | self.settings.setValue('net/port', self.ui.spinPort.value()) 126 | 127 | def about(self): 128 | 129 | self.logger('
Qweborf 1.0') 130 | self.logger('This program comes with ABSOLUTELY NO WARRANTY.' 131 | ' This is free software, and you are welcome to redistribute it under certain conditions.' 132 | ' For details see the GPLv3 Licese.') 133 | self.logger( 134 | 'Homepage') 135 | self.logger( 136 | 'Salvo \'LtWorf\' Tomaselli <tiposchi@tiscali.it>') 137 | 138 | def terminate(self): 139 | if self.started: 140 | self.stop_sharing() 141 | sys.exit(0) 142 | 143 | def start_sharing(self): 144 | 145 | options = {} # Dictionary with the chosen options 146 | 147 | options['path'] = self.ui.txtPath.text() 148 | 149 | if self.ui.chkEnableAuth.isChecked(): 150 | options['username'] = self.ui.txtUsername.text() 151 | options['password'] = self.ui.txtPassword.text() 152 | else: 153 | options['username'] = None 154 | options['password'] = None 155 | 156 | if self.ui.txtKey.text() or self.ui.txtCert.text(): 157 | options['key'] = self.ui.txtKey.text() 158 | options['cert'] = self.ui.txtCert.text() 159 | else: 160 | options['key'] = None 161 | options['cert'] = None 162 | 163 | options['port'] = self.ui.spinPort.value() 164 | 165 | options['dav'] = self.ui.chkDav.isChecked() 166 | if self.ui.chkDav.isChecked(): 167 | options['write'] = self.ui.chkWrite.isChecked() 168 | else: 169 | options['write'] = False 170 | 171 | options['tar'] = self.ui.chkTar.isChecked() 172 | 173 | if self.ui.cmbAddress.currentIndex() == 0: 174 | options['ip'] = None 175 | else: 176 | options['ip'] = str(self.ui.cmbAddress.currentText()) 177 | 178 | if self.weborf.start(options): 179 | self.ui.cmdStart.setVisible(False) 180 | self.ui.cmdStop.setVisible(True) 181 | self.ui.tabWidget.setVisible(False) 182 | self.ui.LogLayout.setVisible(True) 183 | self.started = True 184 | 185 | if self.ui.chkNAT.isChecked() and self.started==True: 186 | self.logger('Trying to use UPnP to open a redirection in the NAT device. Please wait...') 187 | QtCore.QCoreApplication.processEvents() 188 | external_addr = nhelper.externaladdr() 189 | QtCore.QCoreApplication.processEvents() 190 | self.logger('Public IP address %s' % str(external_addr)) 191 | QtCore.QCoreApplication.processEvents() 192 | if external_addr is not None: 193 | redirection=nhelper.open_nat(options['port']) 194 | if redirection is not None: 195 | self.redirection=redirection 196 | url='http://%s:%d/' % (external_addr,redirection.eport) 197 | logentry='Public address: %s' % (url,url) 198 | self.logger(logentry) 199 | else: 200 | self.logger('Could not create NAT route') 201 | else: 202 | self.logger('Could not find the external IP address') 203 | 204 | def select_cert(self) -> None: 205 | fname = QtWidgets.QFileDialog.getOpenFileName( 206 | self, 207 | 'Certificate', 208 | self.ui.txtCert.text(), 209 | filter='PEM certificates(*.pem);;All files(*)', 210 | )[0] 211 | if fname: 212 | self.ui.txtCert.setText(fname) 213 | 214 | 215 | def select_key(self) -> None: 216 | fname = QtWidgets.QFileDialog.getOpenFileName( 217 | self, 218 | 'Certificate', 219 | self.ui.txtKey.text(), 220 | )[0] 221 | if fname: 222 | self.ui.txtKey.setText(fname) 223 | 224 | def select_path(self) -> None: 225 | current = self.ui.txtPath.text() 226 | if len(current) == 0: 227 | current = self.defaultdir 228 | dirname = QtWidgets.QFileDialog.getExistingDirectory( 229 | self, 230 | 'Directory to share', 231 | current, 232 | QtWidgets.QFileDialog.ShowDirsOnly 233 | ) 234 | if len(dirname) > 0: 235 | self.ui.txtPath.setText(dirname) 236 | 237 | 238 | def q_main() -> None: 239 | import sys 240 | app = QtWidgets.QApplication(sys.argv) 241 | app.setOrganizationName('weborf') 242 | app.setApplicationName('qweborf') 243 | app.setOrganizationDomain("org.ltworf") 244 | Form = qweborfForm() 245 | ui = main.Ui_Form() 246 | ui.setupUi(Form) 247 | Form.setUi(ui) 248 | Form.show() 249 | res = app.exec_() 250 | Form.terminate() 251 | sys.exit(res) 252 | 253 | if __name__ == "__main__": 254 | q_main() 255 | -------------------------------------------------------------------------------- /qweborf/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | version='1.0', 5 | name='qweborf', 6 | author="Salvo 'LtWorf' Tomaselli", 7 | author_email='tiposchi@tiscali.it', 8 | maintainer="Salvo 'LtWorf' Tomaselli", 9 | maintainer_email='tiposchi@tiscali.it', 10 | url='https://ltworf.github.io/weborf/', 11 | license='GPL3', 12 | packages=('qweborf',), 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /testsuite/cachedir: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | # Test that it fails with a non existing cache directory 5 | if "$BINNAME" -db site1 -p 12352 --cache "/tmp/fakecachedir" --index nonexisting; then 6 | exit 1 7 | fi 8 | 9 | CACHE_DIR=$(mktemp -d) 10 | "$BINNAME" -b site1 -p 12352 --cache $CACHE_DIR --index nonexisting & 11 | WEBORF_PID=$(jobs -p) 12 | 13 | function cleanup () { 14 | kill -9 $WEBORF_PID 15 | ls "$CACHE_DIR" 16 | rm -rf "$CACHE_DIR" 17 | rm -f site1/cachedir.test 18 | } 19 | trap cleanup EXIT 20 | 21 | curl -s http://localhost:12352/ 22 | 23 | [[ "$(ls $CACHE_DIR | wc -l)" = 1 ]] 24 | curl -s http://localhost:12352/ | diff - $CACHE_DIR/* 25 | 26 | touch site1/cachedir.test 27 | sleep 1.1 28 | curl -s http://localhost:12352/ | grep cachedir.test 29 | 30 | rm site1/cachedir.test 31 | sleep 1.1 32 | 33 | if curl -s http://localhost:12352/ | grep cachedir.test; then 34 | exit 1 35 | fi 36 | [[ "$(ls $CACHE_DIR | wc -l)" = 3 ]] 37 | -------------------------------------------------------------------------------- /testsuite/cert/certificate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIETzCCAzegAwIBAgIUZ9/1lFZ0G8yxdd+kgTkvQvLY6aowDQYJKoZIhvcNAQEL 3 | BQAwgbYxCzAJBgNVBAYTAklUMQ8wDQYDVQQIDAZTaWNpbHkxEDAOBgNVBAcMB0Nh 4 | dGFuaWExGzAZBgNVBAoMElNhbGxvcCBDb3Jwb3JhdGlvbjEvMC0GA1UECwwmRGVw 5 | YXJ0bWVudCBvZiBkZXBhcnRtZW50YWwgZGVwYXJ0bWVudHMxEjAQBgNVBAMMCWxv 6 | Y2FsaG9zdDEiMCAGCSqGSIb3DQEJARYTdGlwb3NjaGlAdGlzY2FsaS5pdDAeFw0y 7 | MDEyMjAyMzUxMTFaFw0yMTEyMjAyMzUxMTFaMIG2MQswCQYDVQQGEwJJVDEPMA0G 8 | A1UECAwGU2ljaWx5MRAwDgYDVQQHDAdDYXRhbmlhMRswGQYDVQQKDBJTYWxsb3Ag 9 | Q29ycG9yYXRpb24xLzAtBgNVBAsMJkRlcGFydG1lbnQgb2YgZGVwYXJ0bWVudGFs 10 | IGRlcGFydG1lbnRzMRIwEAYDVQQDDAlsb2NhbGhvc3QxIjAgBgkqhkiG9w0BCQEW 11 | E3RpcG9zY2hpQHRpc2NhbGkuaXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 12 | AoIBAQDoQ+PidmP30luSANOS0XMfrFTP2rfo+D8Ed+RX/WlMNY05i0vpbk9OvKHi 13 | w80LQwDC+PUrpQE07MzIhoOXhmW9y1u4xeyyUORsQX2FgH8wz4mczjQQc5vlMoOM 14 | hJ0Hri2DDKN4Zt+YErgS3taRr75KS/mgsj6/X9nXIShFanpnae2fuL1xYxdsVf8u 15 | xT1zyJ7n4AoFiGxd++HtNlSxpAWfgpozpgNcpBXIUWlIMM5BM+YQNaAtHVAz446N 16 | dOGG6jCL6OJGtHUnY/p1NbQ5hnNuTDVgXwMwutI0u0Au6wtbSaUWc1PHPhIpLvWX 17 | IN7CEpoMn3Mp+wEKH/PBn57nCxOnAgMBAAGjUzBRMB0GA1UdDgQWBBT9SIAVbzyI 18 | DDbVQryS9kma23d0ejAfBgNVHSMEGDAWgBT9SIAVbzyIDDbVQryS9kma23d0ejAP 19 | BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDOPYNeXt3B/nJcnFRq 20 | s825fPiNPwyRw0fhm4+As8RL7JFPgnlszE0GzlxH+cdcfBUtJXT8IE8WCKNU1Sqb 21 | 4kN84xX0OJaL2TbbaZqzmW8jEh0ds2Z/dDTeKLNxhdBWviZfJxHTa3s5r5LW81E0 22 | iJyR/im/x630gKIUBlyKxJAn1kw4T4PK/7gvoMRfpbfLkN7Ms2gTEXwps6IwZjNz 23 | 8Pz0XF6Yct4kTanQcChH+cKSL8yYn72EW9/qtzGXc0JPSlBwjoFoV46oOdpPDX6F 24 | RMdDbpa9CCUUA0L6woJdmgUkh8wRdeZnT2h73jCVK8mr2BCkeXMAaoLmG3Z+XPJc 25 | iDAE 26 | -----END CERTIFICATE----- 27 | -------------------------------------------------------------------------------- /testsuite/cert/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDoQ+PidmP30luS 3 | ANOS0XMfrFTP2rfo+D8Ed+RX/WlMNY05i0vpbk9OvKHiw80LQwDC+PUrpQE07MzI 4 | hoOXhmW9y1u4xeyyUORsQX2FgH8wz4mczjQQc5vlMoOMhJ0Hri2DDKN4Zt+YErgS 5 | 3taRr75KS/mgsj6/X9nXIShFanpnae2fuL1xYxdsVf8uxT1zyJ7n4AoFiGxd++Ht 6 | NlSxpAWfgpozpgNcpBXIUWlIMM5BM+YQNaAtHVAz446NdOGG6jCL6OJGtHUnY/p1 7 | NbQ5hnNuTDVgXwMwutI0u0Au6wtbSaUWc1PHPhIpLvWXIN7CEpoMn3Mp+wEKH/PB 8 | n57nCxOnAgMBAAECggEBAM6mIKoLlbQXh/tmGtfk3F3Q0QDB46E2xbKvDQ2wXLA+ 9 | cTFCmz7MM2mlcQ82EEe1zIasRE4Zl/JDwYukCo6VOA5eUXQbPRYF3MXomspd4kxG 10 | SnSmDjKY+Zo5kEtEbgY4VSvk4citFsDR3s6DTzr9tvuZjzcHf8Z7fHDoglEIhHFe 11 | XnKdADbQAYYyQKg87GRfiYiDKnY3/n557R2Eu1AJg+AZpX/+BkU7Y8JUIgBUDFAC 12 | AuC3JBAvSHQuOEhvhA6tBtb/jBM4b63H8BUgBhWT2DBWBgVLUFJZ2BxawY+wwI+e 13 | wGMxqFNVSgAGZH9Ynhzsy3edF7LyxKHxLEqWFAPQ84kCgYEA/8ncRwiTSNDQMq9+ 14 | OLpxgwQMmNpB11937V4WolfGgEZmNoU0tNBzku5qRloz5X+wOaMmPkFM2WqGtxcf 15 | yc4s9Dn9JIDR+L/jmclEd3qrqaV8wL9J80DqOO/QnfGUd6t6CucbU9AR9tNhhtDX 16 | U2XYx86qXOAifdeD4e+RQeKTdoUCgYEA6HUNAyqjZqsQzvMCoXpFvszN0o0GqdQ4 17 | iexLENnghjk1O2arnncJvDIKapDZhi2ObRddHZVGCCRZzkvtJvAcT9pQ2PoY94ce 18 | Uq3dZ6i5EinvFj0SYsNg+941Qf7hAnR6SJbsBAAWJP8/k5W4Wys3WQVtsKej6JUH 19 | uKTLN+EmpzsCgYEA9tXKXzX0Q6FWOINHz+CDp8XhjiOYxAiZx5MzTmhb4u+MtXIo 20 | IZDC5vhx0AA98msdGRHK1urXCTwWUlrbTzhKA0huc6podZ5fOcmS66WSQHy0/Z/a 21 | 8gYjwNwTukclWbI9bIYGxgOVQlZL1/hywkUXRAG4PzX/sualmwM/bpACc60CgYBl 22 | uhOftyEa5PHOHvqfv+qVvPq1kZHA8GZttUKEdVSUaKSrAhtIlb9k5GE6kXkgBv+1 23 | LexJ7fFfzsieRwvZZmp9Z4TJ72jNqgvTEtM5cdTL5h4DFWbeYbInhu63mtrNQDvj 24 | WGigt4j5V9pys6qh+x+VjZKbJEHOnqlqXHOyWI2Z0QKBgQCxHqLJlG4SmQIi9EyH 25 | 4tz+crRLWIUTQnVp3rTkv3B6TqJvgmJEeidCTsyWnV1jqzGPYXJLx/mbQRxcLHj3 26 | NqejvlUpHfn8Ya/HIc8+Ar5gAVf/OxhNgRd0/yPgV+kl7PgjF5JVeuvszSUaXKRy 27 | +mtHIB6/uneWb/xEk5hAiD0W6w== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /testsuite/cgi: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12350 --yesexec --cgi .py,/usr/bin/python3 5 | 6 | curl -vs http://localhost:12350/cgi.py 7 | curl -vs -H 'If-None-Match: "1545650587"' http://localhost:12350/cgi.py | grep 1545650587 8 | curl -vs http://localhost:12350/cgi.py\?ciccio | grep ciccio 9 | curl -vs --data "lallallero" http://localhost:12350/cgi.py | grep lallallero 10 | -------------------------------------------------------------------------------- /testsuite/etag: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12349 5 | 6 | # ETag header is there 7 | curl -sv http://127.0.0.1:12349/robots.txt |& grep ETag 8 | 9 | ETAG=$(curl -sv http://127.0.0.1:12349/robots.txt |& grep ETag | cut -d\ -f3 | tr -d '\r') 10 | 11 | CACHED=$(curl -vs -H "If-None-Match: $ETAG" http://localhost:12349/robots.txt) 12 | [[ $(printf $CACHED | wc -c) = 0 ]] 13 | 14 | 15 | NON_CACHED=$(curl -vs -H 'If-None-Match: "aaaa"' http://localhost:12349/robots.txt) 16 | [[ "$NON_CACHED" = $(cat site1/robots.txt) ]] 17 | 18 | 19 | CACHED=$(curl -vs -H "If-Range: $ETAG" --range 0-3 http://localhost:12349/robots.txt) 20 | [[ $(printf $CACHED | wc -c) = 4 ]] 21 | 22 | 23 | CACHED=$(curl -vs -H 'If-Range: "qwe"' --range 0-3 http://localhost:12349/robots.txt) 24 | [[ $(printf $CACHED | wc -c) != 4 ]] 25 | -------------------------------------------------------------------------------- /testsuite/functions.sh: -------------------------------------------------------------------------------- 1 | # Helper script, does nothing. 2 | set -mex 3 | cd $(dirname $0) 4 | 5 | if [ -n "$AUTOPKGTEST_TMP" ]; then 6 | # Run system weborf in autopkgtest 7 | BINNAME=weborf 8 | else 9 | BINNAME=../weborf 10 | fi 11 | 12 | function cleanup () { 13 | if [[ -n "$WEBORF_PID" ]]; then 14 | kill -9 "$WEBORF_PID" 15 | fi 16 | } 17 | trap cleanup EXIT 18 | 19 | 20 | function run_weborf () { 21 | "$BINNAME" $@ & 22 | WEBORF_PID=$(jobs -p) 23 | 24 | sleep 0.2 25 | # Wait for it to be ready 26 | if [[ $(ls /proc/$WEBORF_PID/fd/ | wc -l) -lt 4 ]]; then 27 | sleep 2 28 | fi 29 | } 30 | -------------------------------------------------------------------------------- /testsuite/index_file: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12351 --index index.txt,index.dat 5 | 6 | [[ $(curl -Lvs http://localhost:12351/sub1/) = $(cat site1/sub1/index.txt) ]] 7 | [[ $(curl -Lvs http://localhost:12351/sub2/) = $(cat site1/sub2/index.dat) ]] 8 | 9 | [[ $(curl -Lvs http://localhost:12351/sub1) = $(cat site1/sub1/index.txt) ]] 10 | [[ $(curl -Lvs http://localhost:12351/sub2) = $(cat site1/sub2/index.dat) ]] 11 | -------------------------------------------------------------------------------- /testsuite/ip_listener: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12340 --ip 127.0.0.2 5 | 6 | if curl -s http://127.0.0.1:12340/robots.txt; then 7 | exit 1 8 | fi 9 | 10 | curl -s http://127.0.0.2:12340/robots.txt 11 | -------------------------------------------------------------------------------- /testsuite/range: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12348 5 | 6 | # ETag header is there 7 | curl -sv http://127.0.0.1:12348/robots.txt |& grep Content-Length 8 | CONTENT_LENGTH=$(curl -sv http://127.0.0.1:12348/robots.txt |& grep Content-Length | cut -d\ -f3 | tr -d '\r') 9 | ROBOTS="$( 10 | curl -s -r0-5 http://127.0.0.1:12348/robots.txt; 11 | curl -s -r6-10 http://127.0.0.1:12348/robots.txt; 12 | curl -s -r11- http://127.0.0.1:12348/robots.txt)" 13 | 14 | curl -s -r0-$(($CONTENT_LENGTH - 1)) http://127.0.0.1:12348/robots.txt 15 | 16 | if curl -s --fail -r0-$CONTENT_LENGTH http://127.0.0.1:12348/robots.txt; then 17 | exit 1 18 | fi 19 | 20 | [[ $(curl -s -r0-0 http://127.0.0.1:12348/robots.txt | wc -c) = 1 ]] 21 | 22 | [[ "$ROBOTS" = $(cat site1/robots.txt) ]] 23 | -------------------------------------------------------------------------------- /testsuite/site1/cgi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import os 3 | print('X-Extra: Ciao\r\n', end='') 4 | print('Content-Type: text/plain\r\n', end='') 5 | print('\r\n', end='') 6 | 7 | for k,v in os.environ.items(): 8 | print(f'{k}\t{v}') 9 | 10 | if 'CONTENT_LENGTH' in os.environ: 11 | print('============= POST') 12 | data = os.read(0, int(os.environ['CONTENT_LENGTH'])) 13 | print(data) 14 | -------------------------------------------------------------------------------- /testsuite/site1/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ltworf/weborf/10bb70708c80533c505d721eca88bb17ea4c18c4/testsuite/site1/empty -------------------------------------------------------------------------------- /testsuite/site1/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /testsuite/site1/sub1/index.dat: -------------------------------------------------------------------------------- 1 | pappero 2 | -------------------------------------------------------------------------------- /testsuite/site1/sub1/index.txt: -------------------------------------------------------------------------------- 1 | lollellero 2 | -------------------------------------------------------------------------------- /testsuite/site1/sub2/index.dat: -------------------------------------------------------------------------------- 1 | qbetto 2 | -------------------------------------------------------------------------------- /testsuite/site1http: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12345 5 | 6 | ROBOTS=$(curl -s http://127.0.0.1:12345/robots.txt) 7 | [[ "$ROBOTS" = $(cat site1/robots.txt) ]] 8 | 9 | ROBOTS=$(curl -s http://127.0.0.1:12345/empty) 10 | [[ "$ROBOTS" = '' ]] 11 | 12 | curl -s http://127.0.0.1:12345/cgi.py | grep "import os" 13 | -------------------------------------------------------------------------------- /testsuite/site1https: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12346 --cert cert/certificate.pem --key cert/key.pem 5 | 6 | ROBOTS=$(curl -s -k https://127.0.0.1:12346/robots.txt) 7 | 8 | [[ "$ROBOTS" = $(cat site1/robots.txt) ]] 9 | -------------------------------------------------------------------------------- /testsuite/site1mimetype: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -b site1 -p 12347 --mime 5 | 6 | function cleanup () { 7 | kill -9 $WEBORF_PID 8 | } 9 | trap cleanup EXIT 10 | 11 | curl -v http://127.0.0.1:12347/robots.txt |& grep Content-Type | grep text/ 12 | -------------------------------------------------------------------------------- /testsuite/site2/site2.txt: -------------------------------------------------------------------------------- 1 | site2 2 | -------------------------------------------------------------------------------- /testsuite/version_and_help: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | "$BINNAME" --help 5 | "$BINNAME" --version 6 | "$BINNAME" -k 7 | -------------------------------------------------------------------------------- /testsuite/vhost: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . testsuite/functions.sh 3 | 4 | run_weborf -p 12342 --virtual localhost:12342=site1,127.0.0.1:12342=site2 -b site1 5 | 6 | # ETag header is there 7 | curl -vs http://localhost:12342/robots.txt | grep User-agent 8 | 9 | curl -vs http://127.0.0.1:12342/site2.txt | grep site2 10 | -------------------------------------------------------------------------------- /types.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2010-2018 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_TYPES_H 22 | #define WEBORF_TYPES_H 23 | 24 | #include "options.h" 25 | 26 | #include //Adds boolean type 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #ifdef HAVE_LIBSSL 33 | #include 34 | 35 | typedef struct { 36 | int fd; 37 | SSL *ssl; 38 | } fd_t; 39 | #else 40 | typedef int fd_t; 41 | #endif 42 | 43 | #ifdef SEND_MIMETYPES 44 | #include 45 | #else 46 | typedef void* magic_t; 47 | #endif 48 | 49 | typedef struct { 50 | long int id; //ID of the thread 51 | magic_t mime_token; //Token for libmagic 52 | } thread_prop_t; 53 | 54 | typedef struct { 55 | ssize_t len; //length of the array 56 | char *data[MAXINDEXCOUNT]; //Array containing pointers 57 | int data_l[MAXINDEXCOUNT]; //Array containing len of strings 58 | } array_ll; 59 | 60 | typedef struct { 61 | int num, size; //Filled positions in the queue, and its maximum size 62 | int head, tail; //pointers to head and tail of the round queue 63 | int *data; //Socket with client 64 | 65 | #ifdef IPV6 66 | struct sockaddr_in6 *addr; //Local and remote address 67 | #else 68 | struct sockaddr_in *addr; 69 | #endif 70 | 71 | pthread_mutex_t mutex; //mutex to modify the queue 72 | pthread_cond_t for_space, for_data; 73 | int n_wait_sp, n_wait_dt; 74 | } syn_queue_t; 75 | 76 | typedef struct { 77 | fd_t sock; //File and ssl descriptor for the socket 78 | #ifdef IPV6 79 | char ip_addr[INET6_ADDRSTRLEN]; //ip address in string format 80 | #else 81 | char ip_addr[INET_ADDRSTRLEN]; 82 | #endif 83 | 84 | bool keep_alive; //True if we are using pipelining 85 | short int protocol_version; //See defines like HTTP_something 86 | int method_id; //Index of the http method used (GET, POST) 87 | char *method; //String version of the http method used 88 | char *http_param; //Param string 89 | char *page; //Requested URI 90 | ssize_t page_len; //Lengh of the page string 91 | char *get_params; //Params in the URI, after the ? char 92 | char *strfile; //File on filesystem 93 | ssize_t strfile_len; //Length of string strfile 94 | struct stat strfile_stat; //Stat of strfile 95 | int strfile_fd; //File descriptor for strfile 96 | char *basedir; //Basedir for the host 97 | unsigned int status_code; //HTTP status code 98 | 99 | } connection_t; 100 | 101 | typedef struct { 102 | ssize_t len; //length of the string 103 | char *data; //Pointer to string 104 | } string_t; 105 | 106 | typedef struct { 107 | pthread_mutex_t mutex; //Mutex to access this struct 108 | unsigned int free; //Free threads 109 | unsigned int count; //thread count 110 | } t_thread_info; 111 | 112 | typedef struct { 113 | char *basedir; 114 | char* authsock; //Executable that will authenticate 115 | uid_t uid; //Uid to use after bind 116 | gid_t gid; //gid to use after bind 117 | #ifdef SEND_MIMETYPES 118 | bool send_content_type; //True if we want to send the content type 119 | #endif 120 | bool is_inetd; //True if it expects to be executed by inetd 121 | array_ll cgi_paths; //Paths to cgi binaries 122 | bool virtual_host; //True if must check for virtual hosts 123 | bool exec_script; //Enable CGI if false 124 | bool tar_directory; //Sends directories compressed into tar-files 125 | bool daemonize; //Run daemon() 126 | char *ip; //IP addr with default value 127 | char *port; //port with default value 128 | 129 | char *indexes[MAXINDEXCOUNT];//List of pointers to index files 130 | int indexes_l; //Count of the list 131 | #ifdef HAVE_LIBSSL 132 | SSL_CTX *sslctx; //SSL context 133 | #endif 134 | 135 | } weborf_configuration_t; 136 | 137 | #endif 138 | 139 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2007 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_UTILS_H 22 | #define WEBORF_UTILS_H 23 | 24 | #include "types.h" 25 | #include "options.h" 26 | 27 | int list_dir(connection_t *connection_prop, char *html, unsigned int bufsize, bool parent); 28 | void help(); 29 | void version(); 30 | void moo(); 31 | void print_start_disclaimer(int argc, char *argv[]); 32 | bool get_param_value(char *http_param, char *parameter, char *buf, ssize_t size,ssize_t param_len); 33 | void daemonize(); 34 | void print_capabilities(); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /webdav.h: -------------------------------------------------------------------------------- 1 | /* 2 | Weborf 3 | Copyright (C) 2009 Salvo "LtWorf" Tomaselli 4 | 5 | Weborf is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | @author Salvo "LtWorf" Tomaselli 19 | */ 20 | 21 | #ifndef WEBORF_WEBDAV_H 22 | #define WEBORF_WEBDAV_H 23 | 24 | #include "types.h" 25 | 26 | int propfind(connection_t* connection_prop,string_t *post_param); 27 | int mkcol(connection_t* connection_prop); 28 | int copy_move(connection_t* connection_prop); 29 | #endif 30 | -------------------------------------------------------------------------------- /weborf.1: -------------------------------------------------------------------------------- 1 | .TH Weborf 1 "May 05, 2023" "Minimal webserver" 2 | .SH NAME 3 | weborf 4 | \- Minimal webserver 5 | 6 | .SH SYNOPSIS 7 | weborf [options] 8 | 9 | .SH DESCRIPTION 10 | Weborf is a minimal webserver. Also has a limited support for webdav. 11 | .BR 12 | This manual page documents \fBWeborf\fP's command-line parameters. 13 | .BR 14 | \fBWeborf\fP is released under the GNU General Public License version 3. 15 | 16 | .SH OPTIONS 17 | .SS 18 | .SS Options: 19 | 20 | .TP 21 | .B \-b, \-\-basedir 22 | Must be followed by a valid directory. Weborf will use this directory as root directory, and won't send files located in parent dirs. But it is still possible for server\-side scripts to read contents located anywhere on the filesystem. Links are also a workaround to exit from the base directory. 23 | Defaults to /srv/www. 24 | 25 | .TP 26 | .B \-a, \-\-auth 27 | Must be followed by a unix socket listened by a program who will handle authentication. See the website for more details. 28 | 29 | .TP 30 | .B \-c, \-\-cgi 31 | Must be followed by a list (separated with commas and without spaces) of CGI formats and the binary to execute that format. 32 | For example: .php,/usr/bin/php-cgi,.sh,/usr/bin/sh-cgi 33 | In /etc/weborf.conf there is a 'cgi' directive, corresponding to this option. It is used when launching weborf as SystemV daemon. 34 | 35 | .TP 36 | .B \-C, \-\-cache 37 | Must be followed by a directory that will be used to store cached files. 38 | To flush the cache (empty that directory) you must delete the files in the directory. 39 | 40 | .TP 41 | .B \-T, \-\-inetd 42 | Must be specified when using weborf with inetd or xinetd. 43 | It will be still necessary to specify the used port, to pass the correct value to the CGI scripts. 44 | The \-u directive will be ignored. 45 | Daemon \-d mode should not be used. 46 | 47 | .TP 48 | .B \-t, \-\-tar 49 | If used, instead of sending directory listing when requesting a directory, weborf will send a tar.gz file with the content of that directory. 50 | It is used mainly to share files and preserving their permissions. 51 | It cannot be used together with https. 52 | 53 | .TP 54 | .B \-Y, \-\-yesexec 55 | When used, weborf will enable CGI. 56 | 57 | .TP 58 | .B \-m, \-\-mime 59 | When used, weborf will send the Content-Type header. It is strongly advised to use it when using weborf as production server because some browsers rely on this field. 60 | This value will not affect the CGI pages. 61 | 62 | .TP 63 | .B \-i, \-\-ip 64 | Must be followed by a valid IP address (v6 or v4, depending on how weborf was compiled. Run weborf \-h to know it), and weborf will accept only connections directed to that specific IP. 65 | If the IP address provided isn't used by a network device on the host, weborf will terminate. 66 | By default weborf listens to all IP addresses on the local host. 67 | 68 | .TP 69 | .B \-k, \-\-caps 70 | Shows some compile-time options in a machine-readable format. 71 | 72 | .TP 73 | .B \-p, \-\-port 74 | Must be followed by a valid port number (between 1 and 65535), and weborf will listen to incoming connection on the specified port. 75 | If the port is already used weborf will terminate. 76 | To use low port numbers (less than 1024) it is necessary to execute the process as root. 77 | Thus it isn't a good idea to run a webserver with root privileges, so it is possible to specify another user. 78 | 79 | .TP 80 | .B \-S, \-\-cert 81 | Path to the SSL certificate. Enables https. Requires a key to be passed as well. 82 | 83 | .TP 84 | .B \-K, \-\-key 85 | Path to the SSL key. Enables https. Requires a certificate to be passed as well. 86 | 87 | .TP 88 | .B \-V, \-\-virtual 89 | Enables weborf to use virtualhosts. The basedir supplied with \-b will be the default one (will be used if the requested host is unknown). 90 | Every virtualhost must be in the form host[:port]=basedir. The port must be specified if the port used is different than 80. And the basedir must end with a /. To separate many virtualhosts, use a comma, and avoid spaces. 91 | To make weborf use different virtualhosts on different ports, it will be necessary to launch many weborf's processes. This can now be achieved easily by creating multiple configuration files and using the systemd units like weborf@cfgfile.conf 92 | 93 | .TP 94 | .B \-I, \-\-index 95 | Must be followed by a list (separated with commas and without spaces) of index files. 96 | Weborf will try to load an index file following the order they're listed, and if none is found it will list the content of the directory. 97 | In /etc/weborf.conf there is an 'indexes' directive, corresponding to this option. It is used when launching weborf as SystemV daemon. 98 | 99 | .TP 100 | .B \-u, \-\-uid 101 | Must be followed by a valid uid, different from 0. Weborf will use this user to do his work, but will bind to the network port with the previous user. This mechanism is meant to let users execute it as root and use port 80, and then let it run without root privileges. 102 | 103 | .TP 104 | .B \-g, \-\-gid 105 | Must be followed by a valid gid, different from 0. Weborf will use this user to do his work, but will bind to the network port before changing. 106 | 107 | .TP 108 | .B \-d 109 | Runs weborf as a daemon. It will not terminate when its father process terminates, and it will leave the shell free to receive commands. 110 | .SS 111 | 112 | .SH SCRIPTING 113 | Weborf is able to send dynamically generated pages using php-cgi (if installed). 114 | When a filename ends with ".php", weborf will use php to execute this file before sending it to the client. The \-c switch will override the default behavior. 115 | .BR 116 | It is also possible to create scripts or binaries in other languages, just read rfc3875 to know how to handle parameters. 117 | 118 | .SH RETURN VALUE 119 | .TP 120 | .B 0 121 | Normal termination occurred after a signal, a daemonization or a print version and exit or so on... 122 | .TP 123 | .B 1 124 | Basedir is not a directory 125 | .TP 126 | 127 | .B 2 128 | Invalid IP address 129 | .TP 130 | 131 | .B 3 132 | Port already in use 133 | .TP 134 | 135 | .B 4 136 | Invalid port number 137 | .TP 138 | 139 | .B 5 140 | Authentication socket doesn't exist or is not a unix socket 141 | .TP 142 | 143 | .B 6 144 | Too many indexes provided as parameter to \-I or to \-c. Increasing MAXINDEXCOUNT in the file options.h and recompiling can solve the problem. But providing a reasonable amount of index file names would be a better solution. 145 | .TP 146 | 147 | .B 7 148 | Unable to allocate memory 149 | .TP 150 | 151 | .B 9 152 | Unable to change UID 153 | .TP 154 | 155 | .B 10 156 | Error with cache directory 157 | .TP 158 | 159 | 160 | .B 19 161 | Invalid parameters on command line 162 | .SS 163 | 164 | .SH "SIGNALS" 165 | .TP 166 | .B SIGUSR1 167 | Prints the internal status of the socket's queue and threads on the standard output 168 | .SS 169 | 170 | .SH "SEE ALSO" 171 | .BR weborf.conf(5), php (1) 172 | 173 | .SH VERSION 174 | .BR Weborf 0.13 175 | 176 | .SH WEB 177 | .BR https://ltworf.github.io/weborf/ 178 | 179 | .SH AUTHORS 180 | .nf 181 | Salvo "LtWorf" Tomaselli 182 | Salvo Rinaldi 183 | .br 184 | -------------------------------------------------------------------------------- /weborf.conf: -------------------------------------------------------------------------------- 1 | # /etc/weborf.conf - configuration file for weborf(1) 2 | # see weborf.conf(5) for details on this file 3 | # 4 | #Index files. This list is ordered by priority. If not set, the default value will be index.html. 5 | #indexes=index.html,index.php 6 | 7 | # Comment this to not start this unit automatically. 8 | # Only works with systemd 9 | start=auto 10 | 11 | # Base directory. 12 | basedir=/srv/www/ 13 | 14 | # Enables or disables use of CGI support 15 | use-cgi=false 16 | 17 | #Enable weborf to send Content-Type header 18 | use-mime=true 19 | 20 | # Tells weborf which binary it has to use to execute a certain dynamic page 21 | # default value: .php,/usr/lib/cgi-bin/php5,.py, 22 | #cgi=.php,/usr/lib/cgi-bin/php5,.py,/usr/lib/cgi-bin/weborf_py_wrapper,.cgi, 23 | 24 | # Authentication 25 | #auth-socket=/var/run/weborf.auth 26 | 27 | # User that will be used to run the process. 28 | user=www-data 29 | group=www-data 30 | 31 | # Directory that will be used for the cached files 32 | cachedir=/var/cache/weborf 33 | 34 | # Port used to listen 35 | port=80 36 | 37 | # SSL cert. Change port to 443 when using ssl 38 | #key=/path/to/key 39 | #cert=/path/to/cert 40 | 41 | # Virtualhosts. Read manpage for more details. 42 | # Examples 43 | # This line will enable two hosts named "localhost" and "serverq.com" 44 | #virtual=localhost=/var/www/,serverq.com=/var/www-alt/ 45 | -------------------------------------------------------------------------------- /weborf.conf.5: -------------------------------------------------------------------------------- 1 | .TH Weborf 5 "Sep 30, 2020" "Minimal webserver" 2 | 3 | .SH NAME 4 | .B weborf.conf 5 | \- configuration file for weborf daemon 6 | 7 | .SH SYNOPSIS 8 | /etc/weborf.conf 9 | .br 10 | /etc/weborf.d/*.conf 11 | 12 | .SH DESCRIPTION 13 | Weborf is a minimal webserver. Also has a limited support for webdav. 14 | .br 15 | Can be started as stand-alone or as system daemon. This manual page documents Weborf's configuration file, used only when it is started as daemon. 16 | .br 17 | 18 | .SH DESCRIPTION 19 | Options are case sensitive. Immediately followed by the equal = sign, without any space between name and value. 20 | Lines beginning with # will be ignored and treated as comments. 21 | .P 22 | When systemd is in use, every .conf file in /etc/weborf.d/ is used to start a different instance of weborf, with a different configuration. Otherwise the file /etc/weborf.conf is used to start a single instance of weborf. 23 | .SS 24 | 25 | .TP 26 | .B indexes 27 | By default weborf searches for index.html. Anyway it is possible to specify a different index file and also many index files. Name of the pages must be separated by a comma and between them there aren't spaces. 28 | 29 | .TP 30 | .B basedir 31 | Default base directory used by the webserver. The default means that this will be used also when virtual hosts are enabled, if the requested host is unknown. Of course the user used for the webserver will need to have access to this directory. 32 | 33 | .TP 34 | .B use-cgi 35 | Can be true or false. If false weborf will handle all files as normal files. Otherwise it will use the CGI protocol to execute some files. 36 | Defaults to false. 37 | 38 | .TP 39 | .B use-mime 40 | Can be true or false. If true weborf will send the Content-Type header to the clients. Turning it off will increase speed but might cause problems with some old clients. 41 | 42 | .TP 43 | .B cgi 44 | List of extensions to consider as dynamic pages and binaries to execute them. It takes a file format and a path, comma separated, and the list can include more formats and paths. Eg: cgi=.php,/bin/phpexecutor,.sh,/bin/shellexecutor 45 | 46 | .TP 47 | .B auth-socket 48 | Path of the unix socket that weborf will use to connect to the authentication server. When this is enabled, for every HTTP request weborf opens a connection to this socket, forwards the request, and the authentication daemon is in charge of deciding whether to accept or deny the request. Examples are provided in /usr/share/doc/weborf/examples. 49 | 50 | .TP 51 | .B cachedir 52 | Will set the path of the directory used for caching. When this is enabled, weborf will cache PROPFIND and directory listing requests, making them faster. 53 | 54 | .TP 55 | .B user 56 | Username of the user that will run the webserver. On Debian this is usually www-data. 57 | 58 | .TP 59 | .B group 60 | Groupname of the group that will run the webserver. On Debian this is usually www-data. 61 | 62 | .TP 63 | .B port 64 | The port to use. 65 | 66 | .TP 67 | .B key 68 | Absolute path to the SSL key file. It must be used with the cert option. 69 | .br 70 | When set, weborf will use HTTPS instead of HTTP. 71 | 72 | .TP 73 | .B cert 74 | Absolute path to the SSL certificate file. It must be used with the key option. 75 | .br 76 | When set, weborf will use HTTPS instead of HTTP. 77 | 78 | .TP 79 | .B virtual 80 | This directive is used to enable virtualhosts. 81 | The format is: 82 | virtual=localhost=/var/www/,serverq.com=/var/www-alt/ 83 | .br 84 | To run on multiple ports, more instances are needed. 85 | 86 | .TP 87 | .B start 88 | If this is set to auto, when systemd is in use, the instance using this configuration file is considered as part of the weborf service and started/stopped along with it. It does nothing with other init systems. 89 | 90 | .SS 91 | 92 | .SH "SEE ALSO" 93 | .BR weborf (1) 94 | 95 | .SH WEB 96 | .BR https://ltworf.github.io/weborf/ 97 | 98 | .SH AUTHORS 99 | .nf 100 | Salvo "LtWorf" Tomaselli 101 | Salvo Rinaldi 102 | .br 103 | --------------------------------------------------------------------------------