生成时间格式为:Thu, 27 May 2010 12:12:35 +080

Publish: November 26, 2012 Category: C/C++ 1 Comment

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
 
#define DAY_MIN		(24 * HOUR_MIN)
#define HOUR_MIN	60
#define MIN_SEC		60
 
int main(int argc, char **argv)
{
	time_t now;
	struct tm *lt;
	struct tm gmt;
	int gmtoff;
	char vp[100];
	char *p = vp;
 
	time(&now);
 
	gmt = *gmtime(&now);
	lt = localtime(&now);
 
	gmtoff = (lt->tm_hour - gmt.tm_hour) * HOUR_MIN + lt->tm_min - gmt.tm_min;
	if (lt->tm_year < gmt.tm_year)
		gmtoff -= DAY_MIN;
	else if (lt->tm_year > gmt.tm_year)
		gmtoff += DAY_MIN;
	else if (lt->tm_yday < gmt.tm_yday)
		gmtoff -= DAY_MIN;
	else if (lt->tm_yday > gmt.tm_yday)
		gmtoff += DAY_MIN;
 
	if (lt->tm_sec <= gmt.tm_sec - MIN_SEC)
		gmtoff -= 1;
	else if (lt->tm_sec >= gmt.tm_sec + MIN_SEC)
		gmtoff += 1;
 
#ifdef MISSING_STRFTIME_E
#define STRFTIME_FMT "%a, %d %b %Y %H:%M:%S "
#else
#define STRFTIME_FMT "%a, %e %b %Y %H:%M:%S "
#endif
 
	int len = strftime(p, 100, STRFTIME_FMT, lt);
	p += len;
 
	if (gmtoff < -DAY_MIN || gmtoff > DAY_MIN)
	printf("UTC time offset %d is larger than one day", gmtoff);
	len = sprintf(p, "%+03d%02d", (int)(gmtoff / HOUR_MIN),
			(int)(abs(gmtoff) % HOUR_MIN));
	p += len;
 
	len = strftime(p, 100, " (%Z)", lt);
 
	printf("%s\n", vp);
 
	return 0;
}

使用Resolver获取MX记录

Publish: November 26, 2012 Category: C/C++ No Comments

/************************************
编译:
gcc -g -o dns dns.c -lresolv

测试:
./dns gmail.com

结果:
pref    domain name
20      alt2.gmail-smtp-in.l.google.com
30      alt3.gmail-smtp-in.l.google.com
40      alt4.gmail-smtp-in.l.google.com
5       gmail-smtp-in.l.google.com
10      alt1.gmail-smtp-in.l.google.com
*************************************/

//-----------------------------------
// dns.h
#ifndef     DNS_H
#define     DNS_H
 
#define     DNS_MSG_END -2
 
#define     dns_mx_query(str)       dns_resolve((str), T_MX)
#define     dns_mx_expand()         dns_findmx(T_MX)
 
#define     foreach_mxrr(p, dn)     while(dns_mx_expand() != DNS_MSG_END \
                                        && (!dns_get_mxrr(&p, dn, MAXDNAME)))
 
void dns_init(void);
int dns_get_mxrr(unsigned short *, unsigned char *, unsigned int);
int dns_resolve(char *, int);
int dns_findmx(int);
 
#endif
//-----------------------------------

//dns.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys types.h="">
#include <netinet in.h="">
#include <arpa nameser.h="">
#include <resolv.h>
#include <errno.h>
#include "dns.h"
 
extern int res_query();
extern int res_search();
extern int errno;
extern int h_errno;
 
HEADER	*hdr;
unsigned char *buf;
static int response_len;
static unsigned char *response_end;
static unsigned char *response_pos;
static int num_answers;
static char name[MAXDNAME];
unsigned short pref;
 
static unsigned short getshort(unsigned char *c)
{
    unsigned short u;
    u = c[0];
    return (u << 8) + c[1];
}
 
int dns_resolve(char *domain, int type)
{
    int     n;
    int     i;
    errno = 0;
    if (domain == NULL)
        return -1;
 
    response_len = res_search(domain, C_IN, type, buf, PACKETSZ);
 
    if (response_len <= 0)
        return -1;
 
    if (response_len >= PACKETSZ)
        response_len = PACKETSZ;
 
    response_end = buf + response_len;
    response_pos = buf + sizeof(HEADER);
    n = ntohs(hdr->qdcount);
    while (n-- > 0) {
        i = dn_expand(buf, response_end, response_pos, name, MAXDNAME);
        response_pos += i;
        i = response_end - response_pos;
        if (i < QFIXEDSZ)   return -1;
        response_pos += QFIXEDSZ;
    }
 
    num_answers = ntohs(hdr->ancount);
    return num_answers;
}
 
