#include #include #include #include #include #include #include #include MYSQL* sql; const char* rand_ch="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; Json::Value do_login(Json::Value o) { MYSQL_RES* sqlr=NULL; MYSQL_ROW row; char q[256]; Json::Value ret; std::string usrname=o["username"].asString(); std::string passwd=o["passwd"].asString(); std::string sessname=o["sessionname"].asString(); std::string token; std::string qpwd; if(usrname.length()<1){ret["result"]=1;goto fail;} for(size_t i=0;i0){ret["result"]=2;goto fail;} mysql_free_result(sqlr);sqlr=NULL; } do{ if(sqlr){mysql_free_result(sqlr);sqlr=NULL;} token=""; for(int i=0;i<32;++i)token.push_back(rand_ch[rand()%62]); snprintf(q,256,"select token from navigator_session where token='%s'", token.c_str()); mysql_query(sql,q); sqlr=mysql_store_result(sql); }while(mysql_num_rows(sqlr)); mysql_free_result(sqlr);sqlr=NULL; snprintf(q,256,"insert into navigator_session values('%s','%s','%s',%lld)", usrname.c_str(), token.c_str(), sessname.c_str(), time(NULL) ); mysql_query(sql,q); mysql_commit(sql); ret["result"]=0; ret["token"]=token; fail: if(sqlr){mysql_free_result(sqlr);sqlr=NULL;} return ret; } const int tsl[]={1800,86400,604800,1296000,2592000,5184000,7776000,15552000,31104000}; void set_session_length(std::string user,int c) { char q[256]; if(c>7)c=7;if(c<0)c=0; snprintf(q,256,"update navigator_user set session_length=%d where username='%s'",user.c_str()); mysql_query(sql,q); mysql_commit(sql); } int get_session_length(std::string user) { MYSQL_RES* sqlr=NULL; MYSQL_ROW row; char q[256]; snprintf(q,256,"select session_length from navigator_user where username='%s'",user.c_str()); mysql_query(sql,q); sqlr=mysql_store_result(sql); if(mysql_num_rows(sqlr)!=1){mysql_free_result(sqlr);return -1;} row=mysql_fetch_row(sqlr); int sl=atoi(row[0]); mysql_free_result(sqlr); return sl; } std::string authenticate(std::string token) { MYSQL_RES* sqlr=NULL; MYSQL_ROW row; char q[256]; if(token.length()!=32)return ""; snprintf(q,256,"select username,sessionname,date from navigator_session where token='%s'",token.c_str()); mysql_query(sql,q); sqlr=mysql_store_result(sql); if(mysql_num_rows(sqlr)!=1){mysql_free_result(sqlr);return "";} row=mysql_fetch_row(sqlr); std::string ret=std::string(row[0]); bool is_temporary=strlen(row[1])>0; long long d=atoll(row[2]); mysql_free_result(sqlr); int sl=get_session_length(ret); if(sl<0||sl>7){return "";} int reall=tsl[is_temporary?0:sl+1]; if(time(NULL)-d>reall) { snprintf(q,256,"delete from navigator_session where token='%s'",token.c_str()); mysql_query(sql,q); mysql_commit(sql); return ""; } return ret; } Json::Value set_option(Json::Value o) { Json::Value ret; std::string token=o["token"].asString(); std::string usr=authenticate(token); int opt=o["option"].asInt(); int val=o["value"].asInt(); if(!usr.length()){ret["result"]=1;goto fail;} switch(opt) { case 0: ret["result"]=0; set_session_length(usr,val); break; default: ret["result"]=1; } fail: return ret; } Json::Value get_option(Json::Value o) { Json::Value ret; std::string token=o["token"].asString(); std::string usr=authenticate(token); int opt=o["option"].asInt(); if(!usr.length()){ret["result"]=1;goto fail;} switch(opt) { case 0: ret["result"]=0; ret["value"]=get_session_length(usr); break; default: ret["result"]=1; } fail: return ret; } Json::Value get_bookmarks(Json::Value o) { MYSQL_RES* sqlr=NULL; MYSQL_ROW row; char q[256]; Json::Value ret; std::string token=o["token"].asString(); std::string usr=authenticate(token); if(!usr.length()){ret["result"]=1;goto fail;} snprintf(q,256,"select bookmarks from navigator_user where username='%s'",usr.c_str()); mysql_query(sql,q); sqlr=mysql_store_result(sql); if(mysql_num_rows(sqlr)!=1){mysql_free_result(sqlr);sqlr=NULL;ret["result"]=4;goto fail;} row=mysql_fetch_row(sqlr); ret["result"]=0; ret["bookmarks"]=std::string(row[0]); mysql_free_result(sqlr);sqlr=NULL; fail: if(sqlr){mysql_free_result(sqlr);sqlr=NULL;} return ret; } Json::Value set_bookmarks(Json::Value o) { char *q=(char*)malloc(65537); Json::Value ret; std::string token=o["token"].asString(); std::string usr=authenticate(token); if(!usr.length()){ret["result"]=1;goto fail;} snprintf(q,65536,"update navigator_user set bookmarks='%s' where username='%s'",o["bookmarks"].asString().c_str(),usr.c_str()); mysql_query(sql,q); mysql_commit(sql); ret["result"]=0; fail: free(q); return ret; } Json::Value list_sessions(Json::Value o) { MYSQL_RES* sqlr=NULL; MYSQL_ROW row; char q[256]; Json::Value ret,ss; std::string token=o["token"].asString(); std::string usr=authenticate(token); if(!usr.length()){ret["result"]=1;goto fail;} snprintf(q,256,"select sessionname,date from navigator_session where username='%s'",usr.c_str()); mysql_query(sql,q); sqlr=mysql_store_result(sql); for(int i=0;row=mysql_fetch_row(sqlr);++i) { Json::Value c; c["sessionname"]=std::string(row[0]); c["date"]=atoi(row[1]); ss[i]=c; } mysql_free_result(sqlr);sqlr=NULL; ret["result"]=0;ret["sessions"]=ss; fail: return ret; } Json::Value remove_session(Json::Value o) { char q[256]; Json::Value ret; std::string token=o["token"].asString(); std::string usr=authenticate(token); std::string sess=o["session"].asString(); if(!usr.length()){ret["result"]=1;goto fail;} snprintf(q,256,"delete from navigator_session where username='%s' and sessionname='%s'",usr.c_str(),sess.c_str()); mysql_query(sql,q); mysql_commit(sql); ret["result"]=0; fail: return ret; } int main() { if(!getenv("CONTENT_LENGTH"))return -1; int len=atoi(getenv("CONTENT_LENGTH")); char *buf;buf=(char*)malloc(len+1); fread(buf,1,len,stdin);buf[len]=0; std::string sbuf(buf,len); free(buf); std::stringstream ss(sbuf); Json::Value o,r;ss>>o; sql=mysql_init(NULL); if(!sql)return -1; if(!mysql_real_connect(sql,"localhost","chrisoft",NULL,"chrisoft",0,"/var/run/mysqld/mysqld.sock",0)) return -1; switch(o.get("op",-1).asInt()) { case 0://login r=do_login(o); break; case 1://get bookmarks r=get_bookmarks(o); break; case 2://set bookmarks r=set_bookmarks(o); break; case 3://list sessions r=list_sessions(o); break; case 4://remove session r=remove_session(o); break; case 5://set option r=set_option(o); break; case 6://get option r=get_option(o); break; } printf("Status: 200 OK\r\n"); printf("Content-type: application/json; charset=utf-8\r\n\r\n"); std::ostringstream oss; oss<