1
0
Эх сурвалжийг харах

feat: 可以读取和写入hpd文件

标签可存储hpd文件
可从hpd文件读取标签
SongZihuan 3 жил өмнө
parent
commit
6b9a6cb76a
5 өөрчлөгдсөн 557 нэмэгдсэн , 3 устгасан
  1. 1 1
      CMakeLists.txt
  2. 35 2
      main.c
  3. 19 0
      main.h
  4. 226 0
      md5.c
  5. 276 0
      passwd_file.c

+ 1 - 1
CMakeLists.txt

@@ -16,4 +16,4 @@ if (have_key)
 endif()
 
 add_definitions(-DVERSION="0.0.1" -DVERSION_INFO="H-Password, now start.")
-add_executable(H_Passwd main.c base64.c passwd.c argument.c random_passwd.c)
+add_executable(H_Passwd main.c base64.c passwd.c argument.c random_passwd.c passwd_file.c md5.c)

+ 35 - 2
main.c

@@ -14,6 +14,7 @@ struct arg_define arg[] = {
         {.ch='h', .name="help", .flat='h', .argument=no_argument},
         {.ch='s', .name="set-pw", .flat='s', .argument=no_argument},
         {.ch='g', .name="get-pw", .flat='g', .argument=no_argument},
+        {.ch='i', .name="in-file", .flat='i', .argument=no_argument},
 #ifdef INCLUDE_KEY
         {.ch='c', .name="check-key", .flat='c', .argument=must_argument},
 #endif
@@ -24,6 +25,7 @@ enum {
     set_pw,
     get_pw,
 } work = no;
+bool in_file = false;  // 是否在文件中工作
 
 void printVersion(void);
 void printHelp(void);
@@ -66,6 +68,9 @@ int main(int argc, char **argv) {
                     goto what_do;
                 work = get_pw;
                 break;
+            case 'i':
+                in_file = true;
+                break;
             case 0:
                 break;
             case '?':
@@ -105,6 +110,9 @@ int main(int argc, char **argv) {
         exit(EXIT_FAILURE);
     initBase64(key);
 
+    if (in_file)
+        initPasswdInit("passwd.hpd");
+
     bool status = false;
     if (work == set_pw)
         status = setPassWd();
@@ -179,6 +187,7 @@ bool setPassWd(void) {
     char *account = NULL;
     char *passwd = NULL;
     char *note = NULL;
+    char *in_file_name = NULL;
     char *passwd_str = NULL;
 
     READ_WORD(account, 100, "Your account", ERROR1);
@@ -192,18 +201,31 @@ bool setPassWd(void) {
 
     READ_WORD(note, 100, "Your note", ERROR3);
 
+    if (in_file)
+        READ_WORD(in_file_name, 100, "Account name", ERROR4);
+
     passwd_str = makePasswordString(account, passwd, note);
     if (passwd_str == NULL)
-        goto ERROR4;
+        goto ERROR5;
     printf("***********\n");
     printPasswdStr(account, passwd, note, passwd_str);
 
+    if (in_file) {
+        addConnect(in_file_name, passwd_str);
+        printf("The label has been written to the file. (name: %s)\n", in_file_name);
+    }
+
+    if (in_file_name != NULL)
+        free(in_file_name);
     free(account);
     free(passwd);
     free(note);
     free(passwd_str);
     return true;
 
+    ERROR5:
+    if (in_file_name != NULL)
+        free(in_file_name);
     ERROR4: free(note);
     ERROR3: free(passwd);
     ERROR2: free(account);
@@ -214,9 +236,20 @@ bool getPassWd(void) {
     char *account = NULL;
     char *passwd = NULL;
     char *note = NULL;
+    char *in_file_name = NULL;
     char *passwd_str = NULL;
 
-    READ_WORD(passwd_str, 200, "Your Label", ERROR1);
+    if (in_file) {
+        READ_WORD(in_file_name, 50, "Your Label", ERROR1);
+        passwd_str = findConnect(in_file_name);
+        if (passwd_str == NULL) {
+            fprintf(stderr, "name [%s] not found.", in_file_name);
+            free(in_file_name);
+            return false;
+        }
+        free(in_file_name);
+    } else
+        READ_WORD(passwd_str, 200, "Your Label", ERROR1);
 
     if (!getInfoFromPasswordString(passwd_str, &account, &passwd, &note))
         goto ERROR2;

+ 19 - 0
main.h

@@ -17,6 +17,21 @@
 #define VERSION_INFO "Special characters, special uses."
 #endif
 
+#define MD5_SIZE (16)
+#define MD5_STR_LEN (MD5_SIZE * 2)
+
+struct MD5_CTX {
+    unsigned int count[2];
+    unsigned int state[4];
+    unsigned char buffer[64];
+};
+
+typedef struct MD5_CTX MD5_CTX;
+
+void MD5Init(MD5_CTX *context);
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int input_len);
+void MD5Final(MD5_CTX *context,unsigned char digest[16]);
+
 char *base64Encode(char *str);
 char *base64Decode(char *code);
 void initBase64(char *key);
@@ -30,5 +45,9 @@ void printPasswdStr(char *account, char *passwd, char *note, char *passwd_str);
 void randomInit(void);
 unsigned long long getRandom(int min, int max);
 char *randomPasswd(void);
+bool initPasswdInit(const char *path_);
+void addConnect(char *name, char *passwd_str);
+char *findConnect(char *name);
+void printContent(void);
 
 #endif //H_PASSWD_MAIN_H

+ 226 - 0
md5.c

@@ -0,0 +1,226 @@
+/**
+ * 文件名: md5.c
+ * 目标: 计算文件的md5值
+ */
+
+#include "main.h"
+#include <stdio.h>
+#include <string.h>
+
+#define F(x,y,z) ((x & y) | (~x & z))
+#define G(x,y,z) ((x & z) | (y & ~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
+#define FF(a,b,c,d,x,s,ac) \
+          do { \
+          a += F(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#define GG(a,b,c,d,x,s,ac) \
+          do { \
+          a += G(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#define HH(a,b,c,d,x,s,ac) \
+          do { \
+          a += H(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#define II(a,b,c,d,x,s,ac) \
+          do { \
+          a += I(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+
+static void MD5Transform(unsigned int state[4],unsigned char block[64]);
+static void MD5Encode(unsigned char *output,const unsigned int *input,unsigned int len);
+static void MD5Decode(unsigned int *output,const unsigned char *input,unsigned int len);
+
+unsigned char PADDING[] = {
+        0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+void MD5Init(MD5_CTX *context) {
+    context->count[0] = 0;
+    context->count[1] = 0;
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+}
+
+void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int input_len) {
+    unsigned int i;
+    unsigned int index;
+    unsigned int part_len;
+
+    index = (context->count[0] >> (unsigned)3) & (unsigned)0x3F;
+    part_len = 64 - index;
+    context->count[0] += input_len << (unsigned)3;
+
+    if(context->count[0] < (input_len << (unsigned)3))
+        context->count[1]++;
+    context->count[1] += input_len >> (unsigned)29;
+
+    if(input_len >= part_len) {
+        memcpy(&context->buffer[index], input, part_len);
+        MD5Transform(context->state, context->buffer);
+
+        for(i = part_len; i + 64 <= input_len; i+=64)
+            MD5Transform(context->state, &input[i]);
+
+        index = 0;
+    }
+    else
+        i = 0;
+    memcpy(&context->buffer[index], &input[i], input_len - i);
+}
+
+void MD5Final(MD5_CTX *context, unsigned char digest[16]) {
+    unsigned int index;
+    unsigned int pad_len;
+    unsigned char bits[8];
+
+    index = (context->count[0] >> (unsigned)3) & (unsigned)0x3F;
+    pad_len = (index < 56) ? (56 - index) : (120 - index);
+    MD5Encode(bits, context->count, 8);
+    MD5Update(context, PADDING, pad_len);
+    MD5Update(context, bits, 8);
+    MD5Encode(digest, context->state, 16);
+}
+
+static void MD5Encode(unsigned char *output,const unsigned int *input, unsigned int len) {
+    unsigned int i = 0;
+    unsigned int j = 0;
+
+    while(j < len)
+    {
+        output[j] = input[i] & (unsigned)0xFF;
+        output[j+1] = (input[i] >> (unsigned)8) & (unsigned)0xFF;
+        output[j+2] = (input[i] >> (unsigned)16) & (unsigned)0xFF;
+        output[j+3] = (input[i] >> (unsigned)24) & (unsigned)0xFF;
+        i++;
+        j += 4;
+    }
+}
+
+static void MD5Decode(unsigned int *output, const unsigned char *input, unsigned int len) {
+    for (unsigned int i=0, j=0; j < len; i++, j+=4) {
+        output[i] = (input[j]) |
+                    (input[j+1] << (unsigned)8) |
+                    (input[j+2] << (unsigned)16) |
+                    (input[j+3] << (unsigned)24);
+    }
+}
+
+static void MD5Transform(unsigned int state[4], unsigned char block[64]) {
+    unsigned int a = state[0];
+    unsigned int b = state[1];
+    unsigned int c = state[2];
+    unsigned int d = state[3];
+    unsigned int x[64];
+
+    MD5Decode(x,block,64);
+
+    FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+    FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+    FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+    FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+    FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+    FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+    FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+    FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+    FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+    FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+    FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+    FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+    FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+    FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+    FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+    FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+    /* Round 2 */
+    GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+    GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+    GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+    GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+    GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+    GG(d, a, b, c, x[10], 9,  0x2441453); /* 22 */
+    GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+    GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+    GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+    GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+    GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+    GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+    GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+    GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+    GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+    /* Round 3 */
+    HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+    HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+    HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+    HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+    HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+    HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+    HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+    HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+    HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+    HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+    HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+    HH(b, c, d, a, x[ 6], 23,  0x4881d05); /* 44 */
+    HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+    HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+    HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+    HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+    /* Round 4 */
+    II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+    II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+    II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+    II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+    II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+    II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+    II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+    II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+    II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+    II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+    II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+    II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+    II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+    II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+    II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+    II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+}
+
+
+int getStringMd5(const char *string, char *md5str) {
+    unsigned char md5_value[MD5_SIZE];
+    MD5_CTX md5;
+
+    MD5Init(&md5);
+    MD5Update(&md5, (unsigned char *)string, strlen((char *)string));
+    MD5Final(&md5, md5_value);
+
+    for(int i = 0; i < MD5_SIZE; i++)
+        snprintf(md5str + i * 2, 2 + 1, "%02x", md5_value[i]);
+
+    return 0;
+}

+ 276 - 0
passwd_file.c

@@ -0,0 +1,276 @@
+#include "main.h"
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+typedef uint64_t h_size_t;
+typedef char h_char;
+const char *path = NULL;  // 文件地址
+
+struct Content {
+    h_char *name;
+    h_char *passwd_str;
+    struct Content *next;
+};  // 链表
+
+struct Content *content = NULL;
+h_size_t content_size = 0;
+
+static size_t fread_str(h_char *dest, size_t size, FILE *fp) {
+    return fread(dest, sizeof(h_char), size, fp);
+}
+
+static size_t fwrite_str(h_char *dest, size_t size, FILE *fp) {
+    return fwrite(dest, sizeof(h_char), size, fp);
+}
+
+static size_t fread_size_t(h_size_t *dest, FILE *fp) {
+    return fread(dest, sizeof(h_size_t), 1, fp);
+}
+
+static size_t fwrite_size_t(h_size_t dest, FILE *fp) {
+    return fwrite(&dest, sizeof(h_size_t), 1, fp);
+}
+
+static h_char get_fread_char(FILE *fp) {
+    h_char ch;
+    size_t ret = fread(&ch, sizeof(h_char), 1, fp);
+    if (ret != 1)
+        return 0;
+    return ch;
+}
+
+static bool put_fwrite_enter(FILE *fp) {
+    static char const ch = '\n';
+    return fwrite(&ch, sizeof(h_char), 1, fp) == 1;
+}
+
+static bool readFileHead(FILE *fp, h_char *file_md5) {
+    size_t ret;
+    ret = fread_str(file_md5, MD5_STR_LEN + 1, fp);  // 先读取md5码, 包括NUL
+    if (ret < MD5_STR_LEN + 1)
+        return false;
+
+    if (fread_size_t(&content_size, fp) != 1)
+        return false;
+
+    if (get_fread_char(fp) != '\n')
+        return false;
+
+    return true;
+}
+
+static bool writeFileHead(FILE *fp, h_char *md5str) {
+    size_t ret;
+    ret = fwrite_str(md5str, MD5_STR_LEN + 1, fp);  // 写入NUL
+    if (ret < MD5_STR_LEN + 1)
+        return false;
+
+    if (fwrite_size_t(content_size, fp) != 1)
+        return false;
+
+    if (!put_fwrite_enter(fp))
+        return false;
+
+    return true;
+}
+
+static bool readFileInfo(FILE *fp, struct Content *con) {
+    size_t ret;
+    h_size_t name_size;
+    h_size_t passwd_str_size;
+    h_char *name = NULL;
+    h_char *passwd_str = NULL;
+
+    if (fread_size_t(&name_size, fp) != 1)
+        return false;
+
+    if (fread_size_t(&passwd_str_size, fp) != 1)
+        return false;
+
+    name = calloc(name_size, sizeof(h_char));  // 包含 NUL
+    passwd_str = calloc(passwd_str_size, sizeof(h_char));  // 包含 NUL
+
+    ret = fread_str(name, name_size, fp);
+    if (ret < name_size)
+        goto error;
+
+    ret = fread_str(passwd_str, passwd_str_size, fp);
+    if (ret < name_size)
+        goto error;
+
+    if (get_fread_char(fp) != '\n') {
+    error:
+        free(name);
+        free(passwd_str);
+        return false;
+    }
+
+    con->name = name;
+    con->passwd_str = passwd_str;
+    return true;
+}
+
+static bool writeFileInfo(FILE *fp, struct Content *con) {
+    size_t ret;
+    h_char *name = con->name;
+    h_char *passwd_str = con->passwd_str;
+    h_size_t passwd_str_size = strlen((char *)passwd_str);
+    h_size_t name_size = strlen((char *)name);
+
+    if (fwrite_size_t(name_size + 1, fp) != 1)  // 写入NUL
+        return false;
+
+    if (fwrite_size_t(passwd_str_size + 1, fp) != 1)
+        return false;
+
+    ret = fwrite_str(name, name_size + 1, fp);  // 写入NUL
+    if (ret < name_size)
+        goto error;
+
+    ret = fwrite_str(passwd_str, passwd_str_size + 1, fp);
+    if (ret < name_size)
+        goto error;
+
+    if (!put_fwrite_enter(fp))
+        goto error;
+
+    return true;
+    error: return false;
+}
+
+static void freeContent(void) {
+    struct Content *con = content;
+    for (int i = 0; i < content_size; i++) {
+        struct Content *tmp = con->next;
+        free(con->name);
+        free(con->passwd_str);
+        free(con);
+        con = tmp;
+    }
+    content_size = 0;
+    content = NULL;
+}
+
+static h_char *getContentMD5(void) {
+    h_char *md5str = calloc(MD5_STR_LEN + 1, sizeof(h_char));
+    h_char md5_value[MD5_SIZE];
+    struct Content *con = content;
+    MD5_CTX md5;
+
+    MD5Init(&md5);
+    for (int i = 0; i < content_size; i++, con = con->next) {
+        h_char *tmp = calloc(strlen((char *)con->name) + strlen((char *)con->passwd_str) + 1, sizeof(h_char));
+        strcpy((char *)tmp, (char *)con->name);
+        strcat((char *)tmp, (char *)con->passwd_str);
+        MD5Update(&md5, (unsigned char *)tmp, strlen((char *)tmp));
+        free(tmp);
+    }
+    MD5Final(&md5, (unsigned char *)md5_value);
+
+    for(int i = 0; i < MD5_SIZE; i++)
+        snprintf((char *)md5str + i * 2, 2 + 1, "%02x", md5_value[i]);
+    return md5str;
+}
+
+static void atEnd(void) {  // 写入数据
+    FILE *fp = fopen(path, "wb");
+    h_char *md5 = getContentMD5();
+
+    if (!writeFileHead(fp, md5))
+        goto error;
+
+    struct Content *con = content;
+    for (int i = 0; i < content_size; i++, con = con->next) {
+        if (!writeFileInfo(fp, con))
+            goto error;
+    }
+
+    if (!put_fwrite_enter(fp))
+        goto error;
+
+    free(md5);
+    fclose(fp);
+    freeContent();
+    return;
+
+    error:
+    free(md5);
+    fclose(fp);
+    freeContent();
+    fprintf(stderr, "File writing error occurred.\n");
+}
+
+void printContent(void) {
+    struct Content *con = content;
+    for (int i = 0; i < content_size; i++, con = con->next)
+        printf("%d. name: %s, label: %s\n", i, con->name, con->passwd_str);
+}
+
+bool initPasswdInit(const char *path_) {
+    h_char file_md5[MD5_STR_LEN + 1] = {0};
+    h_char *get_md5;
+    FILE *fp = fopen(path_, "rb");
+    path = path_;
+    if (fp == NULL) {
+        content_size = 0;
+        content = NULL;
+        goto re;
+    }
+
+    if (!readFileHead(fp, file_md5))
+        goto error;
+
+    struct Content **con = &content;
+    for (int i = 0; i < content_size; i++, con = &((*con)->next)) {
+        *con = calloc(1, sizeof(struct Content));
+        if (!readFileInfo(fp, *con))
+            goto error;
+    }
+
+    if (get_fread_char(fp) != '\n')
+        goto error;
+
+    get_md5 = getContentMD5();
+    if (strcmp((char *)get_md5, (char *)file_md5) != 0)
+        goto error;
+
+    fclose(fp);
+
+    re:
+    atexit(atEnd);
+    return true;
+
+    error:
+    freeContent();
+    fclose(fp);
+    return false;
+}
+
+void addConnect(char *name, char *passwd_str) {
+    h_char *name_cp = calloc(strlen(name) + 1, sizeof(h_char));
+    h_char *passwd_str_cp = calloc(strlen(passwd_str) + 1, sizeof(h_char));
+    strcpy(name_cp, name);
+    strcpy(passwd_str_cp, passwd_str);
+
+    struct Content *new = calloc(1, sizeof(struct Content));
+    new->name = name_cp;
+    new->passwd_str = passwd_str_cp;
+    new->next = content;
+    content = new;
+    content_size++;
+}
+
+char *findConnect(char *name) {
+    struct Content *con = content;
+    for (int i = 0; i < content_size; i++, con = content->next) {
+        if (!strcmp(con->name, name)) {
+            char *re = calloc(strlen(con->passwd_str) + 1, sizeof(char));
+            strcpy(re, con->passwd_str);
+            return re;
+        }
+    }
+    return NULL;
+}