int dns_findmx(int want_type)
{
    unsigned short rrtype;
    unsigned short rrdlen;
    int             i;
 
    if (num_answers <= 0) return DNS_MSG_END;
    num_answers--;
 
    if (response_pos == response_end) return -1;
    i = dn_expand(buf, response_end, response_pos, name, MAXDNAME);
    if (i < 0) return -1;
    response_pos += i;
 
    i = response_end - response_pos;
    if (i < 10) return -1;
 
    rrtype = getshort(response_pos);
    rrdlen = getshort(response_pos + 8);
    response_pos += 10;
    if (rrtype == want_type) {
        if (rrdlen < 3) return -1;
        pref = (response_pos[0] << 8) + response_pos[1];
        memset(name, 0, MAXDNAME);
        if (dn_expand(buf, response_end, response_pos + 2, name, MAXDNAME) < 0)
            return -1;
        response_pos += rrdlen;
        return strlen(name);
    }
 
    response_pos += rrdlen;
    return 0;
}
 
void dns_init()
{
    res_init();
    memset(name, 0, MAXDNAME);
}
 
int dns_get_mxrr(unsigned short *p, unsigned char *dn, unsigned int len)
{
    *p = pref;
    strncpy(dn, name, len);
    if (len < (strlen(name) + 1))
        return -1;
    return 0;
}
 
int main(int argc, char **argv)
{
    char dname[MAXDNAME];
    int     i;
    unsigned short p;
 
	buf = (unsigned char *)calloc(1, PACKETSZ);
	if (buf == NULL) {
		fprintf(stderr, "calloc for response.buf failed");
		exit(-1);
	}
	hdr = (void *)buf;
 
    dns_init();
    if (argc != 2) {
        fprintf(stderr, "bad argument\n");
        exit(-1);
    }
 
    i = dns_mx_query(argv[1]);
    if (i < 0) {
        fprintf(stderr, "err\n");
        return 0;
    }
    printf("pref\tdomain name\n");
    foreach_mxrr(p, dname) {
        printf("%d\t%s\n", p, dname);
    }
 
    if (buf) {
        free(buf);
        buf = NULL;
    }
 
    return 0;
}

使用openssl进行Base64编解码

Publish: November 26, 2012 Category: C/C++ No Comments

/********************************************
编译:
gcc -g -o base64 base64.c -lssl

测试:
./base64 -e 123qwe
base64_encode("123qwe"): MTIzcXdl
 
./base64 -d MTIzcXdl
base64_decode("MTIzcXdl"): 123qwe
*********************************************/
//base64.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
 
char *base64_encode(const unsigned char *in, int32_t len)
{
	BIO		*bmem, *b64;
	BUF_MEM	*b_ptr;
 
	b64 = BIO_new(BIO_f_base64());
	bmem = BIO_new(BIO_s_mem());
	b64 = BIO_push(b64, bmem);
	BIO_write(b64, in, len);
	BIO_flush(b64);
	BIO_get_mem_ptr(b64, &b_ptr);
 
	char *buff = (char *)calloc(1, b_ptr->length);
	if (buff == NULL) {
		printf("alloc memory fail\n");
		return NULL;
	}
 
	memcpy(buff, b_ptr->data, b_ptr->length - 1);
	buff[b_ptr->length - 1] = 0;
 
	BIO_free_all(b64);
 
	return buff;
}
 
char *base64_decode(unsigned char *in, int32_t len)
{
	BIO		*b64, *bmem;
 
	char *buffer = (char *)calloc(1, len);
	if (buffer == NULL) {
		printf("alloc memory fail\n");
		return NULL;
	}
 
	b64 = BIO_new(BIO_f_base64());
	bmem = BIO_new_mem_buf(in, len);
	bmem = BIO_push(b64, bmem);
 
	BIO_read(bmem, buffer, len);
 
	BIO_free_all(bmem);
 
	return buffer;
}
 
