+/*Number bit of int type*/
+#define INT_BIT_SIZE (sizeof(int)*CHAR_BIT)
+/*Enable bit at a position*/
+#define SetBit(Array,pos) ( Array[(pos/INT_BIT_SIZE)] |= (1 << (pos%INT_BIT_SIZE)) )
+/*Check state of bit at a */
+#define TestBit(Array,pos) ( Array[(pos/INT_BIT_SIZE)] & (1 << (pos%INT_BIT_SIZE)) )
+
+int *MapIDToBitArray()
+{
+ FILE *fp;
+ char line_read[FILE_SIZE + 1];
+ line_read[FILE_SIZE] = '\0';
+ int *arrayID;
+ int max = MAX_AGENTS + AUTHD_FIRST_ID;
+ if (isChroot()) {
+ fp = fopen(AUTH_FILE, "r");
+ } else {
+ fp = fopen(KEYSFILE_PATH, "r");
+ }
+
+ if (!fp) {
+ return (NULL);
+ }
+
+ os_calloc(MAX_AGENTS/INT_BIT_SIZE + 1, sizeof(int), arrayID);
+
+ while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) {
+ char *name;
+
+ if (line_read[0] == '#') {
+ continue;
+ }
+
+ name = strchr(line_read, ' ');
+ if (name) {
+ *name = '\0';
+ int name_num=atoi(line_read);
+ /*Enable bit at ID already allocated*/
+ if (name_num >= AUTHD_FIRST_ID && name_num < max) {
+ SetBit(arrayID, (name_num-AUTHD_FIRST_ID));
+ }
+ }
+
+ }
+ fclose(fp);
+ return arrayID;
+}
+
+char *OS_AddNewAgent(const char *name, const char *ip, const char *id)
+{
+ FILE *fp;
+ os_md5 md1;
+ os_md5 md2;
+ char str1[STR_SIZE + 1];
+ char str2[STR_SIZE + 1];
+ char *muname;
+ char *finals;
+ char nid[9] = { '\0' };
+
+ srandom_init();
+ muname = getuname();
+
+ snprintf(str1, STR_SIZE, "%d%s%d%s", (int)time(0), name, (int)random(), muname);
+ snprintf(str2, STR_SIZE, "%s%s%ld", ip, id, (long int)random());
+ OS_MD5_Str(str1, md1);
+ OS_MD5_Str(str2, md2);
+
+ free(muname);
+
+ if (id == NULL) {
+ int *arrayID;
+ int i;
+ arrayID=(int *)MapIDToBitArray();
+ if (arrayID != NULL) {
+ /*Find first item in bit array which is not marked as allocated*/
+ for (i=0; i<MAX_AGENTS; i++) {
+ if(!TestBit(arrayID, i)) {
+ snprintf(nid, 8, "%d", (i + AUTHD_FIRST_ID));
+ break;
+ }
+ }
+ os_free(arrayID);
+
+ if (i == MAX_AGENTS) {
+ return (NULL);
+ }
+ }
+ else {
+ return (NULL);
+ }
+
+ id = nid;
+ }
+
+ char authentication_file[2048 + 1];
+ snprintf(authentication_file, 2048, "%s%s", DEFAULTDIR, AUTH_FILE);
+
+ fp = fopen(authentication_file, "a");
+ if (!fp) {
+ return (NULL);
+ }
+
+ os_calloc(2048, sizeof(char), finals);
+ if (ip == NULL) {
+ snprintf(finals, 2048, "%s %s any %s%s", id, name, md1, md2);
+ } else {
+ snprintf(finals, 2048, "%s %s %s %s%s", id, name, ip, md1, md2);
+ }
+ fprintf(fp, "%s\n", finals);
+
+ fclose(fp);
+ return (finals);
+}
+
+int OS_RemoveAgent(const char *u_id) {
+ FILE *fp;
+ int id_exist;
+ char *full_name;
+
+ id_exist = IDExist(u_id);
+
+ if (!id_exist)
+ return 0;
+
+ fp = fopen(isChroot() ? AUTH_FILE : KEYSFILE_PATH, "r+");
+
+ if (!fp)
+ return 0;
+
+#ifndef WIN32
+ if((chmod(AUTH_FILE, 0440)) < 0) {
+ merror("addagent: ERROR: Cannot chmod %s: %s", AUTH_FILE, strerror(errno));
+ }
+#endif
+
+#ifdef REUSE_ID
+ long fp_seek;
+ size_t fp_read;
+ char *buffer;
+ char buf_discard[OS_BUFFER_SIZE];
+ struct stat fp_stat;
+
+ if (stat(AUTH_FILE, &fp_stat) < 0) {
+ fclose(fp);
+ return 0;
+ }
+
+ buffer = malloc(fp_stat.st_size);
+ if (!buffer) {
+ fclose(fp);
+ return 0;
+ }
+
+ fsetpos(fp, &fp_pos);
+ fp_seek = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ fp_read = fread(buffer, sizeof(char), fp_seek, fp);
+ fgets(buf_discard, OS_BUFFER_SIZE - 1, fp);
+
+ if (!feof(fp))
+ fp_read += fread(buffer + fp_read, sizeof(char), fp_stat.st_size, fp);
+
+ fclose(fp);
+ fp = fopen(AUTH_FILE, "w");
+
+ if (!fp) {
+ free(buffer);
+ return 0;
+ }
+
+ fwrite(buffer, sizeof(char), fp_read, fp);