⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libapr.c

📁 用于对svn的用户密码进行加密和校验的源程序。可以很方便的生成svn服务器使用的密码格式
💻 C
字号:
#include <stdlib.h>
#include <string.h>
#include "libapr.h"
#include "md5.h"

static const char *apr1_id = "$apr1$";
static const char itoa64[] =         /* 0 ... 63 => ASCII - 64 */
		"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

static void to64(char *s, unsigned long v, int n)
{
    while (--n >= 0) {
        *s++ = itoa64[v&0x3f];
        v >>= 6;
    }
}

char *getRandomString(int Len, char *buf, const char *KeyStr)
{
	static int Rand_Init = 0;
	int MaxLen;
	const char *key = itoa64;
	char *p = buf;
	if(KeyStr)
		key = KeyStr;
	MaxLen = strlen(key);
	if(!Rand_Init)
	{
		#include <time.h>
		time_t tm;
		srand(time(&tm));
		Rand_Init = 1;
	}
	if(p)
	{
		while(Len > 0)
		{
			*p++ = key[rand() % MaxLen];
			Len--;
		}
		*p = '\0';
	}
	return buf;
}

int password_encode(const char *pw, const char *salt, char *result, size_t len)
{
	char rand_salt[9];
	char passwd[128] = "";
	unsigned char Final[16];
	const char *sp;
	int sl;
	md5_ctx_t cry1, cry2;

	int pl, i;
	if((salt == NULL) || ((salt != NULL) && (strlen(salt) == 0)))
	{
		int len;
		getRandomString(0, NULL, NULL);
		len = rand() & 0x03;
		len += 3;
		getRandomString(len, rand_salt, NULL);
		sp = rand_salt;
		sl = strlen(sp);
	}
	else
	{
		const char *ep;
		sp = salt;
		if (!strncmp(sp, apr1_id, strlen(apr1_id))) {
			sp += strlen(apr1_id);
		}
		for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++);
		sl = ep - sp;
	}
	md5_init(&cry1);
	md5_init(&cry2);
	// md5(pw, apr1_id, salt)
	md5_update(&cry1, pw, strlen(pw));
	md5_update(&cry1, apr1_id, 6);
	md5_update(&cry1, sp, sl);
	// md5(pw, salt, pw)
	md5_update(&cry2, pw, strlen(pw));
	md5_update(&cry2, sp, sl);
	md5_update(&cry2, pw, strlen(pw));
	md5_final(&cry2, Final);
	for(pl = strlen(pw); pl > 0; pl -= 16)
		md5_update(&cry1, Final, pl > 16 ? 16 : pl);

	memset(Final, 0, 16);
    for(i = strlen(pw); i != 0; i >>= 1)
	{
        if (i & 1)
			md5_update(&cry1, Final, 1);
        else
			md5_update(&cry1, pw, 1);
    }
    /*
     * Now make the output string.  We know our limitations, so we
     * can use the string routines without bounds checking.
     */
    strcpy(passwd, apr1_id);
    strncat(passwd, sp, sl);
    strcat(passwd, "$");
	md5_final(&cry1, Final);
    for (i = 0; i < 1000; i++)
	{
		md5_ctx_t cry3;
		md5_init(&cry3);
		/*
		* apr_md5_final clears out ctx1.xlate at the end of each loop,
		* so need to to set it each time through
		*/
        if (i & 1)
			md5_update(&cry3, pw, strlen(pw));
        else
            md5_update(&cry3, Final, 16);

        if (i % 3)
			md5_update(&cry3, sp, sl);
		
        if (i % 7)
			md5_update(&cry3, pw, strlen(pw));
		
        if (i & 1)
			md5_update(&cry3, Final, 16);
        else
			md5_update(&cry3, pw, strlen(pw));

		md5_final(&cry3, Final);
    }
	{
		char *p = passwd + strlen(passwd);
		unsigned long l;
		l = (Final[ 0]<<16) | (Final[ 6]<<8) | Final[12]; to64(p, l, 4); p += 4;
		l = (Final[ 1]<<16) | (Final[ 7]<<8) | Final[13]; to64(p, l, 4); p += 4;
		l = (Final[ 2]<<16) | (Final[ 8]<<8) | Final[14]; to64(p, l, 4); p += 4;
		l = (Final[ 3]<<16) | (Final[ 9]<<8) | Final[15]; to64(p, l, 4); p += 4;
		l = (Final[ 4]<<16) | (Final[10]<<8) | Final[ 5]; to64(p, l, 4); p += 4;
		l =                    Final[11]                ; to64(p, l, 2); p += 2;
		*p = '\0';
	}
	memcpy(result, passwd, len);
	return 0;
}

int password_validate(const char *passwd, const char *hash)
{
	char key[128];
	password_encode(passwd, hash, key, 128);
	if(strlen(key) == strlen(hash))
		if(strcmp(key, hash) == 0)
			return 1;
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -