00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "autoconfig.h"
00034 #endif
00035
00036 #include <sys/time.h>
00037 #include "pages.h"
00038 #include "tools.h"
00039 #include "session_manager.h"
00040
00041 using namespace zmm;
00042 using namespace mxml;
00043
00044 #define LOGIN_TIMEOUT 10 // in seconds
00045
00046 static long get_time()
00047 {
00048 struct timeval tv;
00049 gettimeofday(&tv, NULL);
00050 return tv.tv_sec;
00051 }
00052
00053 static String generate_token()
00054 {
00055 long expiration = get_time() + LOGIN_TIMEOUT;
00056 String salt = generate_random_id();
00057 return String::from(expiration) + '_' + salt;
00058 }
00059
00060 static bool check_token(String token, String password, String encPassword)
00061 {
00062 Ref<Array<StringBase> > parts = split_string(token, '_');
00063 if (parts->size() != 2)
00064 return false;
00065 long expiration = String(parts->get(0)).toLong();
00066 if (expiration < get_time())
00067 return false;
00068 String checksum = hex_string_md5(token + password);
00069 return (checksum == encPassword);
00070 }
00071
00072 web::auth::auth() : WebRequestHandler()
00073 {
00074 timeout = 60 * ConfigManager::getInstance()->getIntOption(CFG_SERVER_UI_SESSION_TIMEOUT);
00075 }
00076 void web::auth::process()
00077 {
00078 String action = param(_("action"));
00079 Ref<SessionManager> sessionManager = SessionManager::getInstance();
00080
00081 if (! string_ok(action))
00082 {
00083 root->appendTextChild(_("error"), _("req_type auth: no action given"));
00084 return;
00085 }
00086
00087 if (action == "get_config")
00088 {
00089 Ref<ConfigManager> cm = ConfigManager::getInstance();
00090 Ref<Element> config (new Element(_("config")));
00091 root->appendElementChild(config);
00092 config->setAttribute(_("accounts"), accountsEnabled() ? _("1") : _("0"), mxml_bool_type);
00093 config->setAttribute(_("show-tooltips"),
00094 (cm->getBoolOption(
00095 CFG_SERVER_UI_SHOW_TOOLTIPS) ? _("1") : _("0")), mxml_bool_type);
00096 config->setAttribute(_("poll-when-idle"),
00097 (cm->getBoolOption(
00098 CFG_SERVER_UI_POLL_WHEN_IDLE) ? _("1") : _("0")), mxml_bool_type);
00099 config->setAttribute(_("poll-interval"),
00100 String::from(cm->getIntOption(CFG_SERVER_UI_POLL_INTERVAL)), mxml_int_type);
00102 Ref<Element> ipp (new Element(_("items-per-page")));
00103 ipp->setArrayName(_("option"));
00104 ipp->setAttribute(_("default"),
00105 String::from(cm->getIntOption(CFG_SERVER_UI_DEFAULT_ITEMS_PER_PAGE)), mxml_int_type);
00106
00107 Ref<Array<StringBase> > menu_opts =
00108 cm->getStringArrayOption(CFG_SERVER_UI_ITEMS_PER_PAGE_DROPDOWN);
00109
00110 for (int i = 0; i < menu_opts->size(); i++)
00111 {
00112 ipp->appendTextChild(_("option"), menu_opts->get(i), mxml_int_type);
00113 }
00114
00115 config->appendElementChild(ipp);
00116 #ifdef HAVE_INOTIFY
00117 if (cm->getBoolOption(CFG_IMPORT_AUTOSCAN_USE_INOTIFY))
00118 config->setAttribute(_("have-inotify"), _("1"), mxml_bool_type);
00119 else
00120 config->setAttribute(_("have-inotify"), _("0"), mxml_bool_type);
00121 #else
00122 config->setAttribute(_("have-inotify"), _("0"), mxml_bool_type);
00123 #endif
00124
00125
00126 Ref<Element> actions (new Element(_("actions")));
00127 actions->setArrayName(_("action"));
00128 #ifdef YOUTUBE
00129 if (cm->getBoolOption(CFG_ONLINE_CONTENT_YOUTUBE_ENABLED))
00130 {
00131 actions->appendTextChild(_("action"), _(UI_ACTION_REFRESH_YOUTUBE));
00132 }
00133 #endif
00134
00135
00136
00137 config->appendElementChild(actions);
00138 }
00139 else if (action == "get_sid")
00140 {
00141 log_debug("checking/getting sid...\n");
00142 Ref<Session> session = nil;
00143 String sid = param(_("sid"));
00144
00145 if (sid == nil || (session = sessionManager->getSession(sid)) == nil)
00146 {
00147 session = sessionManager->createSession(timeout);
00148 root->setAttribute(_("sid_was_valid"), _("0"), mxml_bool_type);
00149 }
00150 else
00151 {
00152 session->clearUpdateIDs();
00153 root->setAttribute(_("sid_was_valid"), _("1"), mxml_bool_type);
00154 }
00155 root->setAttribute(_("sid"), session->getID());
00156
00157 if (! session->isLoggedIn() && ! accountsEnabled())
00158 {
00159 session->logIn();
00160
00161 }
00162 root->setAttribute(_("logged_in"), session->isLoggedIn() ? _("1") : _("0"), mxml_bool_type);
00163 }
00164 else if (action == "logout")
00165 {
00166 check_request();
00167 String sid = param(_("sid"));
00168 Ref<Session> session = SessionManager::getInstance()->getSession(sid);
00169 if (session == nil)
00170 throw _Exception(_("illegal session id"));
00171 sessionManager->removeSession(sid);
00172 }
00173 else if (action == "get_token")
00174 {
00175 check_request(false);
00176
00177
00178 String token = generate_token();
00179 session->put(_("token"), token);
00180 root->appendTextChild(_("token"), token);
00181 }
00182 else if (action == "login")
00183 {
00184 check_request(false);
00185
00186
00187 String username = param(_("username"));
00188 String encPassword = param(_("password"));
00189 String sid = param(_("sid"));
00190
00191 if (! string_ok(username) || ! string_ok(encPassword))
00192 throw LoginException(_("Missing username or password"));
00193
00194 Ref<Session> session = sessionManager->getSession(sid);
00195 if (session == nil)
00196 throw _Exception(_("illegal session id"));
00197
00198 String correctPassword = sessionManager->getUserPassword(username);
00199
00200 if (! string_ok(correctPassword) || ! check_token(session->get(_("token")), correctPassword, encPassword))
00201 throw LoginException(_("Invalid username or password"));
00202
00203 session->logIn();
00204 }
00205 else
00206 throw _Exception(_("illegal action given to req_type auth"));
00207 }