ngx_int_t ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted) { char *value; size_t len; struct crypt_data cd; cd.initialized = 0; #ifdef __GLIBC__ /* work around the glibc bug */ cd.current_salt[0] = ~salt[0]; #endif value = crypt_r((char *) key, (char *) salt, &cd); if (value) { len = ngx_strlen(value) + 1; *encrypted = ngx_pnalloc(pool, len); if (*encrypted == NULL) { return NGX_ERROR; } ngx_memcpy(*encrypted, value, len); return NGX_OK; } ngx_log_error(NGX_LOG_CRIT, pool->log, ngx_errno, "crypt_r() failed"); return NGX_ERROR; }
ngx_int_t ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted) { char *value; size_t len; struct crypt_data cd; cd.initialized = 0; value = crypt_r((char *) key, (char *) salt, &cd); if (value) { len = ngx_strlen(value) + 1; *encrypted = ngx_pnalloc(pool, len); if (*encrypted == NULL) { return NGX_ERROR; } ngx_memcpy(*encrypted, value, len); return NGX_OK; } ngx_log_error(NGX_LOG_CRIT, pool->log, ngx_errno, "crypt_r() failed"); return NGX_ERROR; }
static bool test_one_setting (const char *label, const char *setting, struct crypt_data *cd, bool expected_to_succeed) { bool ok = true; const char *retval; int cdsize = (int) sizeof (struct crypt_data); #ifdef VERBOSE printf ("%s: testing %s (expect: %s)\n", label, setting, expected_to_succeed ? "succeed" : "fail"); #endif retval = crypt (phrase, setting); if (!check_crypt (label, "crypt", retval, setting, expected_to_succeed)) ok = false; retval = crypt_r (phrase, setting, cd); if (!check_crypt (label, "crypt_r", retval, setting, expected_to_succeed)) ok = false; retval = crypt_rn (phrase, setting, cd, cdsize); if (!check_crypt_rn (label, "crypt_rn", retval, cd->output, setting, expected_to_succeed)) ok = false; retval = crypt_ra (phrase, setting, (void **)&cd, &cdsize); if (!check_crypt_rn (label, "crypt_ra", retval, cd->output, setting, expected_to_succeed)) ok = false; return ok; }
/** * Verify a username and password * * @param username Username to verify * @param password Password to verify * @return Non-zero if the username/password combination is valid */ int admin_verify(char *username, char *password) { char *pw; initialise(); if (users == NULL) { if (strcmp(username, "admin") == 0 && strcmp(password, "mariadb") == 0) { return 1; } } else { if ((pw = users_fetch(users, username)) == NULL) { return 0; } struct crypt_data cdata; cdata.initialized = 0; if (strcmp(pw, crypt_r(password, ADMIN_SALT, &cdata)) == 0) { return 1; } } return 0; }
int crack(char *initPa, char **pCrackL, char **saltL, int qtPCRACK, int intervalo){ int pass[tP]; char c_pass[tP]; int j,ok=1,k,h,q=0; char *result; unsigned long int qtPGen = 0; memcpy(c_pass,initPa,sizeof(char)*tP); if(c_pass==NULL) exit(0); for(j=0;j<tP;j++){ for(k=0;k<T_D;k++){ if(c_pass[j]==d[k]){ pass[j] = k; break; } } } j=0; struct crypt_data data; data.initialized = 0; while(j!=-1){ if(q==qtPCRACK)return 1; for(j = pass[tP-1] ; j < T_D && qtPGen<intervalo ; j++){ qtPGen++; pass[tP-1] = j; c_pass[tP-1] = d[j]; //printf("%s\n",c_pass); for(h = 0 ; h < qtPCRACK ; h++){ if(saltL[h][0]!='\0'){ result = crypt_r(&c_pass[k], saltL[h],&data); ok = strcmp(result,pCrackL[h]); if(!ok){ //printf("%s %s\n",result,pCrackL[h]); ok=1; saltL[h][0]='\0'; q++; printf("A %iª senha é: %s\n",h+1,&c_pass[k]); if(q==qtPCRACK)return 1; } } } } if(qtPGen>=intervalo)return 2; pass[tP-1]=0; c_pass[tP-1] = d[0]; for(j = tP-2 ; j>=0 ; j--){ if(pass[j] <T_D-1){ pass[j]++; c_pass[j]=d[pass[j]]; break; }else{ pass[j] = 0; c_pass[j] = d[0]; continue; } } } return 0; }
/* *This function recursively enumerates through a char array * of a given length. *It compares each enumeration with both its final goal and * the cryptographic hash. If one is a match the function * returns or exits respectively. */ int strenum(char *s,char *sp, char *f,struct crypt_data data){ int r; while( ((*sp)%97) < 26){ char *hash; hash = crypt_r(s,salt,&data); //You have found the hash. if (strcmp(hash,target) == 0){ printf("%s\n",s); exit(1); } //Check if its equal to final. if (strcmp(s,f) == 0){ return 1; } //Uses the NULL char to find end of current string. if (*(sp+1) != '\0'){ r = strenum(s,sp+1,f,data); if(r==1){ return 1; } *(sp+1)='a'; //Reset the value of the last changed char. } (*sp)++; } return 0; }
static void crypt_all(int count) { int index; #if defined(_OPENMP) && defined(__GLIBC__) #pragma omp parallel for default(none) private(index) shared(count, crypt_out, saved_key, saved_salt, crypt_data) for (index = 0; index < count; index++) { char *hash; int t = omp_get_thread_num(); if (t < MAX_THREADS) { struct crypt_data **data = &crypt_data[t]; if (!*data) { /* Stagger the structs to reduce their competition for the same cache lines */ size_t mask = MEM_ALIGN_PAGE, shift = 0; while (t) { mask >>= 1; if (mask < MEM_ALIGN_CACHE) break; if (t & 1) shift += mask; t >>= 1; } *data = (void *)((char *) mem_alloc_tiny(sizeof(**data) + shift, MEM_ALIGN_PAGE) + shift); memset(*data, 0, sizeof(**data)); } hash = crypt_r(saved_key[index], saved_salt, *data); } else { /* should not happen */
ngx_int_t ngx_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted) { char *value; size_t len; ngx_err_t err; struct crypt_data cd; ngx_set_errno(0); cd.initialized = 0; /* work around the glibc bug */ cd.current_salt[0] = ~salt[0]; value = crypt_r((char *) key, (char *) salt, &cd); err = ngx_errno; if (err == 0) { len = ngx_strlen(value); *encrypted = ngx_pnalloc(pool, len); if (*encrypted) { ngx_memcpy(*encrypted, value, len + 1); return NGX_OK; } } ngx_log_error(NGX_LOG_CRIT, pool->log, err, "crypt_r() failed"); return NGX_ERROR; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_PERMISSION_DENIED; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* be reentrant */ struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); int fCorrect = !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); if (!fCorrect) return VERR_PERMISSION_DENIED; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_PERMISSION_DENIED; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_PERMISSION_DENIED; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_PERMISSION_DENIED; #endif }
static int mod_authn_mysql_password_cmp(const char *userpw, unsigned long userpwlen, const char *reqpw) { #if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT) if (userpwlen >= 3 && userpw[0] == '$' && userpw[2] == '$') { /* md5 crypt() * request by Nicola Tiling <*****@*****.**> */ const char *saltb = userpw+3; const char *salte = strchr(saltb, '$'); char salt[32]; size_t slen = (NULL != salte) ? (size_t)(salte - saltb) : sizeof(salt); if (slen < sizeof(salt)) { char *crypted; #if defined(HAVE_CRYPT_R) struct crypt_data crypt_tmp_data; #ifdef _AIX memset(&crypt_tmp_data, 0, sizeof(crypt_tmp_data)); #else crypt_tmp_data.initialized = 0; #endif #endif memcpy(salt, saltb, slen); salt[slen] = '\0'; #if defined(HAVE_CRYPT_R) crypted = crypt_r(reqpw, salt, &crypt_tmp_data); #else crypted = crypt(reqpw, salt); #endif if (NULL != crypted) { return strcmp(userpw, crypted); } } } else #endif if (32 == userpwlen) { /* plain md5 */ li_MD5_CTX Md5Ctx; unsigned char HA1[16]; unsigned char md5pw[16]; li_MD5_Init(&Md5Ctx); li_MD5_Update(&Md5Ctx, (unsigned char *)reqpw, strlen(reqpw)); li_MD5_Final(HA1, &Md5Ctx); /*(compare 16-byte MD5 binary instead of converting to hex strings * in order to then have to do case-insensitive hex str comparison)*/ return (0 == http_auth_md5_hex2bin(userpw, 32 /*(userpwlen)*/, md5pw)) ? memcmp(HA1, md5pw, sizeof(md5pw)) : -1; } return -1; }
int equels_hash (task_t *task, context_t *context, struct crypt_data * data_single) { if (strcmp (context->hash, crypt_r(task->pass, context->hash, data_single)) == 0) { memcpy (context->password, task->pass, context->length); context->complete = !0; return !0; } else return 0; }
// Função usada pelas threads consumidoras void *testPasswords(void *v) { char *pass; char testHash[HASH_SIZE]; struct crypt_data cdata; cdata.initialized = 0; do { // Se a senha já foi bloqueada, encerra a thread if (found) { return NULL; } // Bloqueia o semáforo de acesso à fila sem_wait(&sem); pass = getFirstElementFila(filaPasswords); // Se a fila estava vazia e não há mais senhas a serem produzidas, encerra if (pass == NULL) { if (no_more_pass) { // Libera o semáforo antes de finalizar sem_post(&sem); return NULL; } } else { filaPasswords = removeFirstElementFila(filaPasswords); } // Libera o semáforo sem_post(&sem); if (pass != NULL) { // Gera o hash da senha que está sendo testada strcpy(testHash, crypt_r(pass, "aa", &cdata)); // Compara a hash gerada com a que está sendo procurada if (strcmp(hash, testHash) == 0) { printf("Achou: %s\n", pass); found = 1; return NULL; } } } while (1); return NULL; }
bool rtems_shell_login_check( const char *user, const char *passphrase ) { char buf[256]; struct passwd *pw_res; struct passwd pw; int eno; bool ok; eno = getpwnam_r(user, &pw, &buf[0], sizeof(buf), &pw_res); /* Valid user? */ if (eno == 0 && strcmp(pw.pw_passwd, "*") != 0) { if (strcmp(pw.pw_passwd, "") == 0) { ok = true; } else if (strcmp(pw.pw_passwd, "x") == 0) { /* TODO: /etc/shadow */ ok = false; } else { struct crypt_data data; char *s; s = crypt_r(passphrase, pw.pw_passwd, &data); ok = strcmp(s, pw.pw_passwd) == 0; } } else { ok = false; } if (ok && strcmp(pw.pw_dir, "") != 0) { ok = chroot(pw.pw_dir) == 0; } if (ok) { rtems_shell_env_t *env = rtems_shell_get_current_env(); if (env != NULL) { chown(env->devname, pw.pw_uid, 0); } setuid(pw.pw_uid); setgid(pw.pw_gid); seteuid(pw.pw_uid); setegid(pw.pw_gid); rtems_current_user_env_getgroups(); } return ok; }
/** * Add user * * @param uname Name of the new user * @param passwd Password for the new user * @return NULL on success or an error string on failure */ char * admin_add_user(char *uname, char *passwd) { FILE *fp; char fname[1024], *home, *cpasswd; initialise(); if (access(get_datadir(), F_OK) != 0) { if (mkdir(get_datadir(), S_IRWXU) != 0 && errno != EEXIST) { return ADMIN_ERR_PWDFILEOPEN; } } snprintf(fname,1023, "%s/passwd", get_datadir()); fname[1023] = '\0'; if (users == NULL) { MXS_NOTICE("Create initial password file."); if ((users = users_alloc()) == NULL) { return ADMIN_ERR_NOMEM; } if ((fp = fopen(fname, "w")) == NULL) { MXS_ERROR("Unable to create password file %s.", fname); return ADMIN_ERR_PWDFILEOPEN; } fclose(fp); } if (users_fetch(users, uname) != NULL) { return ADMIN_ERR_DUPLICATE; } struct crypt_data cdata; cdata.initialized = 0; cpasswd = crypt_r(passwd, ADMIN_SALT, &cdata); users_add(users, uname, cpasswd); if ((fp = fopen(fname, "a")) == NULL) { MXS_ERROR("Unable to append to password file %s.", fname); return ADMIN_ERR_FILEAPPEND; } fprintf(fp, "%s:%s\n", uname, cpasswd); fclose(fp); return ADMIN_SUCCESS; }
char *ast_crypt(const char *key, const char *salt) { struct crypt_data data = {}; const char *crypted = crypt_r(key, salt, &data); /* Crypt may return success even if it doesn't recognize the salt. But * in those cases it always mangles the salt in some way. */ if (!crypted || !ast_begins_with(crypted, salt)) { return NULL; } return ast_strdup(crypted); }
/*_______________________________________________________________________*/ void *passwordLooper(void *arg){ passwordData *pwd = (passwordData *)arg; int result; struct crypt_data data; //Data structure for crypt_r data.initialized = 0; //Initialized to zero int level = 0; int ks = pwd->keysize; password[ks] = 0; char localpw[9]; char *target = pwd->target; char *s = pwd->salt; //Checks possible passwords while (level < ks){ level = 0; pthread_mutex_lock(&alock); //Locking while (level < ks) { if (password[level] >= 'a' && password[level] < 'z'){ password[level]++; break; } if (password[level] == 'z'){ password[level] = 'a'; level++; } } strcpy(localpw, password); pthread_mutex_unlock(&alock); //Unlocking if (strcmp( crypt_r(localpw, s, &data), target ) == 0){ printf("password found!\n"); printf("Password = %s\n", localpw); exit(0); } } if (level >= ks){//if level ends up bigger than the keysize, break, no longer checking for passwords printf("Password not found\n"); exit(0); } return 0; }
void do_cmd_pass(session_t *pses) { if(pses == NULL) handle_error_str("do_cmd_user: pses is NULL."); //收到密码后,开始用户验证 //根据用户uid获取用户信息 struct passwd *pw = getpwuid(pses->uid); //尝试获取要登陆用户的信息 if(pw == NULL) { //用户不存在 ftp_reply(pses->ctrl_fd, FTP_LOGINERR, "Login incorrect."); //530 return; } //根据用户名字获取密码信息 struct spwd *sp = getspnam(pw->pw_name); if(sp == NULL) { //用户不存在 ftp_reply(pses->ctrl_fd, FTP_LOGINERR, "Login incorrect."); //530 return; } //将明文密码进行加密 struct crypt_data data; data.initialized = 0; char *encrupted_pass = crypt_r(pses->arg, sp->sp_pwdp,&data); //加密结果对比 if(strcmp(encrupted_pass, sp->sp_pwdp) != 0) { //验证失败 ftp_reply(pses->ctrl_fd, FTP_LOGINERR, "Login incorrect."); //530 return; } //密码验证成功 ftp_reply(pses->ctrl_fd, FTP_LOGINOK, "Login successful."); //230 //更改umask umask(tunable_local_umask); //更改进程属性 if(setegid(pw->pw_gid) < 0) handle_error("setegid"); if(seteuid(pw->pw_uid) < 0) handle_error("seteuid"); //更改当前工作目录到用户家目录 if(chdir(pw->pw_dir) < 0) handle_error("chdir"); }
static int compare_password(const char *newpass, const char *oldpass) { char *outval; #ifdef HAVE_CRYPT_R struct crypt_data output; output.initialized = 0; outval = crypt_r (newpass, oldpass, &output); #else outval = crypt (newpass, oldpass); #endif return outval != NULL && strcmp(outval, oldpass) == 0; }
static int do_test (void) { int result = 0; struct crypt_data cd; size_t n = sizeof (tests) / sizeof (*tests); size_t pagesize = (size_t) sysconf (_SC_PAGESIZE); char *page; /* Check that crypt won't look at the second character if the first one is invalid. */ page = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (page == MAP_FAILED) { perror ("mmap"); n--; } else { if (mmap (page + pagesize, pagesize, 0, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0) != page + pagesize) perror ("mmap 2"); page[pagesize - 1] = '*'; tests[n - 1][1] = &page[pagesize - 1]; } for (size_t i = 0; i < n; i++) { if (crypt (tests[i][0], tests[i][1])) { result++; printf ("%s: crypt returned non-NULL with salt \"%s\"\n", tests[i][0], tests[i][1]); } if (crypt_r (tests[i][0], tests[i][1], &cd)) { result++; printf ("%s: crypt_r returned non-NULL with salt \"%s\"\n", tests[i][0], tests[i][1]); } } return result; }
static uint16_t htpasswd_check(char *filename, char *auth) { char line[1024]; char *colon = strchr(auth, ':'); if (!colon) return 0; FILE *htpasswd = fopen(filename, "r"); if (!htpasswd) { return 0; } while(fgets(line, 1024, htpasswd)) { char *colon2 = strchr(line, ':'); if (!colon2) break; char *cpwd = colon2+1; size_t clen = strlen(cpwd); if (clen < 13) break; if (clen > 13) cpwd[13] = 0; #ifdef __linux__ struct crypt_data cd; cd.initialized = 0; // we do as nginx here cd.current_salt[0] = ~cpwd[0]; char *crypted = crypt_r( colon+1, cpwd, &cd); #else if (uwsgi.threads > 1) pthread_mutex_lock(&ur_basicauth_crypt_mutex); char *crypted = crypt( colon+1, cpwd); if (uwsgi.threads > 1) pthread_mutex_unlock(&ur_basicauth_crypt_mutex); #endif if (!crypted) continue; if (!strcmp( crypted, cpwd )) { if (!uwsgi_strncmp(auth, colon-auth, line, colon2-line)) { fclose(htpasswd); return colon-auth; } } } fclose(htpasswd); return 0; }
bool account_authenticate(struct account *account, const char *pw) { struct crypt_data data = { .initialized = 0 }; if (account->password == NULL || *account->password == '\0') { errlog("Account %s[%d] has NULL password. Setting to guess.", account->name, account->id); account_set_password(account, pw); } return !strcmp(account->password, crypt_r(pw, account->password, &data)); } void account_login(struct account *account, struct descriptor_data *d) { slog("login: %s[%d] from %s", account->name, account->id, d->host); set_desc_state(CXN_MENU, d); }
/** Performs a crypt password check in an thread-safe way. * * @param password The user's plaintext password. * @param reference_crypt The 'known good' crypt the password * is being compared to. * @return * - 0 crypt output matched reference crypt. * - 1 crypt output did not match reference crypt. * - -1 crypt failed. */ int fr_crypt_check(char const *password, char const *reference_crypt) { char *crypt_out; int cmp = 0; #ifdef HAVE_CRYPT_R struct crypt_data crypt_data; crypt_data.initialized = 0; crypt_out = crypt_r(password, reference_crypt, &crypt_data); if (crypt_out) cmp = strcmp(reference_crypt, crypt_out); #else /* * Ensure we're thread-safe, as crypt() isn't. */ pthread_mutex_lock(&fr_crypt_mutex); crypt_out = crypt(password, reference_crypt); /* * Got something, check it within the lock. This is * faster than copying it to a local buffer, and the * time spent within the lock is critical. */ if (crypt_out) cmp = strcmp(reference_crypt, crypt_out); pthread_mutex_unlock(&fr_crypt_mutex); #endif /* * Error. */ if (!crypt_out) return -1; /* * OK, return OK. */ if (cmp == 0) return 0; /* * Comparison failed. */ return 1; }
void *algorithm( void *hnd, c4snet_data_t *password, c4snet_data_t *salt, c4snet_data_t *dictionary, int dictionary_size) { struct crypt_data cdata; char *pw, *slt, *dict, *result; bool found = false; int i, j; cdata.initialized = 0; pw = C4SNetGetData(password); slt = C4SNetGetData(salt); dict = C4SNetGetData(dictionary); for (i = 0, j = 0; i < dictionary_size; i++) { result = crypt_r(&dict[j], slt, &cdata); if (!strcmp(result, pw)) { C4SNetOut(hnd, 1, C4SNetCreate(CTYPE_char, strlen(&dict[j]), &dict[j])); found = true; break; } else { j += 1 + strlen(&dict[j]); } } if (!found) { C4SNetOut(hnd, 2, 0); } C4SNetFree(password); C4SNetFree(salt); C4SNetFree(dictionary); return hnd; }
static int userauth(const char *user, const char *password, int gid, int rootfd) { int ret; char *pw, *pw_enc; if (gid != -1 && (ret = check_gid(user, gid)) != 0) return ret; ret = get_user_hash(user, gid, &pw); if (ret != 0) return ret; ret = escape_chroot(rootfd); if (ret == 0) { struct crypt_data data = {}; ret = VZCTL_E_AUTH; pw_enc = crypt_r(password, pw, &data); if (pw_enc && !strcmp(pw_enc, pw)) ret = 0; } free(pw); return ret; }
/* * Looks up an user name in a database and checks the password * * return values: * 1 = User not found * 0 = OK * -1 = Password incorrect * -2 = System error */ static int user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode, const char *user, const char *pass, int ctrl) { DBM *dbm; datum key, data; /* Open the DB file. */ dbm = dbm_open(database, O_RDONLY, 0644); if (dbm == NULL) { pam_syslog(pamh, LOG_ERR, "user_lookup: could not open database `%s': %m", database); return -2; } /* dump out the database contents for debugging */ if (ctrl & PAM_DUMP_ARG) { pam_syslog(pamh, LOG_INFO, "Database dump:"); for (key = dbm_firstkey(dbm); key.dptr != NULL; key = dbm_nextkey(dbm)) { data = dbm_fetch(dbm, key); pam_syslog(pamh, LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'", key.dsize, key.dptr, data.dsize, data.dptr); } } /* do some more init work */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); if (ctrl & PAM_KEY_ONLY_ARG) { if (asprintf(&key.dptr, "%s-%s", user, pass) < 0) key.dptr = NULL; else key.dsize = strlen(key.dptr); } else { key.dptr = strdup(user); key.dsize = strlen(user); } if (key.dptr) { data = dbm_fetch(dbm, key); memset(key.dptr, 0, key.dsize); free(key.dptr); } if (ctrl & PAM_DEBUG_ARG) { pam_syslog(pamh, LOG_INFO, "password in database is [%p]`%.*s', len is %d", data.dptr, data.dsize, (char *) data.dptr, data.dsize); } if (data.dptr != NULL) { int compare = 0; if (ctrl & PAM_KEY_ONLY_ARG) { dbm_close (dbm); return 0; /* found it, data contents don't matter */ } if (cryptmode && strncasecmp(cryptmode, "crypt", 5) == 0) { /* crypt(3) password storage */ char *cryptpw = NULL; if (data.dsize < 13) { compare = -2; } else if (ctrl & PAM_ICASE_ARG) { compare = -2; } else { #ifdef HAVE_CRYPT_R struct crypt_data *cdata = NULL; cdata = malloc(sizeof(*cdata)); if (cdata != NULL) { cdata->initialized = 0; cryptpw = crypt_r(pass, data.dptr, cdata); } #else cryptpw = crypt (pass, data.dptr); #endif if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) { compare = memcmp(data.dptr, cryptpw, data.dsize); } else { compare = -2; if (ctrl & PAM_DEBUG_ARG) { if (cryptpw) pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ"); else pam_syslog(pamh, LOG_INFO, "crypt() returned NULL"); } } #ifdef HAVE_CRYPT_R free(cdata); #endif } } else { /* Unknown password encryption method - * default to plaintext password storage */ if (strlen(pass) != (size_t)data.dsize) { compare = 1; /* wrong password len -> wrong password */ } else if (ctrl & PAM_ICASE_ARG) { compare = strncasecmp(data.dptr, pass, data.dsize); } else { compare = strncmp(data.dptr, pass, data.dsize); } if (cryptmode && strncasecmp(cryptmode, "none", 4) && (ctrl & PAM_DEBUG_ARG)) { pam_syslog(pamh, LOG_INFO, "invalid value for crypt parameter: %s", cryptmode); pam_syslog(pamh, LOG_INFO, "defaulting to plaintext password mode"); } } dbm_close(dbm); if (compare == 0) return 0; /* match */ else return -1; /* wrong */ } else { int saw_user = 0; if (ctrl & PAM_DEBUG_ARG) { pam_syslog(pamh, LOG_INFO, "error returned by dbm_fetch: %m"); } /* probably we should check dbm_error() here */ if ((ctrl & PAM_KEY_ONLY_ARG) == 0) { dbm_close(dbm); return 1; /* not key_only, so no entry => no entry for the user */ } /* now handle the key_only case */ for (key = dbm_firstkey(dbm); key.dptr != NULL; key = dbm_nextkey(dbm)) { int compare; /* first compare the user portion (case sensitive) */ compare = strncmp(key.dptr, user, strlen(user)); if (compare == 0) { /* assume failure */ compare = -1; /* if we have the divider where we expect it to be... */ if (key.dptr[strlen(user)] == '-') { saw_user = 1; if ((size_t)key.dsize == strlen(user) + 1 + strlen(pass)) { if (ctrl & PAM_ICASE_ARG) { /* compare the password portion (case insensitive)*/ compare = strncasecmp(key.dptr + strlen(user) + 1, pass, strlen(pass)); } else { /* compare the password portion (case sensitive) */ compare = strncmp(key.dptr + strlen(user) + 1, pass, strlen(pass)); } } } if (compare == 0) { dbm_close(dbm); return 0; /* match */ } } } dbm_close(dbm); if (saw_user) return -1; /* saw the user, but password mismatch */ else return 1; /* not found */ } /* NOT REACHED */ return -2; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd * must be NULL (no password set for this user). Fail if a password is specified * but the user does not have one assigned. */ int fCorrect = !pszPasswd || !*pszPasswd; if (pw->pw_passwd && *pw->pw_passwd) { struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); /* be reentrant */ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); } if (!fCorrect) return VERR_AUTHENTICATION_FAILURE; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_AUTHENTICATION_FAILURE; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_AUTHENTICATION_FAILURE; #endif }
static int valid(char *ciphertext, struct fmt_main *pFmt) { int length, count_base64, id, pw_length; char pw[PLAINTEXT_LENGTH + 1], *new_ciphertext; /* We assume that these are zero-initialized */ static char sup_length[BINARY_SIZE], sup_id[0x80]; length = count_base64 = 0; while (ciphertext[length]) { if (atoi64[ARCH_INDEX(ciphertext[length])] != 0x7F && (ciphertext[0] == '_' || length >= 2)) count_base64++; length++; } if (length < 13 || length >= BINARY_SIZE) return 0; id = 0; if (length == 13 && count_base64 == 11) id = 1; else if (length >= 13 && count_base64 >= length - 2 && /* allow for invalid salt */ (length - 2) % 11 == 0) id = 2; else if (length == 20 && count_base64 == 19 && ciphertext[0] == '_') id = 3; else if (ciphertext[0] == '$') { id = (unsigned char)ciphertext[1]; if (id <= 0x20 || id >= 0x80) id = 9; } else if (ciphertext[0] == '*' || ciphertext[0] == '!') /* likely locked */ id = 10; /* Previously detected as supported */ if (sup_length[length] > 0 && sup_id[id] > 0) return 1; /* Previously detected as unsupported */ if (sup_length[length] < 0 && sup_id[id] < 0) return 0; pw_length = ((length - 2) / 11) << 3; if (pw_length >= sizeof(pw)) pw_length = sizeof(pw) - 1; memcpy(pw, ciphertext, pw_length); /* reuse the string, why not? */ pw[pw_length] = 0; #if defined(_OPENMP) && defined(__GLIBC__) /* * Let's use crypt_r(3) just like we will in crypt_all() below. * It is possible that crypt(3) and crypt_r(3) differ in their supported hash * types on a given system. */ { struct crypt_data **data = &crypt_data[0]; if (!*data) { /* * **data is not exactly tiny, but we use mem_alloc_tiny() for its alignment * support and error checking. We do not need to free() this memory anyway. * * The page alignment is to keep different threads' data on different pages. */ *data = mem_alloc_tiny(sizeof(**data), MEM_ALIGN_PAGE); memset(*data, 0, sizeof(**data)); } new_ciphertext = crypt_r(pw, ciphertext, *data); } #else new_ciphertext = crypt(pw, ciphertext); #endif if (strlen(new_ciphertext) == length && !strncmp(new_ciphertext, ciphertext, 2)) { sup_length[length] = 1; sup_id[id] = 1; return 1; } if (id != 10 && !ldr_in_pot) #ifdef HAVE_MPI if (mpi_id == 0) #endif fprintf(stderr, "Generic crypt(3) module: " "hash encoding string length %d, type id %c%c\n" "appears to be unsupported on this system; " "will not load such hashes.\n", length, id > 0x20 ? '$' : '#', id > 0x20 ? id : '0' + id); if (!sup_length[length]) sup_length[length] = -1; if (!sup_id[id]) sup_id[id] = -1; return 0; }
if (mask < MEM_ALIGN_CACHE) break; if (t & 1) shift += mask; t >>= 1; } *data = (void *)((char *) mem_alloc_tiny(sizeof(**data) + shift, MEM_ALIGN_PAGE) + shift); memset(*data, 0, sizeof(**data)); } hash = crypt_r(saved_key[index], saved_salt, *data); } else { /* should not happen */ struct crypt_data data; memset(&data, 0, sizeof(data)); hash = crypt_r(saved_key[index], saved_salt, &data); } strnzcpy(crypt_out[index], hash, BINARY_SIZE); } #else #if defined(_OPENMP) && defined(__sun) /* * crypt(3C) is MT-safe on Solaris. For traditional DES-based hashes, this is * implemented with locking (hence there's no speedup from the use of multiple * threads, and the per-thread performance is extremely poor anyway). For * modern hash types, the function is actually able to compute multiple hashes * in parallel by different threads (and the performance for some hash types is * reasonable). Overall, this code is reasonable to use for SHA-crypt and * SunMD5 hashes, which are not yet supported by John natively. */ #pragma omp parallel for default(none) private(index) shared(count, crypt_out, saved_key, saved_salt)
/* * Validate a plaintext password against a smashed one. Uses either * crypt() (if available) or apr_md5_encode() or apr_sha1_base64(), depending * upon the format of the smashed input password. Returns APR_SUCCESS if * they match, or APR_EMISMATCH if they don't. If the platform doesn't * support crypt, then the default check is against a clear text string. */ APU_DECLARE(apr_status_t) apr_password_validate(const char *passwd, const char *hash) { char sample[200]; #if !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) char *crypt_pw; #endif if (hash[0] == '$' && hash[1] == '2' && (hash[2] == 'a' || hash[2] == 'y') && hash[3] == '$') { if (_crypt_blowfish_rn(passwd, hash, sample, sizeof(sample)) == NULL) return APR_FROM_OS_ERROR(errno); } else if (!strncmp(hash, apr1_id, strlen(apr1_id))) { /* * The hash was created using our custom algorithm. */ apr_md5_encode(passwd, hash, sample, sizeof(sample)); } else if (!strncmp(hash, APR_SHA1PW_ID, APR_SHA1PW_IDLEN)) { apr_sha1_base64(passwd, (int)strlen(passwd), sample); } else { /* * It's not our algorithm, so feed it to crypt() if possible. */ #if defined(WIN32) || defined(BEOS) || defined(NETWARE) return (strcmp(passwd, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; #elif defined(CRYPT_R_CRYPTD) apr_status_t rv; CRYPTD *buffer = malloc(sizeof(*buffer)); if (buffer == NULL) return APR_ENOMEM; crypt_pw = crypt_r(passwd, hash, buffer); if (!crypt_pw) rv = APR_EMISMATCH; else rv = (strcmp(crypt_pw, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; free(buffer); return rv; #elif defined(CRYPT_R_STRUCT_CRYPT_DATA) apr_status_t rv; struct crypt_data *buffer = malloc(sizeof(*buffer)); if (buffer == NULL) return APR_ENOMEM; #ifdef __GLIBC_PREREQ /* * For not too old glibc (>= 2.3.2), it's enough to set * buffer.initialized = 0. For < 2.3.2 and for other platforms, * we need to zero the whole struct. */ #if __GLIBC_PREREQ(2,4) #define USE_CRYPT_DATA_INITALIZED #endif #endif #ifdef USE_CRYPT_DATA_INITALIZED buffer->initialized = 0; #else memset(buffer, 0, sizeof(*buffer)); #endif crypt_pw = crypt_r(passwd, hash, buffer); if (!crypt_pw) rv = APR_EMISMATCH; else rv = (strcmp(crypt_pw, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; free(buffer); return rv; #else /* Do a bit of sanity checking since we know that crypt_r() * should always be used for threaded builds on AIX, and * problems in configure logic can result in the wrong * choice being made. */ #if defined(_AIX) && APR_HAS_THREADS #error Configuration error! crypt_r() should have been selected! #endif { apr_status_t rv; /* Handle thread safety issues by holding a mutex around the * call to crypt(). */ crypt_mutex_lock(); crypt_pw = crypt(passwd, hash); if (!crypt_pw) { rv = APR_EMISMATCH; } else { rv = (strcmp(crypt_pw, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; } crypt_mutex_unlock(); return rv; } #endif } return (strcmp(sample, hash) == 0) ? APR_SUCCESS : APR_EMISMATCH; }
void eStreamClient::notifier(int what) { if (!(what & eSocketNotifier::Read)) return; ePtr<eStreamClient> ref = this; char buf[512]; int len; if ((len = singleRead(streamFd, buf, sizeof(buf))) <= 0) { rsn->stop(); stop(); parent->connectionLost(this); return; } request.append(buf, len); if (running || (request.find('\n') == std::string::npos)) return; if (request.substr(0, 5) == "GET /") { size_t pos; if (eConfigManager::getConfigBoolValue("config.streaming.authentication")) { bool authenticated = false; if ((pos = request.find("Authorization: Basic ")) != std::string::npos) { std::string authentication, username, password; std::string hash = request.substr(pos + 21); pos = hash.find('\r'); hash = hash.substr(0, pos); hash += "\n"; { char *in, *out; in = strdup(hash.c_str()); out = (char*)calloc(1, hash.size()); if (in && out) { BIO *b64, *bmem; b64 = BIO_new(BIO_f_base64()); bmem = BIO_new_mem_buf(in, hash.size()); bmem = BIO_push(b64, bmem); BIO_read(bmem, out, hash.size()); BIO_free_all(bmem); authentication.append(out, hash.size()); } free(in); free(out); } pos = authentication.find(':'); if (pos != std::string::npos) { char *buffer = (char*)malloc(4096); if (buffer) { struct passwd pwd; struct passwd *pwdresult = NULL; std::string crypt; username = authentication.substr(0, pos); password = authentication.substr(pos + 1); getpwnam_r(username.c_str(), &pwd, buffer, 4096, &pwdresult); if (pwdresult) { struct crypt_data cryptdata; char *cryptresult = NULL; cryptdata.initialized = 0; crypt = pwd.pw_passwd; if (crypt == "*" || crypt == "x") { struct spwd spwd; struct spwd *spwdresult = NULL; getspnam_r(username.c_str(), &spwd, buffer, 4096, &spwdresult); if (spwdresult) { crypt = spwd.sp_pwdp; } } cryptresult = crypt_r(password.c_str(), crypt.c_str(), &cryptdata); authenticated = cryptresult && cryptresult == crypt; } free(buffer); } } } if (!authenticated) { const char *reply = "HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"streamserver\"\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } } pos = request.find(' ', 5); if (pos != std::string::npos) { std::string serviceref = urlDecode(request.substr(5, pos - 5)); if (!serviceref.empty()) { const char *reply = "HTTP/1.0 200 OK\r\nConnection: Close\r\nContent-Type: video/mpeg\r\nServer: streamserver\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); if (serviceref.substr(0, 10) == "file?file=") /* convert openwebif stream reqeust back to serviceref */ serviceref = "1:0:1:0:0:0:0:0:0:0:" + serviceref.substr(10); pos = serviceref.find('?'); if (pos == std::string::npos) { if (eDVBServiceStream::start(serviceref.c_str(), streamFd) >= 0) running = true; } else { request = serviceref.substr(pos); serviceref = serviceref.substr(0, pos); pos = request.find("?bitrate="); if (pos != std::string::npos) { /* we need to stream transcoded data */ int bitrate = 1024 * 1024; int width = 720; int height = 576; int framerate = 25000; int interlaced = 0; int aspectratio = 0; sscanf(request.substr(pos).c_str(), "?bitrate=%d", &bitrate); pos = request.find("?width="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?width=%d", &width); pos = request.find("?height="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?height=%d", &height); pos = request.find("?framerate="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?framerate=%d", &framerate); pos = request.find("?interlaced="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?interlaced=%d", &interlaced); pos = request.find("?aspectratio="); if (pos != std::string::npos) sscanf(request.substr(pos).c_str(), "?aspectratio=%d", &aspectratio); encoderFd = parent->allocateEncoder(this, serviceref, bitrate, width, height, framerate, !!interlaced, aspectratio); if (encoderFd >= 0) { running = true; streamThread = new eDVBRecordStreamThread(188); if (streamThread) { streamThread->setTargetFD(streamFd); streamThread->start(encoderFd); } } } } } } } if (!running) { const char *reply = "HTTP/1.0 400 Bad Request\r\n\r\n"; writeAll(streamFd, reply, strlen(reply)); rsn->stop(); parent->connectionLost(this); return; } request.clear(); }