/* Copyright (c) 2008 Autistici/Inventati * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* $Id$ */ #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "apr_strings.h" #include "http_protocol.h" #include "http_main.h" #include "ap_config.h" #include "mod_sso.h" namespace modsso { using std::string; void debug(const string& s) { #ifdef DEBUG fprintf(stderr, "%s\n", s.c_str()); #endif } // ugly implementation of url decoding string url_decode(const string& str) { string out; char state = 'N'; char buf[3], obuf[2]; for (string::const_iterator i = str.begin(); i != str.end(); i++) { switch(state) { case 'N': if (*i == '%') state = 1; else out += *i; break; case 1: { char c = tolower(*i); buf[0] = *i; if ((c >= 'a' && c <= 'f') || (c >= '0' && c <= '9')) { state = 2; } else { out += "%"; out += *i; state = 'N'; } break; } case 2: { char c = tolower(*i); if ((c >= 'a' && c <= 'f') || (c >= '0' && c <= '9')) { buf[1] = *i; buf[2] = 0; obuf[0] = strtol(buf, 0, 16); obuf[1] = 0; if (obuf[0]) out += obuf; } else { out += "%"; out += buf[0]; out += *i; } state = 'N'; break; } } } if (state != 'N') { out += buf[0]; if (state > 1) out += buf[1]; } return out; } // ugly implementation of url encoding string url_encode(const string& str) { static const char *hex = "0123456789ABCDEF"; string out; for (string::const_iterator i = str.begin(); i != str.end(); i++) { unsigned char c = *i; if (!isalnum(c) && (c != '.') && (c != '-') && (c != '_')) { out += "%"; out += hex[(c & 0xf0) >> 4]; out += hex[c & 0x0f]; } else { out += c; } } return out; } params_t parse_query_string(const string& str) { params_t p; if(str.size() == 0) return p; vector pairs = explode(str, "&"); for (unsigned int i=0; i < pairs.size(); i++) { string::size_type loc = pairs[i].find( "=", 0 ); // if loc found and loc isn't last char in string if (loc != string::npos && loc != str.size()-1) { string key = url_decode(pairs[i].substr(0, loc)); string value = url_decode(pairs[i].substr(loc+1)); p[key] = value; } } return p; } void make_cookie_value(string& cookie_value, const string& name, const string& session_id, const string& path, int cookie_lifespan) { if (cookie_lifespan == 0) { cookie_value = name + "=" + session_id + "; path=" + path + "; secure;"; } else { time_t t; t = time(NULL) + cookie_lifespan; struct tm *tmp; tmp = gmtime(&t); char expires[200]; strftime(expires, sizeof(expires), "%a, %d-%b-%Y %H:%M:%S GMT", tmp); cookie_value = name + "=" + session_id + "; expires=" + string(expires) + "; Path=" + path + "; secure; httpOnly;"; } } void set_cookie(request_rec *r, const std::string& cookie_name, const std::string& value, const std::string& path) { std::string cookie_value; make_cookie_value(cookie_value, cookie_name, value, path, 0); apr_table_setn(r->err_headers_out, "Set-Cookie", apr_pstrdup(r->pool, cookie_value.c_str())); } void del_cookie(request_rec *r, const std::string& cookie_name) { std::string cookie_value; cookie_value = cookie_name + "=; expires=Mar, 01-01-1971 00:00:00 GMT"; apr_table_setn(r->err_headers_out, "Set-Cookie", apr_pstrdup(r->pool, cookie_value.c_str())); } vector explode(string s, string e) { vector ret; int iPos = s.find(e, 0); int iPit = e.length(); while (iPos>-1) { if (iPos!=0) ret.push_back(s.substr(0,iPos)); s.erase(0,iPos+iPit); iPos = s.find(e, 0); } if (s!="") ret.push_back(s); return ret; } } // namespace modsso