Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024
00025 #if !defined(NDEBUG) && defined(HAVE_ASSERT_H)
00026 # include <assert.h>
00027 #endif
00028
00029 #include "../../intl.h"
00030
00031 #include "pwgen.h"
00032
00033 using namespace YAPET::PWGEN;
00034
00041 void
00042 PWGen::sanitize_password() throw(std::logic_error) {
00043 if ( (static_cast<size_t>(cp->numPoolsAllocated()) > password_len) ||
00044 (cp->numPoolsNotRead() == 0)) return;
00045
00046 for (register size_t pwit_outer = 0; pwit_outer < password_len; pwit_outer++) {
00047 assert(password[pwit_outer] != '\0');
00048
00049 char c_outer = password[pwit_outer];
00050 SUBPOOLS c_outer_pool = cp->fromPool(c_outer);
00051
00052 for (register size_t pwit_inner = 0; pwit_inner < password_len; pwit_inner++) {
00053 if (cp->numPoolsNotRead() == 0) return;
00054 assert(password[pwit_inner] != '\0');
00055 char c_inner = password[pwit_inner];
00056 if (pwit_inner != pwit_outer &&
00057 c_outer_pool == cp->fromPool(c_inner)) {
00058 const_cast<char*>(password)[pwit_outer] = getCharFromUnusedPools();
00059 break;
00060 }
00061 }
00062 if (cp->numPoolsNotRead() == 0) return;
00063 }
00064 }
00065
00066 char
00067 PWGen::getCharFromUnusedPools() throw(std::logic_error) {
00068 char suggestion = 0;
00069 if (cp->numPoolsNotRead() > 0) {
00070
00071 int not_read = cp->getAllocatedPools() &
00072 ~ cp->getPoolsWithRead();
00073
00074
00075
00076
00077
00078 for (int pool_it=YAPET::PWGEN::LETTERS;
00079 pool_it <= YAPET::PWGEN::OTHER;
00080 pool_it = pool_it << 1) {
00081 if ( not_read & pool_it) {
00082 size_t pool_start;
00083
00084
00085
00086
00087
00088
00089
00090
00091 size_t random_val = (*rng)(cp->getPoolPos((YAPET::PWGEN::SUBPOOLS)pool_it,
00092 &pool_start)-1);
00093 suggestion = (*cp)[pool_start + random_val];
00094 return suggestion;
00095 }
00096 }
00097 } else {
00098 assert(0);
00099 throw std::logic_error(_("Cannot get character from unused pool because no unused pools are available"));
00100 }
00101 assert(0);
00102 return -1;
00103 }
00104
00105 void
00106 PWGen::init (int p, RNGENGINE rnge) throw (std::runtime_error) {
00107 cp = new CharacterPool (p);
00108 rng = new RNG(rnge);
00109 }
00110
00111 PWGen::PWGen (SUBPOOLS p, RNGENGINE rnge) throw (std::runtime_error) : cp (NULL), rng(NULL), password (NULL), password_len (0) {
00112 init (p, rnge);
00113 assert (cp != NULL);
00114 assert (rng != NULL);
00115 assert (password == NULL);
00116 }
00117
00118 PWGen::PWGen (int p, RNGENGINE rnge) throw (std::runtime_error) : cp (NULL), rng(NULL), password (NULL), password_len (0) {
00119 init (p, rnge);
00120 assert (cp != NULL);
00121 assert (rng != NULL);
00122 assert (password == NULL);
00123 }
00124
00125
00126
00127
00128 PWGen::PWGen (const PWGen& pw) throw() : cp (NULL), rng(NULL), password (NULL), password_len (0) {
00129 assert (pw.cp != NULL);
00130 assert (pw.rng != NULL);
00131 cp = new CharacterPool (* (pw.cp) );
00132 rng = new RNG(*(pw.rng));
00133 assert (cp != NULL);
00134 assert (rng != NULL);
00135
00136 if (pw.password != NULL) {
00137 assert (pw.password_len > 0);
00138 password = new char[pw.password_len + 1];
00139 memcpy ( (void*) password, pw.password, pw.password_len);
00140
00141 const_cast<char*>(password) [pw.password_len + 1] = '\0';
00142 password_len = pw.password_len;
00143 }
00144 }
00145
00146 PWGen::~PWGen() throw() {
00147 assert (cp != NULL);
00148 assert (rng != NULL);
00149 delete cp;
00150 delete rng;
00151
00152 if (password_len != 0) assert (password != NULL);
00153
00154 if (password != NULL) {
00155 assert (password_len > 0);
00156 memset ( (void*) password, 0, password_len);
00157 delete[] password;
00158 }
00159 }
00160
00161 void
00162 PWGen::setNewPool (int p) throw (std::runtime_error) {
00163 assert (cp != NULL);
00164 delete cp;
00165 cp = new CharacterPool (p);
00166 assert (cp != NULL);
00167 }
00168
00169 void
00170 PWGen::setNewRNG (RNGENGINE rnge) throw (std::runtime_error) {
00171 assert (rng != NULL);
00172 delete rng;
00173 rng = new RNG (rnge);
00174 assert (rng != NULL);
00175 }
00176
00177 void
00178 PWGen::generatePassword (size_t len) throw (std::logic_error) {
00179 if (len == 0) return;
00180
00181 if (password != NULL) {
00182 assert (password_len > 0);
00183 memset ( (void*) password, 0, password_len);
00184 delete[] password;
00185 }
00186
00187 password_len = len;
00188 password = new char[password_len + 1];
00189 cp->resetPoolsWithRead();
00190
00191 for (size_t pw_it = 0; pw_it < password_len; pw_it++) {
00192 RESTART:
00193 char suggestion = (*cp) [(*rng) (cp->getPoolLength() ) ];
00194 if (static_cast<size_t>(cp->getPoolLength()) >= password_len) {
00195
00196 for (size_t pos = 0; pos < pw_it; pos++) {
00197 if (suggestion == password[pos]) {
00198
00199
00200
00201 if (static_cast<size_t>(cp->numPoolsAllocated()) >= password_len &&
00202 cp->numPoolsNotRead() > 0) {
00203
00204 suggestion = getCharFromUnusedPools();
00205 break;
00206 }
00207 }
00208 }
00209 }
00210
00211
00212 if ( (pw_it == 0) || (pw_it == password_len - 1) ) {
00213 #if defined(HAVE_ISBLANK) || defined(HAVE_ISSPACE)
00214 # ifdef HAVE_ISBLANK
00215
00216 if (isblank (suggestion) != 0)
00217 goto RESTART;
00218
00219 # else
00220
00221 if (isspace (suggestion) != 0)
00222 goto RESTART;
00223
00224 # endif // HAVE_ISBLANK
00225 #else // defined(HAVE_ISBLANK) || defined(HAVE_ISSPACE)
00226
00227 if (suggestion == ' ')
00228 goto RESTART;
00229
00230 #endif // defined(HAVE_ISBLANK) || defined(HAVE_ISSPACE)
00231 }
00232
00233 const_cast<char*>(password) [pw_it] = suggestion;
00234 }
00235
00236
00237 const_cast<char*>(password) [password_len] = '\0';
00238
00239 sanitize_password();
00240 #ifndef NDEBUG
00241
00242 if (static_cast<size_t>(cp->numPoolsAllocated()) <= password_len) {
00243 assert(cp->numPoolsNotRead() == 0);
00244 }
00245 #endif
00246 }
00247
00248 const char*
00249 PWGen::getPassword() const throw() {
00250 assert ( ( (password != NULL) && (password_len > 0) ) ||
00251 ( (password == NULL) && (password_len == 0) ) );
00252
00253 if (password == NULL) return NULL;
00254
00255 assert (password[password_len] == '\0');
00256 return password;
00257 }
00258
00259 const PWGen&
00260 PWGen::operator= (const PWGen & pw) throw() {
00261 assert (cp != NULL);
00262 assert (rng != NULL);
00263
00264 if (&pw == this) return *this;
00265
00266 delete cp;
00267 cp = new CharacterPool (* (pw.cp) );
00268 delete rng;
00269 rng = new RNG (* (pw.rng) );
00270
00271 if (password != NULL) {
00272 assert (password_len > 0);
00273 memset ( (void*) password, 0, password_len);
00274 delete[] password;
00275 }
00276
00277 if (pw.password != NULL) {
00278 assert (pw.password_len > 0);
00279 password = new char[pw.password_len];
00280 memcpy ( (void*) password, pw.password, pw.password_len);
00281
00282 const_cast<char*>(password) [pw.password_len + 1] = '\0';
00283 password_len = pw.password_len;
00284 }
00285
00286 return *this;
00287 }