... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
#include "kakumei_session.h" |
25 | 25 |
#include "kakumei_pass.h" |
26 | 26 |
#include "kakumei_posts.h" |
27 |
+#include "kakumei_email.h" |
|
27 | 28 |
#include "kakumei_config.h" |
28 | 29 |
|
29 | 30 |
#define CONFIGFILE "kakumei.conf" |
... | ... |
@@ -50,6 +51,8 @@ wk_action http_lastpost(wk *web, int connid, wk_uri *uri, void *userptr,char *us |
50 | 51 |
wk_action http_getpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
51 | 52 |
wk_action http_newpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
52 | 53 |
wk_action http_newcomment(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
54 |
+wk_action http_changeemail(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
|
55 |
+wk_action http_getemail(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
|
53 | 56 |
|
54 | 57 |
int |
55 | 58 |
main(int argc, char *argv[]) |
... | ... |
@@ -113,8 +116,8 @@ main(int argc, char *argv[]) |
113 | 116 |
log_write("INIT","Server initialized, waiting connections..."); |
114 | 117 |
while(!sigint_flag) { |
115 | 118 |
sselect_wait(ka->ssel,timeout); |
116 |
- if(sigint_flag) |
|
117 |
- break; |
|
119 |
+ if(sigint_flag) |
|
120 |
+ break; |
|
118 | 121 |
wk_service(ka->web); |
119 | 122 |
} |
120 | 123 |
wk_free(ka->web),ka->web=NULL; |
... | ... |
@@ -322,6 +325,10 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
322 | 325 |
return(http_newpost(web,connid,uri,userptr,user)); |
323 | 326 |
else if(memcmp(uri->path,"/newcomment?",12)==0) |
324 | 327 |
return(http_newcomment(web,connid,uri,userptr,user)); |
328 |
+ else if(memcmp(uri->path,"/changeemail?",13)==0) |
|
329 |
+ return(http_changeemail(web,connid,uri,userptr,user)); |
|
330 |
+ else if(memcmp(uri->path,"/getemail?",10)==0) |
|
331 |
+ return(http_getemail(web,connid,uri,userptr,user)); |
|
325 | 332 |
} |
326 | 333 |
/* not found */ |
327 | 334 |
log_write("HTTP","URI not found: %s",uri->path); |
... | ... |
@@ -457,7 +464,6 @@ http_lastpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
457 | 464 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
458 | 465 |
log_write("LSTP","Reply: %s",reply); |
459 | 466 |
return(wkact_finished); |
460 |
- |
|
461 | 467 |
} |
462 | 468 |
|
463 | 469 |
wk_action |
... | ... |
@@ -496,6 +502,7 @@ http_newpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
496 | 502 |
log_write("NEWP","invalid post, send error"); |
497 | 503 |
return(wkact_finished); |
498 | 504 |
} |
505 |
+ email_notify(ka,user,-1); |
|
499 | 506 |
log_write("NEWP","Replying with last post"); |
500 | 507 |
return(http_lastpost(web,connid,uri,userptr,user)); |
501 | 508 |
} |
... | ... |
@@ -519,6 +526,41 @@ http_newcomment(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
519 | 526 |
} |
520 | 527 |
wk_serve_buffer_as_file(web,connid,n,strlen(n),"text/plain"); |
521 | 528 |
log_write("NEWC","Reply: %s",n); |
529 |
+ email_notify(ka,user,num); |
|
530 |
+ return(wkact_finished); |
|
531 |
+} |
|
532 |
+ |
|
533 |
+wk_action |
|
534 |
+http_changeemail(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
|
535 |
+{ |
|
536 |
+ char useremail[128]; |
|
537 |
+ kakumei *ka=(kakumei *)userptr; |
|
538 |
+ if(wk_uri_copyvar(uri,"a",useremail,sizeof(useremail))==NULL) |
|
539 |
+ useremail[0]='\0'; |
|
540 |
+ if(email_set(ka,user,useremail)!=0) { |
|
541 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
542 |
+ log_write("EMCH","couldn't change email, send error"); |
|
543 |
+ return(wkact_finished); |
|
544 |
+ } |
|
545 |
+ /* valid */ |
|
546 |
+ wk_serve_buffer_as_file(web,connid,useremail,strlen(useremail),"text/plain"); |
|
547 |
+ log_write("EMCH","Reply: %s",useremail); |
|
548 |
+ return(wkact_finished); |
|
549 |
+} |
|
550 |
+ |
|
551 |
+wk_action |
|
552 |
+http_getemail(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
|
553 |
+{ |
|
554 |
+ char useremail[128]; |
|
555 |
+ kakumei *ka=(kakumei *)userptr; |
|
556 |
+ if(email_get(ka,user,useremail,sizeof(useremail))!=0) { |
|
557 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
558 |
+ log_write("EMGT","no user email, send error"); |
|
559 |
+ return(wkact_finished); |
|
560 |
+ } |
|
561 |
+ /* valid */ |
|
562 |
+ wk_serve_buffer_as_file(web,connid,useremail,strlen(useremail),"text/plain"); |
|
563 |
+ log_write("EMGT","Reply: %s",useremail); |
|
522 | 564 |
return(wkact_finished); |
523 | 565 |
} |
524 | 566 |
|
... | ... |
@@ -113,6 +113,8 @@ main(int argc, char *argv[]) |
113 | 113 |
log_write("INIT","Server initialized, waiting connections..."); |
114 | 114 |
while(!sigint_flag) { |
115 | 115 |
sselect_wait(ka->ssel,timeout); |
116 |
+ if(sigint_flag) |
|
117 |
+ break; |
|
116 | 118 |
wk_service(ka->web); |
117 | 119 |
} |
118 | 120 |
wk_free(ka->web),ka->web=NULL; |
... | ... |
@@ -15,6 +15,7 @@ |
15 | 15 |
#include <sys/types.h> |
16 | 16 |
#include <sys/stat.h> |
17 | 17 |
#include <unistd.h> |
18 |
+#include <mhash.h> |
|
18 | 19 |
#include "gen_res.h" |
19 | 20 |
#include "socklib.h" |
20 | 21 |
#include "loglib.h" |
... | ... |
@@ -32,12 +33,15 @@ |
32 | 33 |
#define CFBANNERPATH "default.png" |
33 | 34 |
#define CFSSLPROXY 0 |
34 | 35 |
|
36 |
+#define DEBUG_HEADERS |
|
37 |
+ |
|
35 | 38 |
static int signal_init(int signum, void (*fn)(int)); |
36 | 39 |
static void sigint(int signum); |
37 | 40 |
volatile int sigint_flag=0; |
38 | 41 |
|
39 | 42 |
int kakumei_inviteexists(kakumei *ka, char *invite); |
40 | 43 |
int kakumei_invitedel(kakumei *ka, char *invite); |
44 |
+int kakumei_etag(kakumei *ka, char *filename, char *etag, int etagsize); |
|
41 | 45 |
|
42 | 46 |
wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
43 | 47 |
wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr); |
... | ... |
@@ -177,6 +181,38 @@ kakumei_invitedel(kakumei *ka, char *invite) |
177 | 181 |
return(0); |
178 | 182 |
} |
179 | 183 |
|
184 |
+int |
|
185 |
+kakumei_etag(kakumei *ka, char *filename, char *etag, int etagsize) |
|
186 |
+{ |
|
187 |
+ struct stat st; |
|
188 |
+ MHASH td; |
|
189 |
+ char binhash[20]; |
|
190 |
+ char hash[40]; |
|
191 |
+ int i; |
|
192 |
+ char c; |
|
193 |
+ if(filename==NULL || etag==NULL || etagsize<1) |
|
194 |
+ return(-1); |
|
195 |
+ if(stat(filename,&st)!=0 || !S_ISREG(st.st_mode)) |
|
196 |
+ return(-1); |
|
197 |
+ if((td=mhash_init(MHASH_SHA1))==MHASH_FAILED) |
|
198 |
+ return(-1); |
|
199 |
+ mhash(td,&(st.st_mtime),sizeof(st.st_mtime)); |
|
200 |
+ mhash(td,&(st.st_size),sizeof(st.st_size)); |
|
201 |
+ mhash_deinit(td,&binhash); |
|
202 |
+ for(i=0;i<sizeof(binhash);i++) { |
|
203 |
+ c=(((unsigned char *)binhash)[i]>>4); |
|
204 |
+ c=(c>=10)?(c-10+'a'):c+'0'; |
|
205 |
+ hash[i<<1]=c; |
|
206 |
+ c=(((unsigned char *)binhash)[i]&0xf); |
|
207 |
+ c=(c>=10)?(c-10+'a'):c+'0'; |
|
208 |
+ hash[(i<<1)+1]=c; |
|
209 |
+ } |
|
210 |
+ memcpy(etag,hash,(etagsize>sizeof(hash))?sizeof(hash):(etagsize-1)); |
|
211 |
+ etag[(etagsize>sizeof(hash))?sizeof(hash):(etagsize-1)]='\0'; |
|
212 |
+ return(0); |
|
213 |
+} |
|
214 |
+ |
|
215 |
+ |
|
180 | 216 |
|
181 | 217 |
wk_action |
182 | 218 |
callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
... | ... |
@@ -185,6 +221,7 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
185 | 221 |
resindex *res; |
186 | 222 |
char partialpath[1024]; |
187 | 223 |
char *ptr; |
224 |
+ char etag[ETAGSIZE+1]; |
|
188 | 225 |
struct { |
189 | 226 |
char *name; |
190 | 227 |
} whitelist[]={{"/index.html"}, |
... | ... |
@@ -207,6 +244,14 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
207 | 244 |
log_write("HTTP","Request: /newuser?..."); |
208 | 245 |
else |
209 | 246 |
log_write("HTTP","Request: %s",uri->path); |
247 |
+#ifdef DEBUG_HEADERS |
|
248 |
+ { |
|
249 |
+ int j; |
|
250 |
+ char *h; |
|
251 |
+ for(j=0;(h=wk_uri_getheaderbynum(uri,j))!=NULL;j++) |
|
252 |
+ log_write("HDR","%s",h); |
|
253 |
+ } |
|
254 |
+#endif |
|
210 | 255 |
/* extract the name */ |
211 | 256 |
strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
212 | 257 |
partialpath[sizeof(partialpath)-1]='\0'; |
... | ... |
@@ -238,6 +283,7 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
238 | 283 |
if(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL) { |
239 | 284 |
if(whitelisted || validsession) { |
240 | 285 |
log_write("HTTP","Serving in-memory file %s",partialpath+1); |
286 |
+ wk_serve_etagset(web,connid,res->etag); |
|
241 | 287 |
wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
242 | 288 |
return(wkact_finished); |
243 | 289 |
} else if((res=res_find(resindexdata,"index.html"))!=NULL) { |
... | ... |
@@ -251,6 +297,8 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
251 | 297 |
} |
252 | 298 |
} else if(strcmp(uri->path,"/banner.png")==0) { |
253 | 299 |
log_write("HTTP","Serving banner from disk, file %s",partialpath); |
300 |
+ if(kakumei_etag(ka,partialpath,etag,sizeof(etag))==0) |
|
301 |
+ wk_serve_etagset(web,connid,etag); |
|
254 | 302 |
if(wk_serve_file(web,connid,partialpath,mime_getdefault(partialpath,"image/png"))!=0) { |
255 | 303 |
log_write("HTTP","File not found, file %s",partialpath); |
256 | 304 |
wk_serve_error(web,connid,wkerr_notfound); |
... | ... |
@@ -50,17 +50,21 @@ wk_action http_newcomment(wk *web, int connid, wk_uri *uri, void *userptr,char * |
50 | 50 |
int |
51 | 51 |
main(int argc, char *argv[]) |
52 | 52 |
{ |
53 |
- int port; |
|
54 | 53 |
int timeout=500; |
55 | 54 |
int serverfd; |
56 | 55 |
kakumei *ka,kastore; |
57 | 56 |
memset(&kastore,0,sizeof(kastore)); |
58 | 57 |
ka=&kastore; |
58 |
+ char *hostnameport; |
|
59 |
+ char hostname[128]; |
|
60 |
+ char *host; |
|
61 |
+ long hostsize; |
|
62 |
+ char *ptr,*sep; |
|
59 | 63 |
if(argc!=2) { |
60 |
- printf("Syntax: %s port\n",argv[0]); |
|
64 |
+ printf("Syntax: %s [ip:]port\n",argv[0]); |
|
61 | 65 |
return(1); |
62 | 66 |
} |
63 |
- port=atoi(argv[1]); |
|
67 |
+ hostnameport=argv[1]; |
|
64 | 68 |
if(kaconfig_exists(CONFIGFILE)!=0) { |
65 | 69 |
log_setlogfile(CFLOGFILE); |
66 | 70 |
log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
... | ... |
@@ -76,7 +80,20 @@ main(int argc, char *argv[]) |
76 | 80 |
log_write("INIT","ERROR: insufficient memory"); |
77 | 81 |
return(1); |
78 | 82 |
} |
79 |
- if((serverfd=ipv4_server(port))==-1) { |
|
83 |
+ if((sep=strchr(hostnameport,':'))!=NULL) { |
|
84 |
+ serverfd=-1; |
|
85 |
+ strncpy(hostname,hostnameport,sizeof(hostname)); |
|
86 |
+ hostname[sizeof(hostname)-1]='\0'; |
|
87 |
+ if((ptr=strchr(hostname,':'))!=NULL) |
|
88 |
+ *ptr='\0'; |
|
89 |
+ if((host=ipv4_genip(hostname,&hostsize))!=NULL) { |
|
90 |
+ serverfd=ipv4_serverbinded(host,hostsize,atoi(sep+1)); |
|
91 |
+ free(host),host=NULL; |
|
92 |
+ } |
|
93 |
+ } else { |
|
94 |
+ serverfd=ipv4_server(atoi(hostnameport)); |
|
95 |
+ } |
|
96 |
+ if(serverfd==-1) { |
|
80 | 97 |
sselect_free(ka->ssel),ka->ssel=NULL; |
81 | 98 |
log_write("INIT","ERROR: couldn't listen on port"); |
82 | 99 |
return(2); |
... | ... |
@@ -52,6 +52,7 @@ main(int argc, char *argv[]) |
52 | 52 |
{ |
53 | 53 |
int port; |
54 | 54 |
int timeout=500; |
55 |
+ int serverfd; |
|
55 | 56 |
kakumei *ka,kastore; |
56 | 57 |
memset(&kastore,0,sizeof(kastore)); |
57 | 58 |
ka=&kastore; |
... | ... |
@@ -61,21 +62,27 @@ main(int argc, char *argv[]) |
61 | 62 |
} |
62 | 63 |
port=atoi(argv[1]); |
63 | 64 |
if(kaconfig_exists(CONFIGFILE)!=0) { |
64 |
- log_setlogfile(CFLOGFILE); |
|
65 |
+ log_setlogfile(CFLOGFILE); |
|
65 | 66 |
log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
66 | 67 |
kaconfig_write(CONFIGFILE,CFLOGFILE,CFCOOKIENAME,CFCOOKIEDOMAIN,CFBANNERPATH,CFSSLPROXY); |
67 | 68 |
} |
68 | 69 |
if((ka->config=kaconfig_init(CONFIGFILE))==NULL) { |
69 |
- log_setlogfile(CFLOGFILE); |
|
70 |
+ log_setlogfile(CFLOGFILE); |
|
70 | 71 |
log_write("INIT","ERROR: insufficient memory or config file error"); |
71 | 72 |
return(1); |
72 | 73 |
} |
73 |
- log_setlogfile((ka->config->logfile!=NULL)?ka->config->logfile:CFLOGFILE); |
|
74 |
+ log_setlogfile((ka->config->logfile!=NULL)?ka->config->logfile:CFLOGFILE); |
|
74 | 75 |
if((ka->ssel=sselect_init())==NULL) { |
75 | 76 |
log_write("INIT","ERROR: insufficient memory"); |
76 | 77 |
return(1); |
77 | 78 |
} |
78 |
- if((ka->web=wk_init(port,ka->ssel,NULL,callback_http,NULL,NULL,ka))==NULL) { |
|
79 |
+ if((serverfd=ipv4_server(port))==-1) { |
|
80 |
+ sselect_free(ka->ssel),ka->ssel=NULL; |
|
81 |
+ log_write("INIT","ERROR: couldn't listen on port"); |
|
82 |
+ return(2); |
|
83 |
+ } |
|
84 |
+ sock_setunsafe(serverfd); |
|
85 |
+ if((ka->web=wk_init(serverfd,ka->ssel,NULL,callback_http,NULL,NULL,ka))==NULL) { |
|
79 | 86 |
sselect_free(ka->ssel),ka->ssel=NULL; |
80 | 87 |
log_write("INIT","ERROR: couldn't init web server"); |
81 | 88 |
return(2); |
... | ... |
@@ -88,6 +95,7 @@ main(int argc, char *argv[]) |
88 | 95 |
wk_service(ka->web); |
89 | 96 |
} |
90 | 97 |
wk_free(ka->web),ka->web=NULL; |
98 |
+ close(serverfd),serverfd=-1; |
|
91 | 99 |
sselect_free(ka->ssel),ka->ssel=NULL; |
92 | 100 |
kaconfig_free(ka->config),ka->config=NULL; |
93 | 101 |
log_write("FINI","SIGINT detected, exiting..."); |
... | ... |
@@ -26,6 +26,7 @@ |
26 | 26 |
#include "kakumei_config.h" |
27 | 27 |
|
28 | 28 |
#define CONFIGFILE "kakumei.conf" |
29 |
+#define CFLOGFILE "kakumei.log" |
|
29 | 30 |
#define CFCOOKIENAME "kakumeiauthid" |
30 | 31 |
#define CFCOOKIEDOMAIN "localhost" |
31 | 32 |
#define CFBANNERPATH "default.png" |
... | ... |
@@ -60,13 +61,16 @@ main(int argc, char *argv[]) |
60 | 61 |
} |
61 | 62 |
port=atoi(argv[1]); |
62 | 63 |
if(kaconfig_exists(CONFIGFILE)!=0) { |
64 |
+ log_setlogfile(CFLOGFILE); |
|
63 | 65 |
log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
64 |
- kaconfig_write(CONFIGFILE,CFCOOKIENAME,CFCOOKIEDOMAIN,CFBANNERPATH,CFSSLPROXY); |
|
66 |
+ kaconfig_write(CONFIGFILE,CFLOGFILE,CFCOOKIENAME,CFCOOKIEDOMAIN,CFBANNERPATH,CFSSLPROXY); |
|
65 | 67 |
} |
66 | 68 |
if((ka->config=kaconfig_init(CONFIGFILE))==NULL) { |
69 |
+ log_setlogfile(CFLOGFILE); |
|
67 | 70 |
log_write("INIT","ERROR: insufficient memory or config file error"); |
68 | 71 |
return(1); |
69 | 72 |
} |
73 |
+ log_setlogfile((ka->config->logfile!=NULL)?ka->config->logfile:CFLOGFILE); |
|
70 | 74 |
if((ka->ssel=sselect_init())==NULL) { |
71 | 75 |
log_write("INIT","ERROR: insufficient memory"); |
72 | 76 |
return(1); |
... | ... |
@@ -29,6 +29,7 @@ |
29 | 29 |
#define CFCOOKIENAME "kakumeiauthid" |
30 | 30 |
#define CFCOOKIEDOMAIN "localhost" |
31 | 31 |
#define CFBANNERPATH "default.png" |
32 |
+#define CFSSLPROXY 0 |
|
32 | 33 |
|
33 | 34 |
static int signal_init(int signum, void (*fn)(int)); |
34 | 35 |
static void sigint(int signum); |
... | ... |
@@ -60,7 +61,7 @@ main(int argc, char *argv[]) |
60 | 61 |
port=atoi(argv[1]); |
61 | 62 |
if(kaconfig_exists(CONFIGFILE)!=0) { |
62 | 63 |
log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
63 |
- kaconfig_write(CONFIGFILE,CFCOOKIENAME,CFCOOKIEDOMAIN,CFBANNERPATH); |
|
64 |
+ kaconfig_write(CONFIGFILE,CFCOOKIENAME,CFCOOKIEDOMAIN,CFBANNERPATH,CFSSLPROXY); |
|
64 | 65 |
} |
65 | 66 |
if((ka->config=kaconfig_init(CONFIGFILE))==NULL) { |
66 | 67 |
log_write("INIT","ERROR: insufficient memory or config file error"); |
... | ... |
@@ -298,7 +299,7 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
298 | 299 |
/* valid login */ |
299 | 300 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
300 | 301 |
reply[sizeof(reply)-1]='\0'; |
301 |
- wk_serve_cookieadd(web,connid,ka->config->cookiename,authid,ka->config->cookiedomain,21600 /* 6h */,"secure"); |
|
302 |
+ wk_serve_cookieadd(web,connid,ka->config->cookiename,authid,ka->config->cookiedomain,21600 /* 6h */,(ka->config->sslproxy)?"secure":NULL); |
|
302 | 303 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
303 | 304 |
log_write("LGIN","Reply: %s",reply); |
304 | 305 |
return(wkact_finished); |
... | ... |
@@ -354,7 +355,7 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
354 | 355 |
/* valid login */ |
355 | 356 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
356 | 357 |
reply[sizeof(reply)-1]='\0'; |
357 |
- wk_serve_cookieadd(web,connid,ka->config->cookiename,authid,ka->config->cookiedomain,21600 /* 6h */,"secure"); |
|
358 |
+ wk_serve_cookieadd(web,connid,ka->config->cookiename,authid,ka->config->cookiedomain,21600 /* 6h */,(ka->config->sslproxy)?"secure":NULL); |
|
358 | 359 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
359 | 360 |
log_write("NEWU","Reply: %s",reply); |
360 | 361 |
return(wkact_finished); |
... | ... |
@@ -26,7 +26,7 @@ |
26 | 26 |
#include "kakumei_config.h" |
27 | 27 |
|
28 | 28 |
#define CONFIGFILE "kakumei.conf" |
29 |
-#define CFCOOKIEPREFIX "kakumei_" |
|
29 |
+#define CFCOOKIENAME "kakumeiauthid" |
|
30 | 30 |
#define CFCOOKIEDOMAIN "localhost" |
31 | 31 |
#define CFBANNERPATH "default.png" |
32 | 32 |
|
... | ... |
@@ -60,7 +60,7 @@ main(int argc, char *argv[]) |
60 | 60 |
port=atoi(argv[1]); |
61 | 61 |
if(kaconfig_exists(CONFIGFILE)!=0) { |
62 | 62 |
log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
63 |
- kaconfig_write(CONFIGFILE,CFCOOKIEPREFIX,CFCOOKIEDOMAIN,CFBANNERPATH); |
|
63 |
+ kaconfig_write(CONFIGFILE,CFCOOKIENAME,CFCOOKIEDOMAIN,CFBANNERPATH); |
|
64 | 64 |
} |
65 | 65 |
if((ka->config=kaconfig_init(CONFIGFILE))==NULL) { |
66 | 66 |
log_write("INIT","ERROR: insufficient memory or config file error"); |
... | ... |
@@ -164,8 +164,9 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
164 | 164 |
int ishtml; |
165 | 165 |
int whitelisted; |
166 | 166 |
int validsession; |
167 |
- char session[SESSIONSIZE]; |
|
167 |
+ char session[SESSIONSIZE+1]; |
|
168 | 168 |
char user[MAXUSERSIZE+1]; |
169 |
+ char authid[AUTHIDSIZE+1]; |
|
169 | 170 |
int i; |
170 | 171 |
if(ka==NULL) |
171 | 172 |
return(wkact_finished); |
... | ... |
@@ -200,7 +201,9 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
200 | 201 |
if(wk_uri_copyvar(uri,"s",session,sizeof(session))==NULL) |
201 | 202 |
session[0]='\0'; |
202 | 203 |
user[0]='\0'; |
203 |
- validsession=(session_check(ka,session,user,sizeof(user))!=NULL)?1:0; |
|
204 |
+ if(wk_uri_copycookie(uri,ka->config->cookiename,authid,sizeof(authid))==NULL) |
|
205 |
+ authid[0]='\0'; |
|
206 |
+ validsession=(session_check(ka,session,authid,user,sizeof(user))!=NULL)?1:0; |
|
204 | 207 |
/* serve the page */ |
205 | 208 |
if(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL) { |
206 | 209 |
if(whitelisted || validsession) { |
... | ... |
@@ -269,7 +272,8 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
269 | 272 |
{ |
270 | 273 |
char u[MAXUSERSIZE+1],p[MAXPASSWDSIZE+1]; |
271 | 274 |
char reply[1024]; |
272 |
- char session[SESSIONSIZE]; |
|
275 |
+ char session[SESSIONSIZE+1]; |
|
276 |
+ char authid[AUTHIDSIZE+1]; |
|
273 | 277 |
kakumei *ka=(kakumei *)userptr; |
274 | 278 |
if(web==NULL || connid<0 || uri==NULL || ka==NULL) { |
275 | 279 |
log_write("EINT","%s:%i",__FILE__,__LINE__); |
... | ... |
@@ -290,10 +294,11 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
290 | 294 |
log_write("LGIN","Reply: %s",reply); |
291 | 295 |
return(wkact_finished); |
292 | 296 |
} else if(pass_check(ka,u,p)==0 && |
293 |
- session_new(ka,u,session,sizeof(session))!=NULL) { |
|
297 |
+ session_new(ka,u,session,sizeof(session),authid,sizeof(authid))!=NULL) { |
|
294 | 298 |
/* valid login */ |
295 | 299 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
296 | 300 |
reply[sizeof(reply)-1]='\0'; |
301 |
+ wk_serve_cookieadd(web,connid,ka->config->cookiename,authid,ka->config->cookiedomain,21600 /* 6h */,"secure"); |
|
297 | 302 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
298 | 303 |
log_write("LGIN","Reply: %s",reply); |
299 | 304 |
return(wkact_finished); |
... | ... |
@@ -308,7 +313,8 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
308 | 313 |
{ |
309 | 314 |
char u[MAXUSERSIZE+1],p[MAXPASSWDSIZE+1],i[MAXPASSWDSIZE+1]; |
310 | 315 |
char reply[1024]; |
311 |
- char session[SESSIONSIZE]; |
|
316 |
+ char session[SESSIONSIZE+1]; |
|
317 |
+ char authid[AUTHIDSIZE+1]; |
|
312 | 318 |
kakumei *ka=(kakumei *)userptr; |
313 | 319 |
if(web==NULL || connid<0 || uri==NULL || ka==NULL) { |
314 | 320 |
log_write("EINT","%s:%i",__FILE__,__LINE__); |
... | ... |
@@ -339,7 +345,7 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
339 | 345 |
/* delete invitation */ |
340 | 346 |
kakumei_invitedel(ka,i); |
341 | 347 |
/* create session and go to "posts" page */ |
342 |
- if(session_new(ka,u,session,sizeof(session))==NULL) { |
|
348 |
+ if(session_new(ka,u,session,sizeof(session),authid,sizeof(authid))==NULL) { |
|
343 | 349 |
/* "autologin" didn't work, ask for login */ |
344 | 350 |
log_write("NEWU","couldn't generate new session, redirecting to login"); |
345 | 351 |
wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
... | ... |
@@ -348,6 +354,7 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
348 | 354 |
/* valid login */ |
349 | 355 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
350 | 356 |
reply[sizeof(reply)-1]='\0'; |
357 |
+ wk_serve_cookieadd(web,connid,ka->config->cookiename,authid,ka->config->cookiedomain,21600 /* 6h */,"secure"); |
|
351 | 358 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
352 | 359 |
log_write("NEWU","Reply: %s",reply); |
353 | 360 |
return(wkact_finished); |
... | ... |
@@ -23,6 +23,12 @@ |
23 | 23 |
#include "kakumei_session.h" |
24 | 24 |
#include "kakumei_pass.h" |
25 | 25 |
#include "kakumei_posts.h" |
26 |
+#include "kakumei_config.h" |
|
27 |
+ |
|
28 |
+#define CONFIGFILE "kakumei.conf" |
|
29 |
+#define CFCOOKIEPREFIX "kakumei_" |
|
30 |
+#define CFCOOKIEDOMAIN "localhost" |
|
31 |
+#define CFBANNERPATH "default.png" |
|
26 | 32 |
|
27 | 33 |
static int signal_init(int signum, void (*fn)(int)); |
28 | 34 |
static void sigint(int signum); |
... | ... |
@@ -52,6 +58,14 @@ main(int argc, char *argv[]) |
52 | 58 |
return(1); |
53 | 59 |
} |
54 | 60 |
port=atoi(argv[1]); |
61 |
+ if(kaconfig_exists(CONFIGFILE)!=0) { |
|
62 |
+ log_write("INIT","Config file not found, writing default file %s",CONFIGFILE); |
|
63 |
+ kaconfig_write(CONFIGFILE,CFCOOKIEPREFIX,CFCOOKIEDOMAIN,CFBANNERPATH); |
|
64 |
+ } |
|
65 |
+ if((ka->config=kaconfig_init(CONFIGFILE))==NULL) { |
|
66 |
+ log_write("INIT","ERROR: insufficient memory or config file error"); |
|
67 |
+ return(1); |
|
68 |
+ } |
|
55 | 69 |
if((ka->ssel=sselect_init())==NULL) { |
56 | 70 |
log_write("INIT","ERROR: insufficient memory"); |
57 | 71 |
return(1); |
... | ... |
@@ -70,6 +84,7 @@ main(int argc, char *argv[]) |
70 | 84 |
} |
71 | 85 |
wk_free(ka->web),ka->web=NULL; |
72 | 86 |
sselect_free(ka->ssel),ka->ssel=NULL; |
87 |
+ kaconfig_free(ka->config),ka->config=NULL; |
|
73 | 88 |
log_write("FINI","SIGINT detected, exiting..."); |
74 | 89 |
return(0); |
75 | 90 |
} |
... | ... |
@@ -166,6 +181,8 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
166 | 181 |
partialpath[sizeof(partialpath)-1]='\0'; |
167 | 182 |
if(strcmp(uri->path,"/")==0) |
168 | 183 |
strcpy(partialpath,"/index.html"); |
184 |
+ if(strcmp(uri->path,"/banner.png")==0) |
|
185 |
+ strcpy(partialpath,(ka->config->bannerpath!=NULL)?ka->config->bannerpath:"/" CFBANNERPATH); |
|
169 | 186 |
if((ptr=strchr(partialpath,'?'))!=NULL) |
170 | 187 |
*ptr='\0'; |
171 | 188 |
/* check whitelist */ |
... | ... |
@@ -199,6 +216,14 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
199 | 216 |
wk_serve_error(web,connid,wkerr_internal); |
200 | 217 |
return(wkact_finished); /* internal error */ |
201 | 218 |
} |
219 |
+ } else if(strcmp(uri->path,"/banner.png")==0) { |
|
220 |
+ log_write("HTTP","Serving banner from disk, file %s",partialpath); |
|
221 |
+ if(wk_serve_file(web,connid,partialpath,mime_getdefault(partialpath,"image/png"))!=0) { |
|
222 |
+ log_write("HTTP","File not found, file %s",partialpath); |
|
223 |
+ wk_serve_error(web,connid,wkerr_notfound); |
|
224 |
+ return(wkact_finished); /* internal error */ |
|
225 |
+ } |
|
226 |
+ return(wkact_finished); |
|
202 | 227 |
} |
203 | 228 |
/* check for actions */ |
204 | 229 |
if(memcmp(uri->path,"/login?",7)==0) { |
... | ... |
@@ -372,11 +372,14 @@ http_getpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
372 | 372 |
wk_action |
373 | 373 |
http_newpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
374 | 374 |
{ |
375 |
+ char h[8192]; |
|
375 | 376 |
char t[8192]; |
376 | 377 |
kakumei *ka=(kakumei *)userptr; |
378 |
+ if(wk_uri_copyvar(uri,"h",h,sizeof(h))==NULL) |
|
379 |
+ h[0]='\0'; |
|
377 | 380 |
if(wk_uri_copyvar(uri,"t",t,sizeof(t))==NULL) |
378 | 381 |
t[0]='\0'; |
379 |
- if(t[0]=='\0' || post_new(ka,user,t)!=0) { |
|
382 |
+ if((t[0]=='\0' && h[0]=='\0') || post_new(ka,user,h,t)!=0) { |
|
380 | 383 |
wk_serve_error(web,connid,wkerr_internal); |
381 | 384 |
log_write("NEWP","invalid post, send error"); |
382 | 385 |
return(wkact_finished); |
... | ... |
@@ -334,7 +334,7 @@ http_lastpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
334 | 334 |
char reply[64]; |
335 | 335 |
int n; |
336 | 336 |
kakumei *ka=(kakumei *)userptr; |
337 |
- if((n=post_last(ka))<=0) { |
|
337 |
+ if((n=post_last(ka))<0) { |
|
338 | 338 |
wk_serve_error(web,connid,wkerr_internal); |
339 | 339 |
log_write("LSTP","invalid postnum, send error"); |
340 | 340 |
return(wkact_finished); |
... | ... |
@@ -22,6 +22,7 @@ |
22 | 22 |
#include "kakumei.h" |
23 | 23 |
#include "kakumei_session.h" |
24 | 24 |
#include "kakumei_pass.h" |
25 |
+#include "kakumei_posts.h" |
|
25 | 26 |
|
26 | 27 |
static int signal_init(int signum, void (*fn)(int)); |
27 | 28 |
static void sigint(int signum); |
... | ... |
@@ -33,6 +34,10 @@ int kakumei_invitedel(kakumei *ka, char *invite); |
33 | 34 |
wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
34 | 35 |
wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr); |
35 | 36 |
wk_action http_newuser(wk *web, int connid, wk_uri *uri, void *userptr); |
37 |
+wk_action http_lastpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
|
38 |
+wk_action http_getpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
|
39 |
+wk_action http_newpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
|
40 |
+wk_action http_newcomment(wk *web, int connid, wk_uri *uri, void *userptr,char *user); |
|
36 | 41 |
|
37 | 42 |
int |
38 | 43 |
main(int argc, char *argv[]) |
... | ... |
@@ -200,6 +205,15 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
200 | 205 |
return(http_login(web,connid,uri,userptr)); |
201 | 206 |
} else if(memcmp(uri->path,"/newuser?",9)==0) { |
202 | 207 |
return(http_newuser(web,connid,uri,userptr)); |
208 |
+ } else if(validsession && user[0]!='\0') { |
|
209 |
+ if(memcmp(uri->path,"/lastpost?",10)==0) |
|
210 |
+ return(http_lastpost(web,connid,uri,userptr,user)); |
|
211 |
+ else if(memcmp(uri->path,"/getpost?",9)==0) |
|
212 |
+ return(http_getpost(web,connid,uri,userptr,user)); |
|
213 |
+ else if(memcmp(uri->path,"/newpost?",9)==0) |
|
214 |
+ return(http_newpost(web,connid,uri,userptr,user)); |
|
215 |
+ else if(memcmp(uri->path,"/newcomment?",12)==0) |
|
216 |
+ return(http_newcomment(web,connid,uri,userptr,user)); |
|
203 | 217 |
} |
204 | 218 |
/* not found */ |
205 | 219 |
log_write("HTTP","URI not found: %s",uri->path); |
... | ... |
@@ -314,4 +328,82 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
314 | 328 |
return(wkact_finished); |
315 | 329 |
} |
316 | 330 |
|
331 |
+wk_action |
|
332 |
+http_lastpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
|
333 |
+{ |
|
334 |
+ char reply[64]; |
|
335 |
+ int n; |
|
336 |
+ kakumei *ka=(kakumei *)userptr; |
|
337 |
+ if((n=post_last(ka))<=0) { |
|
338 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
339 |
+ log_write("LSTP","invalid postnum, send error"); |
|
340 |
+ return(wkact_finished); |
|
341 |
+ } |
|
342 |
+ /* valid */ |
|
343 |
+ snprintf(reply,sizeof(reply),"%i",n); |
|
344 |
+ reply[sizeof(reply)-1]='\0'; |
|
345 |
+ wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
|
346 |
+ log_write("LSTP","Reply: %s",reply); |
|
347 |
+ return(wkact_finished); |
|
348 |
+ |
|
349 |
+} |
|
350 |
+ |
|
351 |
+wk_action |
|
352 |
+http_getpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
|
353 |
+{ |
|
354 |
+ kakumei *ka=(kakumei *)userptr; |
|
355 |
+ char filename[1024]; |
|
356 |
+ char n[64]; |
|
357 |
+ int num; |
|
358 |
+ if(wk_uri_copyvar(uri,"n",n,sizeof(n))==NULL) |
|
359 |
+ n[0]='\0'; |
|
360 |
+ num=atoi(n); |
|
361 |
+ if(n[0]=='\0' || num<0 || post_get(ka,num,filename,sizeof(filename))!=0) { |
|
362 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
363 |
+ log_write("GETP","invalid postnum, send error"); |
|
364 |
+ return(wkact_finished); |
|
365 |
+ } |
|
366 |
+ /* valid login */ |
|
367 |
+ wk_serve_file(web,connid,filename,"application/json"); |
|
368 |
+ log_write("GETP","Reply: contents of %s",filename); |
|
369 |
+ return(wkact_finished); |
|
370 |
+} |
|
371 |
+ |
|
372 |
+wk_action |
|
373 |
+http_newpost(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
|
374 |
+{ |
|
375 |
+ char t[8192]; |
|
376 |
+ kakumei *ka=(kakumei *)userptr; |
|
377 |
+ if(wk_uri_copyvar(uri,"t",t,sizeof(t))==NULL) |
|
378 |
+ t[0]='\0'; |
|
379 |
+ if(t[0]=='\0' || post_new(ka,user,t)!=0) { |
|
380 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
381 |
+ log_write("NEWP","invalid post, send error"); |
|
382 |
+ return(wkact_finished); |
|
383 |
+ } |
|
384 |
+ log_write("NEWP","Replying with last post"); |
|
385 |
+ return(http_lastpost(web,connid,uri,userptr,user)); |
|
386 |
+} |
|
387 |
+ |
|
388 |
+wk_action |
|
389 |
+http_newcomment(wk *web, int connid, wk_uri *uri, void *userptr,char *user) |
|
390 |
+{ |
|
391 |
+ char t[8192]; |
|
392 |
+ kakumei *ka=(kakumei *)userptr; |
|
393 |
+ char n[64]; |
|
394 |
+ int num; |
|
395 |
+ if(wk_uri_copyvar(uri,"n",n,sizeof(n))==NULL) |
|
396 |
+ n[0]='\0'; |
|
397 |
+ num=atoi(n); |
|
398 |
+ if(wk_uri_copyvar(uri,"t",t,sizeof(t))==NULL) |
|
399 |
+ t[0]='\0'; |
|
400 |
+ if(n[0]=='\0' || n<0 || t[0]=='\0' || post_addcomment(ka,num,user,t)!=0) { |
|
401 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
402 |
+ log_write("NEWC","invalid post, send error"); |
|
403 |
+ return(wkact_finished); |
|
404 |
+ } |
|
405 |
+ wk_serve_buffer_as_file(web,connid,n,strlen(n),"text/plain"); |
|
406 |
+ log_write("NEWC","Reply: %s",n); |
|
407 |
+ return(wkact_finished); |
|
408 |
+} |
|
317 | 409 |
|
... | ... |
@@ -156,7 +156,6 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
156 | 156 |
log_write("HTTP","Request: /newuser?..."); |
157 | 157 |
else |
158 | 158 |
log_write("HTTP","Request: %s",uri->path); |
159 |
- |
|
160 | 159 |
/* extract the name */ |
161 | 160 |
strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
162 | 161 |
partialpath[sizeof(partialpath)-1]='\0'; |
... | ... |
@@ -188,7 +187,7 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
188 | 187 |
return(wkact_finished); |
189 | 188 |
} else if((res=res_find(resindexdata,"index.html"))!=NULL) { |
190 | 189 |
log_write("HTTP","Not allowed page, redirecting to login"); |
191 |
- wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
190 |
+ wk_serve_redirect(web,connid,"/"); |
|
192 | 191 |
return(wkact_finished); |
193 | 192 |
} else { |
194 | 193 |
log_write("EINT","%s:%i",__FILE__,__LINE__); |
... | ... |
@@ -287,8 +286,8 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
287 | 286 |
/* check validity */ |
288 | 287 |
if(kakumei_inviteexists(ka,i)!=0) { |
289 | 288 |
/* retry login */ |
290 |
- wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
|
291 | 289 |
log_write("NEWU","invalid invite %s, redirecting to login",i); |
290 |
+ wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
|
292 | 291 |
return(wkact_finished); |
293 | 292 |
} |
294 | 293 |
/* create user */ |
... | ... |
@@ -303,8 +302,8 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
303 | 302 |
/* create session and go to "posts" page */ |
304 | 303 |
if(session_new(ka,u,session,sizeof(session))==NULL) { |
305 | 304 |
/* "autologin" didn't work, ask for login */ |
306 |
- wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
|
307 | 305 |
log_write("NEWU","couldn't generate new session, redirecting to login"); |
306 |
+ wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
|
308 | 307 |
return(wkact_finished); |
309 | 308 |
} |
310 | 309 |
/* valid login */ |
... | ... |
@@ -135,6 +135,18 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
135 | 135 |
resindex *res; |
136 | 136 |
char partialpath[1024]; |
137 | 137 |
char *ptr; |
138 |
+ struct { |
|
139 |
+ char *name; |
|
140 |
+ } whitelist[]={{"/index.html"}, |
|
141 |
+ {"/newuser.html"} |
|
142 |
+ }; |
|
143 |
+ int len; |
|
144 |
+ int ishtml; |
|
145 |
+ int whitelisted; |
|
146 |
+ int validsession; |
|
147 |
+ char session[SESSIONSIZE]; |
|
148 |
+ char user[MAXUSERSIZE+1]; |
|
149 |
+ int i; |
|
138 | 150 |
if(ka==NULL) |
139 | 151 |
return(wkact_finished); |
140 | 152 |
/* log without passwords */ |
... | ... |
@@ -144,17 +156,45 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
144 | 156 |
log_write("HTTP","Request: /newuser?..."); |
145 | 157 |
else |
146 | 158 |
log_write("HTTP","Request: %s",uri->path); |
147 |
- /* check for an in-memory file */ |
|
159 |
+ |
|
160 |
+ /* extract the name */ |
|
148 | 161 |
strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
149 | 162 |
partialpath[sizeof(partialpath)-1]='\0'; |
163 |
+ if(strcmp(uri->path,"/")==0) |
|
164 |
+ strcpy(partialpath,"/index.html"); |
|
150 | 165 |
if((ptr=strchr(partialpath,'?'))!=NULL) |
151 | 166 |
*ptr='\0'; |
152 |
-#warning TODO check if the page is a "protected" one and, in that case, check for correct session id |
|
153 |
- if((strcmp(uri->path,"/")==0 && (res=res_find(resindexdata,"index.html"))!=NULL) || |
|
154 |
- (partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL)) { |
|
155 |
- log_write("HTTP","Serving in-memory file %s",partialpath+1); |
|
156 |
- wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
157 |
- return(wkact_finished); |
|
167 |
+ /* check whitelist */ |
|
168 |
+ len=strlen(partialpath); |
|
169 |
+ ishtml=(len>5 && strcmp(partialpath+len-5,".html")==0)?1:0; |
|
170 |
+ if(ishtml) { |
|
171 |
+ for(whitelisted=0,i=0;i<(sizeof(whitelist)/sizeof(whitelist[0]));i++) { |
|
172 |
+ if(strcmp(partialpath,whitelist[i].name)==0) { |
|
173 |
+ whitelisted=1; |
|
174 |
+ break; |
|
175 |
+ } |
|
176 |
+ } |
|
177 |
+ } else |
|
178 |
+ whitelisted=1; |
|
179 |
+ if(wk_uri_copyvar(uri,"s",session,sizeof(session))==NULL) |
|
180 |
+ session[0]='\0'; |
|
181 |
+ user[0]='\0'; |
|
182 |
+ validsession=(session_check(ka,session,user,sizeof(user))!=NULL)?1:0; |
|
183 |
+ /* serve the page */ |
|
184 |
+ if(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL) { |
|
185 |
+ if(whitelisted || validsession) { |
|
186 |
+ log_write("HTTP","Serving in-memory file %s",partialpath+1); |
|
187 |
+ wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
188 |
+ return(wkact_finished); |
|
189 |
+ } else if((res=res_find(resindexdata,"index.html"))!=NULL) { |
|
190 |
+ log_write("HTTP","Not allowed page, redirecting to login"); |
|
191 |
+ wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
192 |
+ return(wkact_finished); |
|
193 |
+ } else { |
|
194 |
+ log_write("EINT","%s:%i",__FILE__,__LINE__); |
|
195 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
196 |
+ return(wkact_finished); /* internal error */ |
|
197 |
+ } |
|
158 | 198 |
} |
159 | 199 |
/* check for actions */ |
160 | 200 |
if(memcmp(uri->path,"/login?",7)==0) { |
... | ... |
@@ -195,6 +235,7 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
195 | 235 |
kakumei *ka=(kakumei *)userptr; |
196 | 236 |
if(web==NULL || connid<0 || uri==NULL || ka==NULL) { |
197 | 237 |
log_write("EINT","%s:%i",__FILE__,__LINE__); |
238 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
198 | 239 |
return(wkact_finished); /* internal error */ |
199 | 240 |
} |
200 | 241 |
if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
... | ... |
@@ -233,6 +274,7 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
233 | 274 |
kakumei *ka=(kakumei *)userptr; |
234 | 275 |
if(web==NULL || connid<0 || uri==NULL || ka==NULL) { |
235 | 276 |
log_write("EINT","%s:%i",__FILE__,__LINE__); |
277 |
+ |
|
236 | 278 |
return(wkact_finished); /* internal error */ |
237 | 279 |
} |
238 | 280 |
/* get vars */ |
... | ... |
@@ -17,6 +17,7 @@ |
17 | 17 |
#include <unistd.h> |
18 | 18 |
#include "gen_res.h" |
19 | 19 |
#include "socklib.h" |
20 |
+#include "loglib.h" |
|
20 | 21 |
#include "webkernel.h" |
21 | 22 |
#include "kakumei.h" |
22 | 23 |
#include "kakumei_session.h" |
... | ... |
@@ -47,22 +48,24 @@ main(int argc, char *argv[]) |
47 | 48 |
} |
48 | 49 |
port=atoi(argv[1]); |
49 | 50 |
if((ka->ssel=sselect_init())==NULL) { |
50 |
- fprintf(stderr,"ERROR: insufficient memory\n"); |
|
51 |
+ log_write("INIT","ERROR: insufficient memory"); |
|
51 | 52 |
return(1); |
52 | 53 |
} |
53 | 54 |
if((ka->web=wk_init(port,ka->ssel,NULL,callback_http,NULL,NULL,ka))==NULL) { |
54 | 55 |
sselect_free(ka->ssel),ka->ssel=NULL; |
55 |
- fprintf(stderr,"ERROR: couldn't init web server\n"); |
|
56 |
+ log_write("INIT","ERROR: couldn't init web server"); |
|
56 | 57 |
return(2); |
57 | 58 |
} |
58 | 59 |
sigint_flag=0; |
59 | 60 |
signal_init(SIGINT,sigint); |
61 |
+ log_write("INIT","Server initialized, waiting connections..."); |
|
60 | 62 |
while(!sigint_flag) { |
61 | 63 |
sselect_wait(ka->ssel,timeout); |
62 | 64 |
wk_service(ka->web); |
63 | 65 |
} |
64 | 66 |
wk_free(ka->web),ka->web=NULL; |
65 | 67 |
sselect_free(ka->ssel),ka->ssel=NULL; |
68 |
+ log_write("FINI","SIGINT detected, exiting..."); |
|
66 | 69 |
return(0); |
67 | 70 |
} |
68 | 71 |
|
... | ... |
@@ -134,22 +137,33 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
134 | 137 |
char *ptr; |
135 | 138 |
if(ka==NULL) |
136 | 139 |
return(wkact_finished); |
137 |
- printf("http: %s\n",uri->path); |
|
140 |
+ /* log without passwords */ |
|
141 |
+ if(memcmp(uri->path,"/login?",7)==0) |
|
142 |
+ log_write("HTTP","Request: /login?..."); |
|
143 |
+ else if(memcmp(uri->path,"/newuser?",9)==0) |
|
144 |
+ log_write("HTTP","Request: /newuser?..."); |
|
145 |
+ else |
|
146 |
+ log_write("HTTP","Request: %s",uri->path); |
|
147 |
+ /* check for an in-memory file */ |
|
138 | 148 |
strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
139 | 149 |
partialpath[sizeof(partialpath)-1]='\0'; |
140 | 150 |
if((ptr=strchr(partialpath,'?'))!=NULL) |
141 | 151 |
*ptr='\0'; |
152 |
+#warning TODO check if the page is a "protected" one and, in that case, check for correct session id |
|
142 | 153 |
if((strcmp(uri->path,"/")==0 && (res=res_find(resindexdata,"index.html"))!=NULL) || |
143 | 154 |
(partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL)) { |
155 |
+ log_write("HTTP","Serving in-memory file %s",partialpath+1); |
|
144 | 156 |
wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
145 | 157 |
return(wkact_finished); |
146 | 158 |
} |
159 |
+ /* check for actions */ |
|
147 | 160 |
if(memcmp(uri->path,"/login?",7)==0) { |
148 | 161 |
return(http_login(web,connid,uri,userptr)); |
149 | 162 |
} else if(memcmp(uri->path,"/newuser?",9)==0) { |
150 | 163 |
return(http_newuser(web,connid,uri,userptr)); |
151 | 164 |
} |
152 |
- printf("URI not found: %s\n",uri->path); |
|
165 |
+ /* not found */ |
|
166 |
+ log_write("HTTP","URI not found: %s",uri->path); |
|
153 | 167 |
wk_serve_error(web,connid,wkerr_notfound); |
154 | 168 |
return(wkact_finished); |
155 | 169 |
} |
... | ... |
@@ -179,8 +193,10 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
179 | 193 |
char reply[1024]; |
180 | 194 |
char session[SESSIONSIZE]; |
181 | 195 |
kakumei *ka=(kakumei *)userptr; |
182 |
- if(web==NULL || connid<0 || uri==NULL || ka==NULL) |
|
196 |
+ if(web==NULL || connid<0 || uri==NULL || ka==NULL) { |
|
197 |
+ log_write("EINT","%s:%i",__FILE__,__LINE__); |
|
183 | 198 |
return(wkact_finished); /* internal error */ |
199 |
+ } |
|
184 | 200 |
if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
185 | 201 |
u[0]='\0'; |
186 | 202 |
if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
... | ... |
@@ -192,6 +208,7 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
192 | 208 |
snprintf(reply,sizeof(reply),"/newuser.html?i=%s",p); |
193 | 209 |
reply[sizeof(reply)-1]='\0'; |
194 | 210 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
211 |
+ log_write("LGIN","Reply: %s",reply); |
|
195 | 212 |
return(wkact_finished); |
196 | 213 |
} else if(pass_check(ka,u,p)==0 && |
197 | 214 |
session_new(ka,u,session,sizeof(session))!=NULL) { |
... | ... |
@@ -199,8 +216,10 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
199 | 216 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
200 | 217 |
reply[sizeof(reply)-1]='\0'; |
201 | 218 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
219 |
+ log_write("LGIN","Reply: %s",reply); |
|
202 | 220 |
return(wkact_finished); |
203 | 221 |
} |
222 |
+ log_write("LGIN","Serving error"); |
|
204 | 223 |
wk_serve_error(web,connid,wkerr_internal); |
205 | 224 |
return(wkact_finished); |
206 | 225 |
} |
... | ... |
@@ -212,10 +231,12 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
212 | 231 |
char reply[1024]; |
213 | 232 |
char session[SESSIONSIZE]; |
214 | 233 |
kakumei *ka=(kakumei *)userptr; |
215 |
- if(web==NULL || connid<0 || uri==NULL || ka==NULL) |
|
234 |
+ if(web==NULL || connid<0 || uri==NULL || ka==NULL) { |
|
235 |
+ log_write("EINT","%s:%i",__FILE__,__LINE__); |
|
216 | 236 |
return(wkact_finished); /* internal error */ |
237 |
+ } |
|
217 | 238 |
/* get vars */ |
218 |
- if(wk_uri_copyvar(uri,"i",u,sizeof(i))==NULL) |
|
239 |
+ if(wk_uri_copyvar(uri,"i",i,sizeof(i))==NULL) |
|
219 | 240 |
i[0]='\0'; |
220 | 241 |
if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
221 | 242 |
u[0]='\0'; |
... | ... |
@@ -225,12 +246,14 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
225 | 246 |
if(kakumei_inviteexists(ka,i)!=0) { |
226 | 247 |
/* retry login */ |
227 | 248 |
wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
249 |
+ log_write("NEWU","invalid invite %s, redirecting to login",i); |
|
228 | 250 |
return(wkact_finished); |
229 | 251 |
} |
230 | 252 |
/* create user */ |
231 | 253 |
if(pass_new(ka,u,p)!=0) { |
232 | 254 |
/* error with username */ |
233 | 255 |
wk_serve_error(web,connid,wkerr_internal); |
256 |
+ log_write("NEWU","invalid user, send error"); |
|
234 | 257 |
return(wkact_finished); |
235 | 258 |
} |
236 | 259 |
/* delete invitation */ |
... | ... |
@@ -239,12 +262,14 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
239 | 262 |
if(session_new(ka,u,session,sizeof(session))==NULL) { |
240 | 263 |
/* "autologin" didn't work, ask for login */ |
241 | 264 |
wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
265 |
+ log_write("NEWU","couldn't generate new session, redirecting to login"); |
|
242 | 266 |
return(wkact_finished); |
243 | 267 |
} |
244 | 268 |
/* valid login */ |
245 | 269 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
246 | 270 |
reply[sizeof(reply)-1]='\0'; |
247 | 271 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
272 |
+ log_write("NEWU","Reply: %s",reply); |
|
248 | 273 |
return(wkact_finished); |
249 | 274 |
} |
250 | 275 |
|
... | ... |
@@ -26,6 +26,9 @@ static int signal_init(int signum, void (*fn)(int)); |
26 | 26 |
static void sigint(int signum); |
27 | 27 |
volatile int sigint_flag=0; |
28 | 28 |
|
29 |
+int kakumei_inviteexists(kakumei *ka, char *invite); |
|
30 |
+int kakumei_invitedel(kakumei *ka, char *invite); |
|
31 |
+ |
|
29 | 32 |
wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
30 | 33 |
wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr); |
31 | 34 |
wk_action http_newuser(wk *web, int connid, wk_uri *uri, void *userptr); |
... | ... |
@@ -89,6 +92,39 @@ kakumei_userexists(kakumei *ka, char *username) |
89 | 92 |
return(0); |
90 | 93 |
} |
91 | 94 |
|
95 |
+int |
|
96 |
+kakumei_inviteexists(kakumei *ka, char *invite) |
|
97 |
+{ |
|
98 |
+ char filename[1024]; |
|
99 |
+ struct stat st; |
|
100 |
+ if(invite==NULL) |
|
101 |
+ return(-1); |
|
102 |
+ if(strchr(invite,'/')!=NULL) |
|
103 |
+ return(-1); |
|
104 |
+ if(strcmp(invite,".")==0 || strcmp(invite,"..")==0) |
|
105 |
+ return(-1); |
|
106 |
+ snprintf(filename,sizeof(filename),"%s/%s",INVITESDIR,invite); |
|
107 |
+ filename[sizeof(filename)-1]='\0'; |
|
108 |
+ if(stat(filename,&st)!=0 || !S_ISREG(st.st_mode)) |
|
109 |
+ return(-1); |
|
110 |
+ return(0); |
|
111 |
+} |
|
112 |
+ |
|
113 |
+int |
|
114 |
+kakumei_invitedel(kakumei *ka, char *invite) |
|
115 |
+{ |
|
116 |
+ char filename[1024]; |
|
117 |
+ if(kakumei_inviteexists(ka,invite)!=0) |
|
118 |
+ return(-1); /* doesn't exist */ |
|
119 |
+ snprintf(filename,sizeof(filename),"%s/%s",INVITESDIR,invite); |
|
120 |
+ filename[sizeof(filename)-1]='\0'; |
|
121 |
+ unlink(filename); |
|
122 |
+ if(kakumei_inviteexists(ka,invite)==0) |
|
123 |
+ return(-1); /* couldn't remove invite */ |
|
124 |
+ return(0); |
|
125 |
+} |
|
126 |
+ |
|
127 |
+ |
|
92 | 128 |
wk_action |
93 | 129 |
callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
94 | 130 |
{ |
... | ... |
@@ -139,12 +175,9 @@ sigint(int signum) |
139 | 175 |
wk_action |
140 | 176 |
http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
141 | 177 |
{ |
142 |
- char u[128],p[128]; |
|
178 |
+ char u[MAXUSERSIZE+1],p[MAXPASSWDSIZE+1]; |
|
143 | 179 |
char reply[1024]; |
144 |
- char invitepath[1024]; |
|
145 |
- char userpath[1024]; |
|
146 |
- char session[1024]; |
|
147 |
- struct stat st; |
|
180 |
+ char session[SESSIONSIZE]; |
|
148 | 181 |
kakumei *ka=(kakumei *)userptr; |
149 | 182 |
if(web==NULL || connid<0 || uri==NULL || ka==NULL) |
150 | 183 |
return(wkact_finished); /* internal error */ |
... | ... |
@@ -153,22 +186,15 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
153 | 186 |
if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
154 | 187 |
p[0]='\0'; |
155 | 188 |
/* check for invitation */ |
156 |
- snprintf(invitepath,sizeof(invitepath),"%s/%s",INVITESDIR,p); |
|
157 |
- invitepath[sizeof(invitepath)-1]='\0'; |
|
158 |
- snprintf(userpath,sizeof(userpath),"%s/%s/passwd",USERSDIR,u); |
|
159 |
- userpath[sizeof(userpath)-1]='\0'; |
|
160 | 189 |
if(strcmp(u,INVITATIONUSER)==0 && |
161 |
- strchr(p,'/')==NULL && strchr(p,'.')==NULL && |
|
162 |
- stat(invitepath,&st)==0 && S_ISREG(st.st_mode)) { |
|
190 |
+ kakumei_inviteexists(ka,p)==0) { |
|
163 | 191 |
/* valid invitation */ |
164 | 192 |
snprintf(reply,sizeof(reply),"/newuser.html?i=%s",p); |
165 | 193 |
reply[sizeof(reply)-1]='\0'; |
166 | 194 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
167 | 195 |
return(wkact_finished); |
168 |
- } else if(strchr(u,'/')==NULL && strchr(u,'.')==NULL && |
|
169 |
- stat(userpath,&st)==0 && S_ISREG(st.st_mode) && |
|
170 |
- pass_check(ka,u,p)==0 && |
|
171 |
- session_new(ka,u,session,sizeof(session))!=NULL) { |
|
196 |
+ } else if(pass_check(ka,u,p)==0 && |
|
197 |
+ session_new(ka,u,session,sizeof(session))!=NULL) { |
|
172 | 198 |
/* valid login */ |
173 | 199 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
174 | 200 |
reply[sizeof(reply)-1]='\0'; |
... | ... |
@@ -182,8 +208,43 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
182 | 208 |
wk_action |
183 | 209 |
http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
184 | 210 |
{ |
185 |
-#warning TODO |
|
186 |
- wk_serve_error(web,connid,wkerr_internal); |
|
211 |
+ char u[MAXUSERSIZE+1],p[MAXPASSWDSIZE+1],i[MAXPASSWDSIZE+1]; |
|
212 |
+ char reply[1024]; |
|
213 |
+ char session[SESSIONSIZE]; |
|
214 |
+ kakumei *ka=(kakumei *)userptr; |
|
215 |
+ if(web==NULL || connid<0 || uri==NULL || ka==NULL) |
|
216 |
+ return(wkact_finished); /* internal error */ |
|
217 |
+ /* get vars */ |
|
218 |
+ if(wk_uri_copyvar(uri,"i",u,sizeof(i))==NULL) |
|
219 |
+ i[0]='\0'; |
|
220 |
+ if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
|
221 |
+ u[0]='\0'; |
|
222 |
+ if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
|
223 |
+ p[0]='\0'; |
|
224 |
+ /* check validity */ |
|
225 |
+ if(kakumei_inviteexists(ka,i)!=0) { |
|
226 |
+ /* retry login */ |
|
227 |
+ wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
|
228 |
+ return(wkact_finished); |
|
229 |
+ } |
|
230 |
+ /* create user */ |
|
231 |
+ if(pass_new(ka,u,p)!=0) { |
|
232 |
+ /* error with username */ |
|
233 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
234 |
+ return(wkact_finished); |
|
235 |
+ } |
|
236 |
+ /* delete invitation */ |
|
237 |
+ kakumei_invitedel(ka,i); |
|
238 |
+ /* create session and go to "posts" page */ |
|
239 |
+ if(session_new(ka,u,session,sizeof(session))==NULL) { |
|
240 |
+ /* "autologin" didn't work, ask for login */ |
|
241 |
+ wk_serve_buffer_as_file(web,connid,"/",1,"text/plain"); |
|
242 |
+ return(wkact_finished); |
|
243 |
+ } |
|
244 |
+ /* valid login */ |
|
245 |
+ snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
|
246 |
+ reply[sizeof(reply)-1]='\0'; |
|
247 |
+ wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
|
187 | 248 |
return(wkact_finished); |
188 | 249 |
} |
189 | 250 |
|
... | ... |
@@ -89,8 +89,6 @@ kakumei_userexists(kakumei *ka, char *username) |
89 | 89 |
return(0); |
90 | 90 |
} |
91 | 91 |
|
92 |
- |
|
93 |
- |
|
94 | 92 |
wk_action |
95 | 93 |
callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
96 | 94 |
{ |
... | ... |
@@ -136,6 +134,8 @@ sigint(int signum) |
136 | 134 |
sigint_flag=1; |
137 | 135 |
} |
138 | 136 |
|
137 |
+/* implement the "XmlHttpRequest"s (the reply is the new page to load) */ |
|
138 |
+ |
|
139 | 139 |
wk_action |
140 | 140 |
http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
141 | 141 |
{ |
... | ... |
@@ -63,6 +63,34 @@ main(int argc, char *argv[]) |
63 | 63 |
return(0); |
64 | 64 |
} |
65 | 65 |
|
66 |
+int |
|
67 |
+kakumei_uservalid(kakumei *ka, char *username) |
|
68 |
+{ |
|
69 |
+ if(username==NULL) |
|
70 |
+ return(-1); |
|
71 |
+ if(strchr(username,'/')!=NULL) |
|
72 |
+ return(-1); |
|
73 |
+ if(strcmp(username,".")==0 || strcmp(username,"..")==0) |
|
74 |
+ return(-1); |
|
75 |
+ return(0); |
|
76 |
+} |
|
77 |
+ |
|
78 |
+int |
|
79 |
+kakumei_userexists(kakumei *ka, char *username) |
|
80 |
+{ |
|
81 |
+ char filename[1024]; |
|
82 |
+ struct stat st; |
|
83 |
+ if(kakumei_uservalid(ka,username)!=0) |
|
84 |
+ return(-1); |
|
85 |
+ snprintf(filename,sizeof(filename),"%s/%s/passwd",USERSDIR,username); |
|
86 |
+ filename[sizeof(filename)-1]='\0'; |
|
87 |
+ if(stat(filename,&st)!=0 || !S_ISREG(st.st_mode)) |
|
88 |
+ return(-1); |
|
89 |
+ return(0); |
|
90 |
+} |
|
91 |
+ |
|
92 |
+ |
|
93 |
+ |
|
66 | 94 |
wk_action |
67 | 95 |
callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
68 | 96 |
{ |
... | ... |
@@ -20,6 +20,7 @@ |
20 | 20 |
#include "webkernel.h" |
21 | 21 |
#include "kakumei.h" |
22 | 22 |
#include "kakumei_session.h" |
23 |
+#include "kakumei_pass.h" |
|
23 | 24 |
|
24 | 25 |
static int signal_init(int signum, void (*fn)(int)); |
25 | 26 |
static void sigint(int signum); |
... | ... |
@@ -29,8 +30,6 @@ wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
29 | 30 |
wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr); |
30 | 31 |
wk_action http_newuser(wk *web, int connid, wk_uri *uri, void *userptr); |
31 | 32 |
|
32 |
-int pass_check(char *user, char *passwd); |
|
33 |
- |
|
34 | 33 |
int |
35 | 34 |
main(int argc, char *argv[]) |
36 | 35 |
{ |
... | ... |
@@ -139,7 +138,8 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
139 | 138 |
wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
140 | 139 |
return(wkact_finished); |
141 | 140 |
} else if(strchr(u,'/')==NULL && strchr(u,'.')==NULL && |
142 |
- stat(userpath,&st)==0 && S_ISREG(st.st_mode) && pass_check(u,p)==0 && |
|
141 |
+ stat(userpath,&st)==0 && S_ISREG(st.st_mode) && |
|
142 |
+ pass_check(ka,u,p)==0 && |
|
143 | 143 |
session_new(ka,u,session,sizeof(session))!=NULL) { |
144 | 144 |
/* valid login */ |
145 | 145 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
... | ... |
@@ -160,10 +160,3 @@ http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
160 | 160 |
} |
161 | 161 |
|
162 | 162 |
|
163 |
-int |
|
164 |
-pass_check(char *user, char *passwd) |
|
165 |
-{ |
|
166 |
-#warning TODO |
|
167 |
- return(-1); |
|
168 |
-} |
|
169 |
- |
... | ... |
@@ -18,19 +18,8 @@ |
18 | 18 |
#include "gen_res.h" |
19 | 19 |
#include "socklib.h" |
20 | 20 |
#include "webkernel.h" |
21 |
- |
|
22 |
-#define INVITATIONUSER "invitation" |
|
23 |
-#define DATADIR "data" |
|
24 |
-#define INVITESDIR "data/invitations" |
|
25 |
-#define USERSDIR "data/users" |
|
26 |
-#define POSTSDIR "data/posts" |
|
27 |
-#define SESSIONSDIR "data/sessions" |
|
28 |
- |
|
29 |
-typedef struct kakumei { |
|
30 |
- sselect *ssel; |
|
31 |
- wk *web; |
|
32 |
-} kakumei; |
|
33 |
- |
|
21 |
+#include "kakumei.h" |
|
22 |
+#include "kakumei_session.h" |
|
34 | 23 |
|
35 | 24 |
static int signal_init(int signum, void (*fn)(int)); |
36 | 25 |
static void sigint(int signum); |
... | ... |
@@ -41,9 +30,6 @@ wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr); |
41 | 30 |
wk_action http_newuser(wk *web, int connid, wk_uri *uri, void *userptr); |
42 | 31 |
|
43 | 32 |
int pass_check(char *user, char *passwd); |
44 |
-char *session_new(char *user, char *session, int sessionsize); |
|
45 |
- |
|
46 |
- |
|
47 | 33 |
|
48 | 34 |
int |
49 | 35 |
main(int argc, char *argv[]) |
... | ... |
@@ -132,6 +118,9 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
132 | 118 |
char userpath[1024]; |
133 | 119 |
char session[1024]; |
134 | 120 |
struct stat st; |
121 |
+ kakumei *ka=(kakumei *)userptr; |
|
122 |
+ if(web==NULL || connid<0 || uri==NULL || ka==NULL) |
|
123 |
+ return(wkact_finished); /* internal error */ |
|
135 | 124 |
if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
136 | 125 |
u[0]='\0'; |
137 | 126 |
if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
... | ... |
@@ -151,7 +140,7 @@ http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
151 | 140 |
return(wkact_finished); |
152 | 141 |
} else if(strchr(u,'/')==NULL && strchr(u,'.')==NULL && |
153 | 142 |
stat(userpath,&st)==0 && S_ISREG(st.st_mode) && pass_check(u,p)==0 && |
154 |
- session_new(u,session,sizeof(session))!=NULL) { |
|
143 |
+ session_new(ka,u,session,sizeof(session))!=NULL) { |
|
155 | 144 |
/* valid login */ |
156 | 145 |
snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
157 | 146 |
reply[sizeof(reply)-1]='\0'; |
... | ... |
@@ -178,10 +167,3 @@ pass_check(char *user, char *passwd) |
178 | 167 |
return(-1); |
179 | 168 |
} |
180 | 169 |
|
181 |
-char * |
|
182 |
-session_new(char *user, char *session, int sessionsize) |
|
183 |
-{ |
|
184 |
-#warning TODO |
|
185 |
- return(NULL); |
|
186 |
-} |
|
187 |
- |
... | ... |
@@ -12,10 +12,20 @@ |
12 | 12 |
#include <unistd.h> |
13 | 13 |
#include <string.h> |
14 | 14 |
#include <signal.h> |
15 |
+#include <sys/types.h> |
|
16 |
+#include <sys/stat.h> |
|
17 |
+#include <unistd.h> |
|
15 | 18 |
#include "gen_res.h" |
16 | 19 |
#include "socklib.h" |
17 | 20 |
#include "webkernel.h" |
18 | 21 |
|
22 |
+#define INVITATIONUSER "invitation" |
|
23 |
+#define DATADIR "data" |
|
24 |
+#define INVITESDIR "data/invitations" |
|
25 |
+#define USERSDIR "data/users" |
|
26 |
+#define POSTSDIR "data/posts" |
|
27 |
+#define SESSIONSDIR "data/sessions" |
|
28 |
+ |
|
19 | 29 |
typedef struct kakumei { |
20 | 30 |
sselect *ssel; |
21 | 31 |
wk *web; |
... | ... |
@@ -27,6 +37,13 @@ static void sigint(int signum); |
27 | 37 |
volatile int sigint_flag=0; |
28 | 38 |
|
29 | 39 |
wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
40 |
+wk_action http_login(wk *web, int connid, wk_uri *uri, void *userptr); |
|
41 |
+wk_action http_newuser(wk *web, int connid, wk_uri *uri, void *userptr); |
|
42 |
+ |
|
43 |
+int pass_check(char *user, char *passwd); |
|
44 |
+char *session_new(char *user, char *session, int sessionsize); |
|
45 |
+ |
|
46 |
+ |
|
30 | 47 |
|
31 | 48 |
int |
32 | 49 |
main(int argc, char *argv[]) |
... | ... |
@@ -66,24 +83,24 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
66 | 83 |
{ |
67 | 84 |
kakumei *ka=(kakumei *)userptr; |
68 | 85 |
resindex *res; |
86 |
+ char partialpath[1024]; |
|
87 |
+ char *ptr; |
|
69 | 88 |
if(ka==NULL) |
70 | 89 |
return(wkact_finished); |
90 |
+ printf("http: %s\n",uri->path); |
|
91 |
+ strncpy(partialpath,uri->path,sizeof(partialpath)-1); |
|
92 |
+ partialpath[sizeof(partialpath)-1]='\0'; |
|
93 |
+ if((ptr=strchr(partialpath,'?'))!=NULL) |
|
94 |
+ *ptr='\0'; |
|
71 | 95 |
if((strcmp(uri->path,"/")==0 && (res=res_find(resindexdata,"index.html"))!=NULL) || |
72 |
- (uri->path[0]=='/' && (res=res_find(resindexdata,uri->path+1))!=NULL)) { |
|
96 |
+ (partialpath[0]=='/' && (res=res_find(resindexdata,partialpath+1))!=NULL)) { |
|
73 | 97 |
wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
74 | 98 |
return(wkact_finished); |
75 | 99 |
} |
76 |
- if(memcmp(uri->path,"/doLogin?",9)==0) { |
|
77 |
- char u[128],p[128]; |
|
78 |
- if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
|
79 |
- u[0]='\0'; |
|
80 |
- if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
|
81 |
- p[0]='\0'; |
|
82 |
- printf("URI: %s\n",uri->path); |
|
83 |
- printf("Login: \"%s\"\n",u); |
|
84 |
- printf("Pass.: \"%s\"\n",p); |
|
85 |
- wk_serve_error(web,connid,wkerr_internal); |
|
86 |
- return(wkact_finished); |
|
100 |
+ if(memcmp(uri->path,"/login?",7)==0) { |
|
101 |
+ return(http_login(web,connid,uri,userptr)); |
|
102 |
+ } else if(memcmp(uri->path,"/newuser?",9)==0) { |
|
103 |
+ return(http_newuser(web,connid,uri,userptr)); |
|
87 | 104 |
} |
88 | 105 |
printf("URI not found: %s\n",uri->path); |
89 | 106 |
wk_serve_error(web,connid,wkerr_notfound); |
... | ... |
@@ -106,3 +123,65 @@ sigint(int signum) |
106 | 123 |
sigint_flag=1; |
107 | 124 |
} |
108 | 125 |
|
126 |
+wk_action |
|
127 |
+http_login(wk *web, int connid, wk_uri *uri, void *userptr) |
|
128 |
+{ |
|
129 |
+ char u[128],p[128]; |
|
130 |
+ char reply[1024]; |
|
131 |
+ char invitepath[1024]; |
|
132 |
+ char userpath[1024]; |
|
133 |
+ char session[1024]; |
|
134 |
+ struct stat st; |
|
135 |
+ if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
|
136 |
+ u[0]='\0'; |
|
137 |
+ if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
|
138 |
+ p[0]='\0'; |
|
139 |
+ /* check for invitation */ |
|
140 |
+ snprintf(invitepath,sizeof(invitepath),"%s/%s",INVITESDIR,p); |
|
141 |
+ invitepath[sizeof(invitepath)-1]='\0'; |
|
142 |
+ snprintf(userpath,sizeof(userpath),"%s/%s/passwd",USERSDIR,u); |
|
143 |
+ userpath[sizeof(userpath)-1]='\0'; |
|
144 |
+ if(strcmp(u,INVITATIONUSER)==0 && |
|
145 |
+ strchr(p,'/')==NULL && strchr(p,'.')==NULL && |
|
146 |
+ stat(invitepath,&st)==0 && S_ISREG(st.st_mode)) { |
|
147 |
+ /* valid invitation */ |
|
148 |
+ snprintf(reply,sizeof(reply),"/newuser.html?i=%s",p); |
|
149 |
+ reply[sizeof(reply)-1]='\0'; |
|
150 |
+ wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
|
151 |
+ return(wkact_finished); |
|
152 |
+ } else if(strchr(u,'/')==NULL && strchr(u,'.')==NULL && |
|
153 |
+ stat(userpath,&st)==0 && S_ISREG(st.st_mode) && pass_check(u,p)==0 && |
|
154 |
+ session_new(u,session,sizeof(session))!=NULL) { |
|
155 |
+ /* valid login */ |
|
156 |
+ snprintf(reply,sizeof(reply),"/posts.html?s=%s",session); |
|
157 |
+ reply[sizeof(reply)-1]='\0'; |
|
158 |
+ wk_serve_buffer_as_file(web,connid,reply,strlen(reply),"text/plain"); |
|
159 |
+ return(wkact_finished); |
|
160 |
+ } |
|
161 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
162 |
+ return(wkact_finished); |
|
163 |
+} |
|
164 |
+ |
|
165 |
+wk_action |
|
166 |
+http_newuser(wk *web, int connid, wk_uri *uri, void *userptr) |
|
167 |
+{ |
|
168 |
+#warning TODO |
|
169 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
170 |
+ return(wkact_finished); |
|
171 |
+} |
|
172 |
+ |
|
173 |
+ |
|
174 |
+int |
|
175 |
+pass_check(char *user, char *passwd) |
|
176 |
+{ |
|
177 |
+#warning TODO |
|
178 |
+ return(-1); |
|
179 |
+} |
|
180 |
+ |
|
181 |
+char * |
|
182 |
+session_new(char *user, char *session, int sessionsize) |
|
183 |
+{ |
|
184 |
+#warning TODO |
|
185 |
+ return(NULL); |
|
186 |
+} |
|
187 |
+ |
... | ... |
@@ -45,7 +45,7 @@ main(int argc, char *argv[]) |
45 | 45 |
fprintf(stderr,"ERROR: insufficient memory\n"); |
46 | 46 |
return(1); |
47 | 47 |
} |
48 |
- if((ka->web=wk_init(port,ka->ssel,NULL,callback_http,NULL,ka))==NULL) { |
|
48 |
+ if((ka->web=wk_init(port,ka->ssel,NULL,callback_http,NULL,NULL,ka))==NULL) { |
|
49 | 49 |
sselect_free(ka->ssel),ka->ssel=NULL; |
50 | 50 |
fprintf(stderr,"ERROR: couldn't init web server\n"); |
51 | 51 |
return(2); |
... | ... |
@@ -74,7 +74,14 @@ callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
74 | 74 |
return(wkact_finished); |
75 | 75 |
} |
76 | 76 |
if(memcmp(uri->path,"/doLogin?",9)==0) { |
77 |
- printf("Login: %s\n",uri->path+9); |
|
77 |
+ char u[128],p[128]; |
|
78 |
+ if(wk_uri_copyvar(uri,"u",u,sizeof(u))==NULL) |
|
79 |
+ u[0]='\0'; |
|
80 |
+ if(wk_uri_copyvar(uri,"p",p,sizeof(p))==NULL) |
|
81 |
+ p[0]='\0'; |
|
82 |
+ printf("URI: %s\n",uri->path); |
|
83 |
+ printf("Login: \"%s\"\n",u); |
|
84 |
+ printf("Pass.: \"%s\"\n",p); |
|
78 | 85 |
wk_serve_error(web,connid,wkerr_internal); |
79 | 86 |
return(wkact_finished); |
80 | 87 |
} |
... | ... |
@@ -7,8 +7,95 @@ |
7 | 7 |
* This progran is licensed under the terms of the Affero GPL v1+ |
8 | 8 |
*/ |
9 | 9 |
|
10 |
+#include <stdio.h> |
|
11 |
+#include <stdlib.h> |
|
12 |
+#include <unistd.h> |
|
13 |
+#include <string.h> |
|
14 |
+#include <signal.h> |
|
15 |
+#include "gen_res.h" |
|
16 |
+#include "socklib.h" |
|
17 |
+#include "webkernel.h" |
|
18 |
+ |
|
19 |
+typedef struct kakumei { |
|
20 |
+ sselect *ssel; |
|
21 |
+ wk *web; |
|
22 |
+} kakumei; |
|
23 |
+ |
|
24 |
+ |
|
25 |
+static int signal_init(int signum, void (*fn)(int)); |
|
26 |
+static void sigint(int signum); |
|
27 |
+volatile int sigint_flag=0; |
|
28 |
+ |
|
29 |
+wk_action callback_http(wk *web, int connid, wk_uri *uri, void *userptr); |
|
30 |
+ |
|
10 | 31 |
int |
11 | 32 |
main(int argc, char *argv[]) |
12 | 33 |
{ |
34 |
+ int port; |
|
35 |
+ int timeout=500; |
|
36 |
+ kakumei *ka,kastore; |
|
37 |
+ memset(&kastore,0,sizeof(kastore)); |
|
38 |
+ ka=&kastore; |
|
39 |
+ if(argc!=2) { |
|
40 |
+ printf("Syntax: %s port\n",argv[0]); |
|
41 |
+ return(1); |
|
42 |
+ } |
|
43 |
+ port=atoi(argv[1]); |
|
44 |
+ if((ka->ssel=sselect_init())==NULL) { |
|
45 |
+ fprintf(stderr,"ERROR: insufficient memory\n"); |
|
46 |
+ return(1); |
|
47 |
+ } |
|
48 |
+ if((ka->web=wk_init(port,ka->ssel,NULL,callback_http,NULL,ka))==NULL) { |
|
49 |
+ sselect_free(ka->ssel),ka->ssel=NULL; |
|
50 |
+ fprintf(stderr,"ERROR: couldn't init web server\n"); |
|
51 |
+ return(2); |
|
52 |
+ } |
|
53 |
+ sigint_flag=0; |
|
54 |
+ signal_init(SIGINT,sigint); |
|
55 |
+ while(!sigint_flag) { |
|
56 |
+ sselect_wait(ka->ssel,timeout); |
|
57 |
+ wk_service(ka->web); |
|
58 |
+ } |
|
59 |
+ wk_free(ka->web),ka->web=NULL; |
|
60 |
+ sselect_free(ka->ssel),ka->ssel=NULL; |
|
13 | 61 |
return(0); |
14 | 62 |
} |
63 |
+ |
|
64 |
+wk_action |
|
65 |
+callback_http(wk *web, int connid, wk_uri *uri, void *userptr) |
|
66 |
+{ |
|
67 |
+ kakumei *ka=(kakumei *)userptr; |
|
68 |
+ resindex *res; |
|
69 |
+ if(ka==NULL) |
|
70 |
+ return(wkact_finished); |
|
71 |
+ if((strcmp(uri->path,"/")==0 && (res=res_find(resindexdata,"index.html"))!=NULL) || |
|
72 |
+ (uri->path[0]=='/' && (res=res_find(resindexdata,uri->path+1))!=NULL)) { |
|
73 |
+ wk_serve_buffer_as_file(web,connid,res->data,res->len,mime_getdefault(res->name,"application/octet-stream")); |
|
74 |
+ return(wkact_finished); |
|
75 |
+ } |
|
76 |
+ if(memcmp(uri->path,"/doLogin?",9)==0) { |
|
77 |
+ printf("Login: %s\n",uri->path+9); |
|
78 |
+ wk_serve_error(web,connid,wkerr_internal); |
|
79 |
+ return(wkact_finished); |
|
80 |
+ } |
|
81 |
+ printf("URI not found: %s\n",uri->path); |
|
82 |
+ wk_serve_error(web,connid,wkerr_notfound); |
|
83 |
+ return(wkact_finished); |
|
84 |
+} |
|
85 |
+ |
|
86 |
+static int |
|
87 |
+signal_init(int signum, void (*fn)(int)) |
|
88 |
+{ |
|
89 |
+ struct sigaction sa; |
|
90 |
+ sa.sa_handler=fn; |
|
91 |
+ sigemptyset(&sa.sa_mask); |
|
92 |
+ sa.sa_flags=0; |
|
93 |
+ return(sigaction(signum,&sa,0)); |
|
94 |
+} |
|
95 |
+ |
|
96 |
+static void |
|
97 |
+sigint(int signum) |
|
98 |
+{ |
|
99 |
+ sigint_flag=1; |
|
100 |
+} |
|
101 |
+ |
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,14 @@ |
1 |
+/* |
|
2 |
+ * kakumei.c |
|
3 |
+ * |
|
4 |
+ * Private group web. |
|
5 |
+ * |
|
6 |
+ * Author: Dario Rodriguez dario@softhome.net |
|
7 |
+ * This progran is licensed under the terms of the Affero GPL v1+ |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+int |
|
11 |
+main(int argc, char *argv[]) |
|
12 |
+{ |
|
13 |
+ return(0); |
|
14 |
+} |