onionserver/main.c
2020-07-31 14:50:57 +03:00

185 lines
5.7 KiB
C

/*
* This file is part of the Onion_test project.
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <crypt.h>
#include <errno.h>
#include <onion/block.h>
#include <onion/exportlocal.h>
#include <onion/handler.h>
#include <onion/log.h>
#include <onion/onion.h>
#include <onion/shortcuts.h>
#include <onion/types_internal.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <usefull_macros.h>
#include "auth.h"
#include "cmdlnopts.h"
onion_connection_status get(_U_ onion_handler *h, onion_request *req, onion_response *res){
sessinfo *session = qookieSession(req);
if(!session){
onion_response_write0(res, "NeedAuth");
ONION_WARNING("try to run command without auth");
return OCS_FORBIDDEN;
}
const char *path = onion_request_get_path(req);
if(path && *path == 0) path = NULL;
else printf("GET ask path %s\n", path);
const char *param = getQdata(req, "param");
if(param) printf("User set param=%s\n", param);
if(getQdata(req, "getWSkey")){
addWSkey(res, session);
}
freeSessInfo(&session);
return OCS_CLOSE_CONNECTION;
}
static onion *o = NULL;
void signals(int signo){
if(o) onion_free(o);
closeSQLite();
exit(signo);
}
static void runServer(){
o = onion_new(O_POOL);
if(!(onion_flags(o) & O_SSL_AVAILABLE)){
ONION_ERROR("SSL support is not available");
signals(1);
}
int error = onion_set_certificate(o, O_SSL_CERTIFICATE_KEY, G.certfile, G.keyfile);
if(error){
ONION_ERROR("Cant set certificate and key files (%s, %s)", G.certfile, G.keyfile);
signals(1);
}
onion_set_port(o, G.port);
onion_url *url = onion_root_url(o);
onion_url_add_handler(url, "^static/", onion_handler_export_local_new("static"));
onion_url_add_with_data(url, "", onion_shortcut_internal_redirect, "static/index.html", NULL);
onion_url_add(url, "^auth/", auth);
onion_url_add(url, "^get/", get);
signal(SIGTERM, signals);
error = onion_listen(o);
if(error){
ONION_ERROR("Cant create the server: %s", strerror(errno));
}
onion_free(o);
}
static char *getl(char *msg, int noempty){
static char *inpstr = NULL;
do{
FREE(inpstr);
printf("Enter %s: ", msg);
size_t n = 0;
if(getline(&inpstr, &n, stdin) < 0) FREE(inpstr);
else{
char *nl = strchr(inpstr, '\n');
if(nl) *nl = 0;
if(strlen(inpstr) < 1 && noempty){
WARNX("Enter non-empty string");
}else break;
}
}while(1);
return inpstr;
}
static void adduser(){
userinfo *User = MALLOC(userinfo, 1);
char *str;
do{
str = getl("username", 1);
printf("Username: %s\n", str);
User->username = strdup(str);
do{
str = getl("password", 1);
if(strlen(str) < 4){
WARNX("Bad password: not less than 4 symbols");
}else break;
}while(1);
User->password = strdup(crypt(str, "$6$"));
printf("PassHash: %s\n", User->password);
str = getl("access level", 1);
User->level = atoi(str);
printf("Level: %d\n", User->level);
str = getl("comment", 0);
if(strlen(str)){
User->comment = strdup(str);
printf("Comment: %s", User->comment);
}
if(addUser(User)) continue;
if(!(str = getl("next? (y/n)", 0)) || 0 != strcmp(str, "y")) break;
}while(1);
freeUserInfo(&User);
}
extern char *onion_sessions_generate_id();
int main(int argc, char **argv){
initial_setup();
parse_args(argc, argv);
if(!G.usersdb) ERRX("You should point users database file name");
if(!G.sessiondb) ERRX("You should point session database file name");
if(initSQLite(G.usersdb, G.sessiondb)) return 1;
if(G.vacuum){
printf("VAAAA\n");
vacuumSQLite();
}
if(G.dumpUserDB) showAllUsers();
if(G.userdel){
for(int i = 0; G.userdel[i]; ++i){
if(!deleteUser(G.userdel[i])) green("User %s deleted\n", G.userdel[i]);
}
}
if(G.useradd) adduser();
/*
sessinfo *x = MALLOC(sessinfo, 1);
x->data = strdup("some data");
x->atime = time(NULL);
x->username = strdup("luser");
do{
FREE(x->sessID);
FREE(x->sockID);
x->sessID = onion_sessions_generate_id();
x->sockID = onion_sessions_generate_id();
if(!addSession(x)){
green("Insert session: ID=%s, sockid=%s, atime=%lld, user=%s, data=%s\n",
x->sessID, x->sockID, x->atime, x->username, x->data);
break;
}
}while(1);
freeSessInfo(&x);
*/
if(G.dumpSessDB) showAllSessions();
if(G.delsession){
if(!deleteSession(G.delsession))
green("Session with ID %s deleted\n", G.delsession);
}
if(G.delatime){
if(G.delatime < 0) G.delatime = time(NULL) - 31556926LL;
if(!deleteOldSessions((int64_t)G.delatime))
green("All sessions with atime<%lld deleted\n", G.delatime);
}
if(G.runServer) runServer();
closeSQLite();
return 0;
}