shireError.html: update the error template to show origin contact
[shibboleth/sp.git] / shib-target / shib-mlp.cpp
1 /*
2  * shib-mlp.cpp -- The ShibTarget Markup Language processor
3  *
4  * Created by:  Derek Atkins <derek@ihtfp.com>
5  *
6  * $Id$
7  */
8
9 #include "shib-target.h"
10 #include <sstream>
11 #include <ctype.h>
12 #include <xercesc/util/XercesDefs.hpp>
13
14 #include <log4cpp/Category.hh>
15
16 using namespace std;
17 using namespace shibtarget;
18 using namespace saml;
19
20 class shibtarget::ShibMLPPriv {
21 public:
22   ShibMLPPriv();
23   ~ShibMLPPriv() {}
24   log4cpp::Category *log;
25 };  
26
27 ShibMLPPriv::ShibMLPPriv()
28 {
29   string ctx = "shibtarget.ShibMLP";
30   log = &(log4cpp::Category::getInstance(ctx));
31 }
32
33
34 static void trimspace (string& s)
35 {
36   int end = s.size() - 1, start = 0;
37
38   // Trim stuff on right.
39   while (end > 0 && !isgraph(s[end])) end--;
40
41   // Trim stuff on left.
42   while (start < end && !isgraph(s[start])) start++;
43
44   // Modify the string.
45   s = s.substr(start, end - start + 1);
46 }
47
48 ShibMLP::ShibMLP ()
49 {
50   m_priv = new ShibMLPPriv ();
51
52   // Create a timestamp
53   time_t now = time(NULL);
54   string now_s = ctime(&now);
55   insert ("now", now_s);
56 }
57
58 ShibMLP::~ShibMLP ()
59 {
60   delete m_priv;
61 }
62
63 string ShibMLP::run (const string& is) const
64 {
65   string res;
66
67   const char* line = is.c_str();
68   const char* lastpos = line;
69   const char* thispos;
70
71   m_priv->log->info("Processing string");
72
73   //
74   // Search for SHIBMLP tags.  These are of the form:
75   //    <shibmlp key />
76   // Note that there MUST be white-space after "<shibmlp" but
77   // there does not need to be white space between the key and
78   // the close-tag.
79   //
80   while ((thispos = strstr(lastpos, "<")) != NULL) {
81     // save the string up to this token
82     res += is.substr(lastpos-line, thispos-lastpos);
83
84     // Make sure this token matches our token.
85     if (strnicmp (thispos, "<shibmlp ", 9)) {
86       res += "<";
87       lastpos = thispos + 1;
88       continue;
89     }
90
91     // Save this position off.
92     lastpos = thispos + 9;      // strlen("<shibmlp ")
93
94     // search for the end-tag
95     if ((thispos = strstr(lastpos, "/>")) != NULL) {
96       string key = is.substr(lastpos-line, thispos-lastpos);
97       trimspace(key);
98
99       m_priv->log->debug("found key: \"%s\"", key.c_str());
100
101       map<string,string>::const_iterator i=m_map.find(key);
102       if (i == m_map.end()) {
103         static string s1 = "<!-- Unknown SHIBMLP key: ";
104         static string s2 = "/>";
105         res += s1 + key + s2;
106         m_priv->log->debug("key unknown");
107       } else {
108         res += i->second;
109         m_priv->log->debug("key maps to \"%s\"", i->second.c_str());
110       }
111
112       lastpos = thispos + 2;    // strlen("/>")
113     }
114   }
115   res += is.substr(lastpos-line);
116
117   return res;
118 }
119
120 string ShibMLP::run (istream& is) const
121 {
122   static string eol = "\r\n";
123   string str, line;
124
125   m_priv->log->info("processing stream");
126
127   while (getline(is, line))
128     str += line + eol;
129
130   return run(str);
131 }
132
133 void ShibMLP::insert (RPCError& e)
134 {
135   insert ("errorType", e.getType());
136   insert ("errorText", e.getText());
137   insert ("errorDesc", e.getDesc());
138   insert ("originErrorURL", e.getOriginErrorURL());
139   insert ("originContactName", e.getOriginContactName());
140   insert ("originContactEmail", e.getOriginContactEmail());
141 }
142
143 void ShibMLP::insert (const std::string& key, const std::string& value)
144 {
145   saml::NDC ndc("insert");
146   m_priv->log->debug("inserting %s -> %s", key.c_str(), value.c_str());
147   m_map[key] = value;
148 }