📄 encode.c
字号:
#include <stdio.h>#include <string.h>#define BUFOVER 1#define FALSE 0#define TRUE 1#define SVPN_ACL_MAX_URL_LEN 4096static char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";typedef void T_VOID;typedef char T_CHAR8;typedef unsigned char T_UCHAR8;typedef int T_INT32;#define RP_HTTP_SCHEMA "http://"#define RP_HTTP_SCHEMA_LEN 7#define RP_HTTPS_SCHEMA "https://"#define RP_HTTPS_SCHEMA_LEN 8#define T_SUCCESS 0#define T_FAILURE -1#define T_strncmp strncmp#define T_strlen strlen#define T_strcspn strcspn#define T_strchr strchr#define T_strstr strstr#define T_strncpy strncpy#define T_memcpy memcpy#define T_memmove memmove#define T_memset memset#define H2B(a) ((a) <= '9' ? (a) - '0' : (a) - 55);#define ISXDIGIT(a) (((a) >= '0' && (a) <= '9') || ((a) >= 'A' && (a) <= 'F') || ((a) >= 'a' && (a) <= 'f'))intcvt(char *dst, int dlen, char *src, int slen){ int state = 0, code = 0; char *start = dst; char *dlim = dst+dlen; char *slim = src+slen; if (dst >= dlim) { return 0; } dlim--; /* ensure spot for '\0' */ while (src < slim && dst < dlim) { switch (state) { case 0: if (*src == '%') { state = 1; } else { *dst++ = *src; } break; case 1: code = H2B(*src); case 2: if (ISXDIGIT(*src) == 0) { //errno = EILSEQ; return -1; } if (state == 2) { *dst++ = (code * 16) + H2B(*src); state = 0; } else { state = 2; } break; } src++; } *dst = '\0'; /* I'll be back */ return dst - start;}int base64Encode(const char *_in, unsigned inlen, char *_out, unsigned outmax, unsigned *outlen){ const unsigned char *in = (const unsigned char *)_in; unsigned char *out = (unsigned char *)_out; unsigned char oval; char *blah; unsigned olen; /* Will it fit? */ olen = (inlen + 2) / 3 * 4; if (outlen) *outlen = olen; if (outmax < olen) return BUFOVER; /* Do the work... */ blah=(char *) out; while (inlen >= 3) { /* user provided max buffer size; make sure we don't go over it */ *out++ = basis_64[in[0] >> 2]; *out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)]; *out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; *out++ = basis_64[in[2] & 0x3f]; in += 3; inlen -= 3; } if (inlen > 0) { /* user provided max buffer size; make sure we don't go over it */ *out++ = basis_64[in[0] >> 2]; oval = (in[0] << 4) & 0x30; if (inlen > 1) oval |= in[1] >> 4; *out++ = basis_64[oval]; *out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c]; *out++ = '='; } if (olen < outmax) *out = '\0'; return T_SUCCESS;}T_VOID base64Decode(T_CHAR8 *intext, T_CHAR8 *out, T_INT32 *length){ T_UCHAR8 ibuf[4]; T_UCHAR8 obuf[3]; T_CHAR8 ignore; T_CHAR8 endtext = FALSE; T_CHAR8 ch; T_INT32 lindex = 0; *length = 0; memset(ibuf, 0, sizeof(ibuf)); while (*intext) { ch = *intext; ignore = FALSE; if ((ch >= 'A') && (ch <= 'Z')) ch = ch - 'A'; else if ((ch >= 'a') && (ch <= 'z')) ch = ch - 'a' + 26; else if ((ch >= '0') && (ch <= '9')) ch = ch - '0' + 52; else if (ch == '+') ch = 62; else if (ch == '=') { /* end of text */ if (endtext) break; endtext = TRUE; lindex--; if (lindex < 0) lindex = 3; } else if (ch == '/') ch = 63; else if (endtext) break; else ignore = TRUE; if (!ignore) { if (!endtext) { ibuf[lindex] = ch; lindex++; lindex &= 3; /* use bit arithmetic instead of remainder */ } if ((0 == lindex) || endtext) { obuf[0] = (ibuf[0] << 2) | ((ibuf[1] & 0x30) >> 4); obuf[1] = ((ibuf[1] & 0x0F) << 4) | ((ibuf[2] & 0x3C) >> 2); obuf[2] = ((ibuf[2] & 0x03) << 6) | (ibuf[3] & 0x3F); switch (lindex) { case 1: sprintf(out, "%c", obuf[0]); out++; (*length)++; break; case 2: sprintf(out, "%c%c", obuf[0], obuf[1]); out += 2; (*length) += 2; break; default: sprintf(out, "%c%c%c", obuf[0], obuf[1], obuf[2]); out += 3; (*length) += 3; break; } memset(ibuf, 0, sizeof(ibuf)); } } intext++; } *out = 0;}#define RP_MAX_BASE64_DECODE_LEN 1024/* ---------------------------------------------------------- */static inline void replace_slash(char *input){ char *hit; while((hit = strchr(input, '/')) != NULL) { *hit = '$'; input = hit + 1; }}inline void recover_slash(char *input){ char *hit; while((hit = strchr(input, '$')) != NULL) { *hit = '/'; input = hit + 1; }}T_VOID ZYEncryptEncodeURL(T_CHAR8 *pPrefix, T_CHAR8 *pURL, T_CHAR8 endChar){ T_CHAR8 *pPtr; T_CHAR8 *pTmp; T_INT32 iTmpLen = 0, iOutLen; T_CHAR8 delimitStr[2] = {0}; const T_CHAR8 ch = '~'; T_CHAR8 *hit, *iterator, *sharp; //T_INT32 iEndLen; if (*pURL == endChar) { return; } delimitStr[0] = endChar; //iEndLen = strcspn(pURL, delimitStr); //*(pURL+iEndLen) = '\0'; pPtr = pPrefix + T_strlen(pPrefix); iOutLen = 0; pTmp = pURL; if(!T_strncmp(pTmp, RP_HTTP_SCHEMA, RP_HTTP_SCHEMA_LEN)) { hit = strchr(pTmp + RP_HTTP_SCHEMA_LEN, '/'); iTmpLen = hit ? hit - pTmp + 1 : strlen(pTmp); } else if(!T_strncmp(pURL, RP_HTTPS_SCHEMA, RP_HTTPS_SCHEMA_LEN)) { hit = strchr(pTmp + RP_HTTPS_SCHEMA_LEN, '/'); iTmpLen = hit ? hit - pTmp + 1 : strlen(pTmp); } if(iTmpLen) { *pPtr++ = ch; base64Encode(pTmp, iTmpLen, pPtr, RP_MAX_BASE64_DECODE_LEN, &iOutLen); pTmp += iTmpLen; replace_slash(pPtr); pPtr += iOutLen; *pPtr++ = '/'; } if (!*pTmp) { *pPtr = '\0'; //*(pURL+iEndLen) = endChar; return; } iTmpLen = 0; /* hit will be the last '/' */ hit = NULL; sharp = NULL; iterator = pTmp; while(*iterator != '\0') { switch(*iterator) { case '?': case '#': sharp = iterator; goto done; case '/': hit = iterator + 1; default: iterator++; /* ??? */ break; } }done: if(hit) { *pPtr++ = ch; base64Encode(pTmp, hit - pTmp, pPtr, RP_MAX_BASE64_DECODE_LEN, &iOutLen); replace_slash(pPtr); pPtr += iOutLen; *pPtr++ = '/'; if(sharp) { // sharp must be after hit if(sharp - hit) { *pPtr++ = ch; base64Encode(hit, sharp - hit, pPtr, RP_MAX_BASE64_DECODE_LEN, &iOutLen); replace_slash(pPtr); pPtr += iOutLen; } strcpy(pPtr, sharp); } else { if(*hit) { *pPtr++ = ch; base64Encode(hit, strlen(hit), pPtr, RP_MAX_BASE64_DECODE_LEN, &iOutLen); replace_slash(pPtr); } else *pPtr = '\0'; } } else { if(sharp) { if(sharp - pTmp) { *pPtr++ = ch; base64Encode(pTmp, sharp - pTmp, pPtr, RP_MAX_BASE64_DECODE_LEN, &iOutLen); replace_slash(pPtr); pPtr += iOutLen; } strcpy(pPtr, sharp); } else { if(iterator - pTmp) { *pPtr++ = ch; base64Encode(pTmp, iterator - pTmp, pPtr, RP_MAX_BASE64_DECODE_LEN, &iOutLen); replace_slash(pPtr); } else *pPtr = '\0'; } } //*(pURL+iEndLen) = endChar; return;}/* end of ZYEncryptEncodeURL()*/#if 0#define REVPROXY_DBG#define ZYXEL_DEBUG#endifT_INT32 ZYDecodeDecryptURL(T_CHAR8 **pencURL, T_CHAR8 *pdecURL, T_CHAR8 endchar){ T_CHAR8 *pPtr = 0; T_INT32 iTmpLen = 0, idecURLlen = 0, iLen; T_CHAR8 ch, delimiter[2]={0}; T_CHAR8 URLDecBuf[SVPN_ACL_MAX_URL_LEN+1]; if (**pencURL == endchar) { return T_SUCCESS; } delimiter[0] = endchar; T_memset(URLDecBuf, 0 , SVPN_ACL_MAX_URL_LEN+1); iTmpLen = strcspn(*pencURL, delimiter); /* locate encryption termination char */ if (iTmpLen > SVPN_ACL_MAX_URL_LEN) {#ifdef REVPROXY_DBG printf("Cannot do URL decoding!");#endif pPtr = *pencURL; } else { cvt(URLDecBuf, SVPN_ACL_MAX_URL_LEN+1, *pencURL, iTmpLen);#ifdef REVPROXY_DBG printf("Before URL decoding: %s\n", *pencURL); printf("After URL decoding: %s\n", URLDecBuf);#endif pPtr = URLDecBuf; }#ifdef ZYXEL_DEBUG printf("[ZYXEL_DEBUG]%s: %d: %s():\n", __FILE__, __LINE__, __func__);#endif if (*pPtr != '~') /* some OWA URL links are not encrypted so this condition is required. */ {#ifdef REVPROXY_DBG printf("***Not an Encrypted URL***\n");#endif//eddie: In this case, do not URL decode it because of space character. #if 1 pPtr = *pencURL;#endif iTmpLen = strcspn(pPtr, delimiter); /* locate end char */ if (iTmpLen > SVPN_ACL_MAX_URL_LEN) {#ifdef SSLVPN_DEBUG Trace(SSLVPN_ID, TRACE_SEVERE, "Request URL Exceeded Maximum URL Length Limit");#endif return T_FAILURE; } T_strncpy(pdecURL, pPtr, iTmpLen); pdecURL[iTmpLen] = '\0'; return T_SUCCESS; } else {#ifdef REVPROXY_DBG printf("***This is an Encrypted URL***\n");#endif } /* Decode the URL */ while((*pPtr == '~') && (iTmpLen = strcspn(++pPtr, "/?#"))) { iTmpLen = strcspn(pPtr, "/?#"); ch = *(pPtr+iTmpLen); *(pPtr+iTmpLen) = '\0'; /* replase all '$' with '/' character. since '/' is a delimiter * for folder name it has been escaped at the client end with '$' charcter */ recover_slash(pPtr); base64Decode(pPtr, (T_CHAR8 *)pdecURL+idecURLlen, &iLen); idecURLlen += iLen; pdecURL[idecURLlen] = '\0'; *(pPtr+iTmpLen) = ch; pPtr += iTmpLen; if (*pPtr == '?' || *pPtr == '#') { break; } pPtr++; } if (*pPtr) { strcpy(pdecURL+idecURLlen, pPtr); } pPtr = pdecURL;#ifdef REVPROXY_DBG printf("Decrypted URL: %s\n", pdecURL);#endif return T_SUCCESS;}/* end of ZYDecodeDecryptURL() *//* ---------------------------------------------------------- */intmain(){ int i; char *to_encode[] = {// "http://www.abc.com",// "http://www.abc.com/",// "http://www.abc.com/#",// "http://www.abc.com/dir/",// "http://www.abc.com/~julian/",// "http://www.abc.com/hello/world/a.html",// "http://www.abc.com/zysh-cgi?cmd=encode",// "https://www.abc.com/zysh-cgi#result",// "https://www.abc.com/zysh-cgi?cmd=/",// "a.html", "a.html#hello", "#hello", "#",// "http://www.zyxel.com/~julian/#",// "http://www.zyxel.com/~julian/a.html#zzz", }; T_CHAR8 outbuf[1024]; T_CHAR8 outbuf2[1024]; T_CHAR8 *pPtr; for(i = 0; i < sizeof(to_encode) / sizeof(char *); i++) { outbuf[0] = '\0'; outbuf2[0] = '\0'; ZYEncryptEncodeURL(outbuf, to_encode[i], '\n'); printf("=====================================\n"); printf("[%s] --> [%s]\n", to_encode[i], outbuf); pPtr = outbuf; ZYDecodeDecryptURL(&pPtr, outbuf2, '\n'); printf("[%s] --> [%s]\n", outbuf, outbuf2); printf("=====================================\n"); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -