summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Shyti <andi@etezian.org>2012-09-02 02:12:08 +0200
committerAndi Shyti <andi@etezian.org>2012-09-02 02:12:08 +0200
commitfdb1692c4e93ec4a71453d5d6c319fe1d6405e60 (patch)
tree0f6142f3858f3f79f00d13097a73b60f89b37476
accman: git repo created
Signed-off-by: Andi Shyti <andi@etezian.org>
-rw-r--r--.gitignore4
-rw-r--r--Makefile20
-rw-r--r--accman.c63
-rw-r--r--include/accman.h16
-rw-r--r--include/db.h6
-rw-r--r--include/encrypt.h6
-rw-r--r--src/crypt_sha256.c76
-rw-r--r--src/db_user.c32
8 files changed, 223 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dae75df
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*~
+*.swp
+bin/*
+bin
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f48c1bf
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+CC=gcc
+SRC=accman.c src/crypt_sha256.c src/db_user.c
+BINDIR=bin
+INC=-Iinclude/ -I/usr/include/mysql
+OPT_DBG=-g
+OPT_OPT=-O2
+OPT=-Wall -DBIG_JOINS=1 -fno-strict-aliasing
+LD=-lssl -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lm -lrt -ldl
+TARGET=accman
+
+${TARGET}:
+ $(shell mkdir -p bin)
+ ${CC} ${OPT} ${OPT_OPT} ${LD} ${INC} ${SRC} -o ${BINDIR}/${TARGET}
+
+debug:
+ $(shell mkdir -p bin)
+ ${CC} ${OPT} ${OPT_DBG} ${LD} ${INC} ${SRC} -o ${BINDIR}/${TARGET}
+
+clean:
+ rm -rf bin
diff --git a/accman.c b/accman.c
new file mode 100644
index 0000000..79a3d1c
--- /dev/null
+++ b/accman.c
@@ -0,0 +1,63 @@
+#include <accman.h>
+#include <string.h>
+#include <encrypt.h>
+#include <unistd.h>
+#include <encrypt.h>
+#include <stdint.h>
+#include <ctype.h>
+#include <db.h>
+
+char *get_name(void)
+{
+ char name[32];
+ char *usr_n;
+
+ scanf("%s", name);
+ usr_n = (char *) malloc(sizeof(name) + DIM_MDOM + 1);
+ if (!usr_n) {
+ printf("No free memory available\n");
+ exit(EXIT_FAILURE);
+ }
+
+ strcpy(usr_n, name);
+ strcat(usr_n, MDOMAIN);
+
+ return usr_n;
+}
+
+uint8_t confirm(struct user u)
+{
+ int i;
+ char choice[32];
+ ssize_t len;
+
+ printf("User: %s\n", u.n);
+ printf("Do you want to insert new user '%s'? [Y/n] \n", u.n);
+
+ len = read(0, choice, 32);
+ choice[len-1] = '\0';
+
+ for (i = 0; i < strlen(choice); i++)
+ choice[i] = toupper(choice[i]);
+
+ return (!strcmp(choice, "Y") || !strcmp(choice, "YES") ||
+ !strcmp(choice, "")) ? 1 : 0;
+}
+
+int main (void)
+{
+ struct user usr;
+
+ printf("Insert user name (user@etezian.org): ");
+ usr.n = get_name();
+ usr.p = get_crypt_sha256(getpass("Password: "));
+
+ if (confirm(usr)) {
+ db_insert_user(usr);
+ printf("User %s inserted correctly\n", usr.n);
+ }
+ else
+ printf("user insertion aborted\n");
+
+ return 0;
+}
diff --git a/include/accman.h b/include/accman.h
new file mode 100644
index 0000000..27bfe2b
--- /dev/null
+++ b/include/accman.h
@@ -0,0 +1,16 @@
+#ifndef _ACCMAN_H_
+#define _ACCMAN_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DOMAIN "etezian.org"
+#define MDOMAIN "@"DOMAIN
+#define DIM_MDOM 12
+
+struct user {
+ char *n;
+ char *p;
+};
+
+#endif
diff --git a/include/db.h b/include/db.h
new file mode 100644
index 0000000..f391284
--- /dev/null
+++ b/include/db.h
@@ -0,0 +1,6 @@
+#ifndef _DB_H_
+#define _DB_H_
+
+void db_insert_user(struct user);
+
+#endif
diff --git a/include/encrypt.h b/include/encrypt.h
new file mode 100644
index 0000000..116e781
--- /dev/null
+++ b/include/encrypt.h
@@ -0,0 +1,6 @@
+#ifndef _ENCRYPT_H_
+#define _ENCRYPT_H_
+
+char* get_crypt_sha256(const char *);
+
+#endif
diff --git a/src/crypt_sha256.c b/src/crypt_sha256.c
new file mode 100644
index 0000000..c480637
--- /dev/null
+++ b/src/crypt_sha256.c
@@ -0,0 +1,76 @@
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+
+#define RAND_FILE "/dev/random"
+#define SHA_STR "{SHA256}"
+
+/* string length */
+#define LEN_PASSWD_MIN 8
+#define LEN_PASSWD_MAX 64
+#define LEN_RAND_STR 16
+#define LEN_BUFFER LEN_PASSWD_MAX + LEN_RAND_STR + \
+ SHA256_DIGEST_LENGTH
+#define LEN_ENC64 64
+#define LEN_SHA_STR 8
+#define LEN_FINAL_PASSWD LEN_ENC64 + LEN_SHA_STR + 1
+
+
+uint8_t check_passwd(const char *p, size_t len)
+{
+ return ((len > LEN_PASSWD_MIN) || (len < LEN_PASSWD_MAX)) ? 1 : 0;
+}
+
+char* get_crypt_sha256(const char *p)
+{
+ int rand_fd;
+ ssize_t size;
+ size_t len = strlen(p);
+ char rand_str[LEN_RAND_STR];
+ char passwd_buff[LEN_BUFFER];
+ char sha_pwd[SHA256_DIGEST_LENGTH];
+ char enc64_pwd[LEN_ENC64];
+ char *final_pwd;
+
+ if (!check_passwd(p, len)) {
+ fprintf(stderr,
+ "the password has to be between 8 and 64 chars\n");
+ exit(EXIT_FAILURE);
+ }
+
+ rand_fd = open(RAND_FILE, O_RDONLY);
+ if (rand_fd < 0) {
+ fprintf(stderr, "impossible to open " RAND_FILE "\n");
+ exit(EXIT_FAILURE);
+ }
+
+ size = read(rand_fd, rand_str, LEN_RAND_STR);
+ close(rand_fd);
+ if (size != LEN_RAND_STR) {
+ fprintf(stderr, "failed to read from " RAND_FILE "\n");
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(passwd_buff + SHA256_DIGEST_LENGTH, p, len);
+ memcpy(passwd_buff + SHA256_DIGEST_LENGTH + len,
+ rand_str, LEN_RAND_STR);
+
+ SHA256((unsigned char*) passwd_buff + SHA256_DIGEST_LENGTH,
+ len + LEN_RAND_STR, (unsigned char*) sha_pwd);
+
+ memcpy(passwd_buff, sha_pwd, SHA256_DIGEST_LENGTH);
+
+ EVP_EncodeBlock((unsigned char*) enc64_pwd, (unsigned char*) sha_pwd,
+ SHA256_DIGEST_LENGTH + len + LEN_RAND_STR);
+
+
+ final_pwd = (char*) malloc (LEN_FINAL_PASSWD);
+ memcpy(final_pwd, SHA_STR, LEN_SHA_STR);
+ memcpy(final_pwd+8, enc64_pwd, LEN_ENC64);
+ final_pwd[LEN_SHA_STR + LEN_FINAL_PASSWD] = '\0';
+
+ return final_pwd;
+}
diff --git a/src/db_user.c b/src/db_user.c
new file mode 100644
index 0000000..1a851c8
--- /dev/null
+++ b/src/db_user.c
@@ -0,0 +1,32 @@
+#include <accman.h>
+#include <mysql.h>
+
+void db_insert_user(struct user u)
+{
+ MYSQL *conn;
+ char mysql_query_str[1024];
+
+ conn = mysql_init(NULL);
+
+ if (!conn) {
+ printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
+ exit(EXIT_FAILURE);
+ }
+
+ if (!mysql_real_connect(conn, "localhost", "user", "password",
+ "mailserver", 0, NULL, 0)) {
+ printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
+ exit(EXIT_FAILURE);
+ }
+
+ snprintf(mysql_query_str, 1024,
+ "insert into virtual_users(domain_id, password, email) "
+ "values (1, '%s', '%s')", u.p, u.n);
+
+ if (mysql_query(conn, mysql_query_str)) {
+ printf("Error %u: %s\n", mysql_errno(conn), mysql_error(conn));
+ exit(1);
+ }
+
+ mysql_close(conn);
+}