int main(int argc, char **argv)
{
	char *type = argv[1];
	char *str = NULL;
	char *out = NULL;
 
    if (type[0] == '-' && type[1] == 'e') {
		str = argv[2];
		out = base64_encode(str, strlen(str));
		printf("base64_encode(\"%s\"): %s\n", str, out);
	} else {
		str = (char *)calloc(1, strlen(argv[2]) + 1);
		if (str == NULL) {
			printf("calloc memory fail\n");
			return -1;
		}
		memcpy(str, argv[2], strlen(argv[2]));
		str[strlen(argv[2])] = '\n';
		str[strlen(argv[2])+1] = '\0';
		out = base64_decode(str, strlen(str));
		printf("base64_decode(\"%s\"): %s\n", argv[2], out);
		free(str);
	}
 
	free(out);
 
	return 0;
}

使用openssl做SSHA认证

Publish: November 26, 2012 Category: C/C++ 9 Comments

/*******************************
编译:
gcc -g -o ssha_check ssha_check.c -lssl

测试:
./ssha_check shanghai 8Mhh1STpS0WOcp15/hd26yZMbE9uRMN0NQcBEQ==
ret: 0
*********************************/
//ssha_check.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
 
#define PASSWD_OK      (0)
#define PASSWD_ERR     (-1)
#define SHA1_BYTES 20
 
char *base64_decode(unsigned char *in, int32_t len)
{
    BIO		*b64, *bmem;
 
    char *buffer = (char *)calloc(1, len);
    if (buffer == NULL) {
        printf("alloc memory fail\n");
        return -1;
    }
 
    b64 = BIO_new(BIO_f_base64());
    bmem = BIO_new_mem_buf(in, len);
    bmem = BIO_push(b64, bmem);
 
    BIO_read(bmem, buffer, len);
 
    BIO_free_all(bmem);
 
    return buffer;
}
 
/*
*   @passwd:    source passwd from user intpu
*   @cred:      ssha passwd
*   return:
*       0:      succ
*      -1:      fail
*/
static int chk_ssha1(const char *passwd, const char *cred)
{
    SHA_CTX SHA1context;
    unsigned char SHA1digest[SHA1_BYTES];
    int32_t rc;
    unsigned char *orig_pass = NULL;
    char *cred_pass = NULL;
 
    /* safety check -- must have some salt */
    if (BASE64_DECODE_LEN(strlen(cred)) <= sizeof(SHA1digest)) {
        return PASSWD_ERR;
    }
 
    /* decode base64 password */
    cred_pass = (unsigned char *)calloc(1, strlen(cred) + 1);
    if(cred_pass == NULL ) return PASSWD_ERR;
 
    memcpy(cred_pass, cred, strlen(cred));
    cred_pass[strlen(cred)] = '\n';
    cred_pass[strlen(cred)+1] = '\0';
 
    orig_pass = base64_decode(cred_pass, strlen(cred_pass));
    rc = strlen(orig_pass);
 
    /* safety check -- must have some salt */
    if (rc <= (int)(sizeof(SHA1digest))) {
        free(cred_pass);
        free(orig_pass);
        return PASSWD_ERR;
    }
 
    /* hash credentials with salt */
    SHA1_Init(&SHA1context);	
    SHA1_Update(&SHA1context,
        (const unsigned char *) passwd, strlen(passwd));
    SHA1_Update(&SHA1context,
        (const unsigned char *) &orig_pass[sizeof(SHA1digest)],
        rc - sizeof(SHA1digest));
    SHA1_Final(SHA1digest, &SHA1context);
 
    /* compare */
    rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
 
    free(cred_pass);
    free(orig_pass);
 
    return rc ? PASSWD_ERR : PASSWD_OK;
}
 
// ./ssha_check shanghai 8Mhh1STpS0WOcp15/hd26yZMbE9uRMN0NQcBEQ==
int main(int argc, char **argv)
{
    char *passwd = argv[1];
    char *cred = argv[2];
 
    int32_t ret = chk_ssha1(passwd, cred);
 
    printf("ret: %d\n", ret);
 
    return 0;
}

getopt 使用

Publish: November 26, 2012 Category: C/C++ No Comments

#include <stdio.h>
#include <string.h>
#include <getopt.h>

int main(int argc, char **argv)
{
	char cond_file[1024];
	char dict_file[1024];
	int size = 0;

	int ch;
	const char *args = "c:d:f:s:h";
	while ((ch = getopt(argc, argv, args)) != -1) {
		switch (ch) {
			case 'c':
				snprintf(cond_file, sizeof(cond_file), "%s", optarg);
				break;
			case 'd':
				snprintf(dict_file, sizeof(dict_file), "%s", optarg);
				break;
			case 's':
				size = atoi(optargs);
				break;

			case 'h':
			default:
				usage(argv[0]);
				exit(0);
		}
	}
	
	return 0;

}