/* * get_pw.c - Part of AFD, an automatic file distribution program. * Copyright (c) 2003 - 2022 Holger Kiehl * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "afddefs.h" DESCR__S_M3 /* ** NAME ** get_pw - gets the password from password file ** ** SYNOPSIS ** int get_pw(char *uh_name, char *password, int url_conform) ** ** DESCRIPTION ** Gets the password for the given user hostname combination (uh_name) ** and stores it in password. If it does not find the combination ** it will just return an empty string. ** ** RETURN VALUES ** If found it will return the password in 'password' and SUCCESS. ** If no password is found NONE is returned. Otherwise INCORRECT ** will be returned. For both cases NONE and INCORRECT 'password' ** will return an empty string. ** ** AUTHOR ** H.Kiehl ** ** HISTORY ** 12.05.2003 H.Kiehl Created ** 22.10.2014 H.Kiehl Added possibility to have several different ** encryption methods. ** */ DESCR__E_M3 #include /* NULL */ #include /* strcat() */ #include #include /* fstat() */ #ifdef HAVE_MMAP # include /* mmap(), munmap() */ #endif #ifdef HAVE_FCNTL_H # include /* open() */ #endif #include /* close() */ #include /* External global variables. */ extern char *p_work_dir; /*############################# get_pw() ################################*/ int get_pw(char *uh_name, char *password, int url_conform) { int pwb_fd, ret; char pwb_file_name[MAX_PATH_LENGTH]; (void)strcpy(pwb_file_name, p_work_dir); (void)strcat(pwb_file_name, FIFO_DIR); (void)strcat(pwb_file_name, PWB_DATA_FILE); password[0] = '\0'; if ((pwb_fd = open(pwb_file_name, O_RDONLY)) == -1) { if (errno == ENOENT) { /* * It can be that there are absolutly no passwords in DIR_CONFIG, * so PWB_DATA_FILE is not created. */ ret = SUCCESS; } else { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to open() `%s' : %s"), pwb_file_name, strerror(errno)); ret = INCORRECT; } } else { #ifdef HAVE_STATX struct statx stat_buf; #else struct stat stat_buf; #endif #ifdef LOCK_DEBUG rlock_region(pwb_fd, 1, __FILE__, __LINE__); #else rlock_region(pwb_fd, 1); #endif #ifdef HAVE_STATX if (statx(pwb_fd, "", AT_STATX_SYNC_AS_STAT | AT_EMPTY_PATH, STATX_SIZE, &stat_buf) == -1) #else if (fstat(pwb_fd, &stat_buf) == -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, #ifdef HAVE_STATX _("Failed to statx() `%s' : %s"), #else _("Failed to fstat() `%s' : %s"), #endif pwb_file_name, strerror(errno)); ret = INCORRECT; } else { #ifdef HAVE_STATX if (stat_buf.stx_size <= AFD_WORD_OFFSET) #else if (stat_buf.st_size <= AFD_WORD_OFFSET) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Password file %s is not long enough to contain any valid data."), pwb_file_name); ret = INCORRECT; } else { char *ptr; #ifdef HAVE_MMAP if ((ptr = mmap(NULL, # ifdef HAVE_STATX stat_buf.stx_size, PROT_READ, MAP_SHARED, # else stat_buf.st_size, PROT_READ, MAP_SHARED, # endif pwb_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, # ifdef HAVE_STATX stat_buf.stx_size, PROT_READ, MAP_SHARED, # else stat_buf.st_size, PROT_READ, MAP_SHARED, # endif pwb_file_name, 0)) == (caddr_t) -1) #endif { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to mmap() `%s' : %s"), pwb_file_name, strerror(errno)); ret = INCORRECT; } else { if (*(ptr + SIZEOF_INT + 1 + 1 + 1) != CURRENT_PWB_VERSION) { system_log(ERROR_SIGN, __FILE__, __LINE__, "Incorrect password version, unable to get password."); ret = INCORRECT; } else { int digit, i, j, k, no_of_passwd; char str_hex[2]; unsigned char *tmp_ptr; struct passwd_buf *pwb; no_of_passwd = *(int *)ptr; ptr += AFD_WORD_OFFSET; pwb = (struct passwd_buf *)ptr; ret = NONE; /* In case we do not find anything. */ for (i = 0; i < no_of_passwd; i++) { if (CHECK_STRCMP(uh_name, pwb[i].uh_name) == 0) { /* Clear text. */ if ((pwb[i].passwd[0] == '$') && (pwb[i].passwd[1] == '0') && (pwb[i].passwd[2] == '$')) { (void)strcpy(password, (char *)&pwb[i].passwd[3]); ret = SUCCESS; } else if ((pwb[i].passwd[0] == '$') && (pwb[i].passwd[1] == '2') && (pwb[i].passwd[2] == '$')) { (void)xor_decrypt(&pwb[i].passwd[3], strlen((char *)&pwb[i].passwd[3]), (unsigned char *)password); } else { /* AFD internal. */ if ((pwb[i].passwd[0] == '$') && (pwb[i].passwd[1] == '1') && (pwb[i].passwd[2] == '$')) { tmp_ptr = &pwb[i].passwd[3]; } else { tmp_ptr = pwb[i].passwd; } j = 0; k = 0; digit = -1; while (*tmp_ptr != '\0') { if ((j % 2) == 0) { password[k] = *tmp_ptr + 24 - j; } else { password[k] = *tmp_ptr + 11 - j; } if (url_conform != YES) { if (password[k] == '%') { digit = 0; } else if (digit != -1) { str_hex[digit] = password[k]; if (digit == 1) { int value = -1; if ((str_hex[0] >= '0') && (str_hex[0] <= '9')) { value = (str_hex[0] - '0') * 16; } else if ((str_hex[0] >= 'a') && (str_hex[0] <= 'f')) { value = ((str_hex[0] - 'a') + 10) * 16; } else if ((str_hex[0] >= 'A') && (str_hex[0] <= 'F')) { value = ((str_hex[0] - 'A') + 10) * 16; } if (value != -1) { if ((str_hex[1] >= '0') && (str_hex[1] <= '9')) { value += (str_hex[1] - '0'); password[k] = value; k++; } else if ((str_hex[1] >= 'a') && (str_hex[1] <= 'f')) { value += ((str_hex[1] - 'a') + 10); password[k] = value; k++; } else if ((str_hex[1] >= 'A') && (str_hex[1] <= 'F')) { value += ((str_hex[1] - 'A') + 10); password[k] = value; k++; } else { password[k] = '%'; password[k + 1] = str_hex[0]; password[k + 2] = str_hex[1]; k += 3; } digit = -1; } else { password[k] = '%'; password[k + 1] = str_hex[0]; k += 2; digit = -1; } } else { digit++; } } else { k++; } } else { k++; } tmp_ptr++; j++; } password[j] = '\0'; ret = SUCCESS; } break; } } ptr -= AFD_WORD_OFFSET; } #ifdef HAVE_MMAP # ifdef HAVE_STATX if (munmap(ptr, stat_buf.stx_size) == -1) # else if (munmap(ptr, stat_buf.st_size) == -1) # endif #else if (munmap_emu(ptr) == -1) #endif { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to munmap() from `%s' : %s"), pwb_file_name, strerror(errno)); } } } } if (close(pwb_fd) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, _("close() error : %s"), strerror(errno)); } } return(ret); }