- Update to Xerces-2.1 support
[shibboleth/sp.git] / shib-target / shib-shire.cpp
1 /*
2  * shib-shire.cpp -- Shibboleth SHIRE functions
3  *
4  * Created by:  Derek Atkins <derek@ihtfp.com>
5  *
6  * $Id$
7  */
8
9 #include <unistd.h>
10
11 #include "shib-target.h"
12
13 #include <log4cpp/Category.hh>
14
15 #include <stdexcept>
16
17 using namespace std;
18 using namespace saml;
19 using namespace shibboleth;
20 using namespace shibtarget;
21
22 class shibtarget::SHIREPriv
23 {
24 public:
25   SHIREPriv(RPCHandle *rpc, SHIREConfig cfg, string shire_url);
26   ~SHIREPriv();
27
28   RPCHandle *   m_rpc;
29   SHIREConfig   m_config;
30   string        m_url;
31
32   log4cpp::Category* log;
33 };
34
35 SHIREPriv::SHIREPriv(RPCHandle *rpc, SHIREConfig cfg, string shire_url)
36 {
37   string ctx = "shibtarget.SHIRE";
38   log = &(log4cpp::Category::getInstance(ctx));
39   m_rpc = rpc;
40   m_config = cfg;
41   m_url = shire_url;
42 }
43
44 SHIREPriv::~SHIREPriv() {}
45
46
47 SHIRE::SHIRE(RPCHandle *rpc, SHIREConfig cfg, string shire_url)
48 {
49   m_priv = new SHIREPriv(rpc, cfg, shire_url);
50   m_priv->log->info ("New SHIRE handle created");
51 }
52
53 SHIRE::~SHIRE()
54 {
55   delete m_priv;
56 }
57
58
59 RPCError* SHIRE::sessionIsValid(const char* cookie, const char* ip)
60 {
61   saml::NDC ndc("sessionIsValid");
62
63   if (!cookie || *cookie == '\0') {
64     m_priv->log->error ("No cookie");
65     return new RPCError(-1, "No such cookie");
66   }
67
68   if (!ip) {
69     m_priv->log->error ("No IP");
70     return new RPCError(-1, "Invalid IP Address");
71   }
72
73   m_priv->log->info ("is session valid: %s", ip);
74   m_priv->log->debug ("session cookie: %s", cookie);
75
76   shibrpc_session_is_valid_args_1 arg;
77
78   arg.cookie.cookie = (char*)cookie;
79   arg.cookie.client_addr = (char *)ip;
80   arg.lifetime = m_priv->m_config.lifetime;
81   arg.timeout = m_priv->m_config.timeout;
82   arg.checkIPAddress = m_priv->m_config.checkIPAddress;
83
84   shibrpc_session_is_valid_ret_1 ret;
85   memset (&ret, 0, sizeof(ret));
86
87   // Loop on the RPC in case we lost contact the first time through
88   int retry = 1;
89   CLIENT *clnt;
90   do {
91     clnt = m_priv->m_rpc->connect();
92     if (shibrpc_session_is_valid_1 (&arg, &ret, clnt) != RPC_SUCCESS) {
93       m_priv->m_rpc->disconnect();
94       if (retry)
95         retry--;
96       else {
97         m_priv->log->error ("RPC Failure");
98         return new RPCError(-1, "RPC Failure");
99       }
100     } else
101       retry = -1;
102   } while (retry >= 0);
103
104   m_priv->log->debug ("RPC completed with status %d", ret.status);
105
106   RPCError* retval;
107   if (ret.status)
108     retval = new RPCError(ret.status, ret.error_msg);
109   else
110     retval = new RPCError();
111
112   clnt_freeres (clnt, (xdrproc_t)xdr_shibrpc_session_is_valid_ret_1, (caddr_t)&ret);
113
114   m_priv->log->debug ("returning");
115   return retval;
116 }
117
118 RPCError* SHIRE::sessionCreate(const char* post, const char* ip, string& cookie)
119 {
120   saml::NDC ndc("sessionCreate");
121
122   if (!post || *post == '\0') {
123     m_priv->log->error ("No POST");
124     return new RPCError(-1,  "Invalid POST string");
125   }
126
127   if (!ip) {
128     m_priv->log->error ("No IP");
129     return new RPCError(-1, "Invalid IP Address");
130   }
131
132   m_priv->log->info ("create session for user at %s", ip);
133
134   shibrpc_new_session_args_1 arg;
135   arg.shire_location = (char*) (m_priv->m_url.c_str());
136   arg.saml_post = (char*)post;
137   arg.client_addr = (char*)ip;
138   arg.checkIPAddress = m_priv->m_config.checkIPAddress;
139
140   shibrpc_new_session_ret_1 ret;
141   memset (&ret, 0, sizeof(ret));
142
143   // Loop on the RPC in case we lost contact the first time through
144   int retry = 1;
145   CLIENT* clnt;
146   do {
147     clnt = m_priv->m_rpc->connect();
148     if (shibrpc_new_session_1 (&arg, &ret, clnt) != RPC_SUCCESS) {
149       m_priv->m_rpc->disconnect();
150       if (retry)
151         retry--;
152       else {
153         m_priv->log->error ("RPC Failure");
154         return new RPCError(-1, "RPC Failure");
155       }
156     } else
157       retry = -1;
158   } while (retry >= 0);
159
160   m_priv->log->debug ("RPC completed with status %d", ret.status);
161
162   RPCError* retval;
163   if (ret.status)
164     retval = new RPCError(ret.status, ret.error_msg);
165   else {
166     m_priv->log->debug ("new cookie: %s", ret.cookie);
167     cookie = ret.cookie;
168     retval = new RPCError();
169   }
170
171   clnt_freeres (clnt, (xdrproc_t)xdr_shibrpc_new_session_ret_1, (caddr_t)&ret);
172
173   m_priv->log->debug ("returning");
174   return retval;
175 }