9d8ff86f302a1d167fe928465b7484c9c6ec2167
[gssweb.git] / json_gssapi / src / cache / GSSNameCache.cpp
1 /*
2  * Copyright (c) 2014 <copyright holder> <email>
3  *
4  * For license details, see the LICENSE file in the root of this project.
5  *
6  */
7
8 // #include <glib.h>
9 #include <stdexcept>
10 #include <openssl/err.h>
11 #include <openssl/rand.h>
12
13 #include "GSSNameCache.h"
14 #include "utils/base64.h"
15
16 #define KEYLEN 128
17
18 GSSNameCache* GSSNameCache::_instance = 0;
19
20 GSSNameCache::GSSNameCache()
21 {
22
23 }
24
25 GSSNameCache::GSSNameCache ( const GSSNameCache& other )
26 {
27   names = other.names;
28 }
29
30 GSSNameCache::~GSSNameCache()
31 {
32
33 }
34
35 GSSNameCache& GSSNameCache::operator= ( const GSSNameCache& other )
36 {
37   names = other.names;
38   
39   return *this;
40 }
41
42
43 std::string GSSNameCache::store ( GSSName& data, std::string inKey )
44 {
45   /* Variables      */
46   std::string key;
47   
48   /* Error checking */
49   /* Setup          */
50   /* Main           */
51   // Generate a key
52   if ( inKey.length() > 0 )
53   {
54     key = inKey;
55   }
56   else if ( !generateKey(key) )
57   {
58     // Key generation failed.  Eeek!
59     throw std::runtime_error("Could not generate random data for an ID");
60   }
61   
62   // Store the key/value pair in the map
63   // Store the key in the context for convenience
64 //   std::cout << "\n==> In GSSNameCache::store, about to store data in the names hash.\n";
65   names[key] = &data;
66   
67   /* Cleanup        */
68   /* Return         */
69   // Return the key for future reference
70   return(key);
71 }
72
73 /*************************************
74  * Generate random bytes, and base64 *
75  * encode them to be JSONable keys   *
76  *************************************/
77 bool GSSNameCache::generateKey(std::string &key)
78 {
79   /* Variables      */
80   int  osslReturn = 0;
81   unsigned char theKey[KEYLEN];
82   bool existingErrors = false;
83   
84   /* Error checking */
85   // See if there are any queued OpenSSL errors already.
86   existingErrors = ( 0 == ERR_peek_error() ); 
87   
88   /* Setup          */
89   /* Main           */
90   // Generate random byte string
91   osslReturn = RAND_pseudo_bytes(theKey, KEYLEN);
92   
93   // Discard the error message if there weren't any OpenSSL errors to begin with.
94   if (osslReturn == 1 && !existingErrors)
95   {
96     while (0 != ERR_get_error() );
97     return(false);
98   }
99
100   // Encode the binary string
101   key = (char *)theKey;
102   key = base64_encode(key);
103   
104   /* Cleanup        */
105   /* Return         */
106   return(true);
107 }
108
109 GSSName& GSSNameCache::retrieve ( std::string key )
110 {
111   /* Variables      */
112   //GSSName data;
113   
114   /* Error checking */
115   /* Setup          */
116   /* Main           */
117   // Maybe do something about data entries that are expired?
118   
119   /* Cleanup        */
120   /* Return         */
121   return *(names[key]);
122 }
123
124 GSSNameCache* GSSNameCache::instance()
125 {
126     if (_instance == 0)
127       _instance = new GSSNameCache;
128     
129     return _instance;
130 }
131
132
133
134   /* Variables      */
135   /* Error checking */
136   /* Setup          */
137   /* Main           */
138   /* Cleanup        */
139   /* Return         */