Aqwin *aqwin_open(const char *cfg) { Aqwin *win; aqwin_param *p; if ((p = parse_cfg(cfg)) == NULL) { complain("aqwin_open: invalid config \"%s\"\n", cfg); return NULL; } print_params(p); win = aqwin_create(p); aqwin_param_free(p); return win; }
zt_cfg_ty * zt_cfg_ini(char *file, int opts ) { zt_cfg_ty *cfg = zt_cfg_new(&vtbl); cfg->filename = strdup(file); cfg->opts = opts; if (parse_cfg(cfg) < 0) { free(cfg->filename); free(cfg); cfg = NULL; } return cfg; }
int main (int argc, char *argv[]) { int count = 0; arc_t *arc; if (argc < 2) { printf ("Usage: %s cfgfile\n\n", argv[0]); exit (1); } arc = arc_new (outfile, (arc_sig_t *)signature); if (arc == NULL) { printf ("*** Error: failed to create empty archive!\n"); exit (42); } count = parse_cfg (argv[1], arc); printf ("Config file \"%s\" contains %d items.\n", argv[1], count); arc_store (arc); return (0); }
int32_t main(int argc, char *argv[]) { int32_t opt; uint32_t n; char *cfgfile = NULL; struct stat sb; struct bitcoind *b, *sigfrom; struct psj *psj; struct sigaction act; struct config *cfg; cfg = malloc(sizeof(*cfg)); if (cfg == NULL) { APPLOG(LOG_CRIT, "cfg malloc failed"); exit(255); } while ((opt = getopt(argc, argv, "hs:c:")) != -1) { switch(opt) { case 'c': cfgfile = optarg; break; case 's': cfg->force_pid = atoi(optarg); break; default: case 'h': usage(); } } APPLOG(LOG_NOTICE, "psj_sigmon v0.5 starting up"); /* config file parsing */ if (parse_cfg(cfgfile ? cfgfile : "config.cfg", cfg)) { APPLOG(LOG_CRIT, "parse_cfg error"); exit(255); } if (cfg->bitcoind_used == 0) { APPLOG(LOG_CRIT, "no bitcoind defined, exiting"); exit(EXIT_SUCCESS); } if (cfg->psj_used == 0) { APPLOG(LOG_CRIT, "no psj defined, exiting"); exit(EXIT_SUCCESS); } if (cfg->pidfile) { if (write_pidfile(cfg->pidfile) != 0) { APPLOG(LOG_CRIT, "write_pidfile failed"); exit(255); } } if (cfg->daemon) { APPLOG(LOG_NOTICE, "daemonising, you will hear no more from me"); if (daemon(false, false) == -1) { APPLOG(LOG_CRIT, "except daemonising failed.. dying"); exit(255); } cfg->daemon_done = true; } /* install signal handlers */ act.sa_flags = SA_SIGINFO; act.sa_sigaction = &sig_handler; sigaction(SIGUSR1, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); while(1) { select(0, NULL, NULL, NULL, NULL); APPLOG(LOG_INFO, "got signal %d, from pid %d", sig, pid); /* handle INT and TERM */ if (sig == SIGINT || sig == SIGTERM) /* break out of loop and exit gracefully */ break; /* ignore non-USR1 */ if (sig != SIGUSR1) continue; if (cfg->force_pid) { pid = cfg->force_pid; APPLOG(LOG_DEBUG, "forcing sending-pid to %d", pid); } sigfrom = NULL; for(n = 0 ; n < cfg->bitcoind_used ; n++) { /* check if pid == this bitcoind's pid */ b = cfg->bitcoind_list[n]; if (stat(b->pidfile, &sb) == -1) { APPLOG(LOG_WARNING, "%s on stat of %s", strerror(errno), b->pidfile); continue; } if (sb.st_mtime > b->pidfile_mtime) { /* refresh what we think the pid is of this * bitcoind */ b->pid = read_pidfile(b->pidfile); b->pidfile_mtime = sb.st_mtime; APPLOG(LOG_DEBUG, "%s changed: new pid is %u", b->pidfile, b->pid); } if (b->pid == pid) { APPLOG(LOG_DEBUG, "signal matches %s (%s)", b->pidfile, b->name); sigfrom = b; break; } } if (sigfrom == NULL) { APPLOG(LOG_WARNING, "signal not from a recognised pid"); continue; } /* tell each psj about b->name */ for(n = 0 ; n < cfg->psj_used ; n++) { psj = cfg->psj_list[n]; APPLOG(LOG_INFO, "notifying %s of signal", psj->hostport); poke_psj(cfg,psj, b); } } APPLOG(LOG_INFO, "shutting down, removing pidfile"); unlink(cfg->pidfile); /* we're lazy, the kernel will clean up our memory, sorry valgrind :p */ return EXIT_SUCCESS; }
PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) { int retval, rc; const char *user = NULL; const char *password = NULL; char otp[MAX_TOKEN_ID_LEN + TOKEN_OTP_LEN + 1] = { 0 }; char otp_id[MAX_TOKEN_ID_LEN + 1] = { 0 }; int password_len = 0; int skip_bytes = 0; int valid_token = 0; struct pam_conv *conv; struct pam_message *pmsg[1], msg[1]; struct pam_response *resp; int nargs = 1; ykclient_t *ykc = NULL; struct cfg cfg_st; struct cfg *cfg = &cfg_st; /* for DBG macro */ parse_cfg (flags, argc, argv, cfg); retval = pam_get_user (pamh, &user, NULL); if (retval != PAM_SUCCESS) { DBG (("get user returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("get user returned: %s", user)); if (cfg->mode == CHRESP) { #if HAVE_LIBYKPERS_1 return do_challenge_response(pamh, cfg, user); #else DBG (("no support for challenge/response")); retval = PAM_AUTH_ERR; goto done; #endif } if (cfg->try_first_pass || cfg->use_first_pass) { retval = pam_get_item (pamh, PAM_AUTHTOK, (const void **) &password); if (retval != PAM_SUCCESS) { DBG (("get password returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("get password returned: %s", password)); } if (cfg->use_first_pass && password == NULL) { DBG (("use_first_pass set and no password, giving up")); retval = PAM_AUTH_ERR; goto done; } rc = ykclient_init (&ykc); if (rc != YKCLIENT_OK) { DBG (("ykclient_init() failed (%d): %s", rc, ykclient_strerror (rc))); retval = PAM_AUTHINFO_UNAVAIL; goto done; } rc = ykclient_set_client_b64 (ykc, cfg->client_id, cfg->client_key); if (rc != YKCLIENT_OK) { DBG (("ykclient_set_client_b64() failed (%d): %s", rc, ykclient_strerror (rc))); retval = PAM_AUTHINFO_UNAVAIL; goto done; } if (cfg->capath) ykclient_set_ca_path (ykc, cfg->capath); if (cfg->url) ykclient_set_url_template (ykc, cfg->url); if (password == NULL) { retval = pam_get_item (pamh, PAM_CONV, (const void **) &conv); if (retval != PAM_SUCCESS) { DBG (("get conv returned error: %s", pam_strerror (pamh, retval))); goto done; } pmsg[0] = &msg[0]; { const char *query_template = "Yubikey for `%s': "; size_t len = strlen (query_template) + strlen (user); size_t wrote; msg[0].msg = malloc (len); if (!msg[0].msg) { retval = PAM_BUF_ERR; goto done; } wrote = snprintf ((char *) msg[0].msg, len, query_template, user); if (wrote < 0 || wrote >= len) { retval = PAM_BUF_ERR; goto done; } } msg[0].msg_style = cfg->verbose_otp ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; resp = NULL; retval = conv->conv (nargs, (const struct pam_message **) pmsg, &resp, conv->appdata_ptr); free ((char *) msg[0].msg); if (retval != PAM_SUCCESS) { DBG (("conv returned error: %s", pam_strerror (pamh, retval))); goto done; } if (resp->resp == NULL) { DBG (("conv returned NULL passwd?")); goto done; } DBG (("conv returned %i bytes", strlen(resp->resp))); password = resp->resp; } password_len = strlen (password); if (password_len < (cfg->token_id_length + TOKEN_OTP_LEN)) { DBG (("OTP too short to be considered : %i < %i", password_len, (cfg->token_id_length + TOKEN_OTP_LEN))); retval = PAM_AUTH_ERR; goto done; } /* In case the input was systempassword+YubiKeyOTP, we want to skip over "systempassword" when copying the token_id and OTP to separate buffers */ skip_bytes = password_len - (cfg->token_id_length + TOKEN_OTP_LEN); DBG (("Skipping first %i bytes. Length is %i, token_id set to %i and token OTP always %i.", skip_bytes, password_len, cfg->token_id_length, TOKEN_OTP_LEN)); /* Copy full YubiKey output (public ID + OTP) into otp */ strncpy (otp, password + skip_bytes, sizeof (otp) - 1); /* Copy only public ID into otp_id. Destination buffer is zeroed. */ strncpy (otp_id, password + skip_bytes, cfg->token_id_length); DBG (("OTP: %s ID: %s ", otp, otp_id)); /* user entered their system password followed by generated OTP? */ if (password_len > TOKEN_OTP_LEN + cfg->token_id_length) { char *onlypasswd = strdup (password); onlypasswd[password_len - (TOKEN_OTP_LEN + cfg->token_id_length)] = '\0'; DBG (("Extracted a probable system password entered before the OTP - " "setting item PAM_AUTHTOK")); retval = pam_set_item (pamh, PAM_AUTHTOK, onlypasswd); free (onlypasswd); if (retval != PAM_SUCCESS) { DBG (("set_item returned error: %s", pam_strerror (pamh, retval))); goto done; } } else password = NULL; rc = ykclient_request (ykc, otp); DBG (("ykclient return value (%d): %s", rc, ykclient_strerror (rc))); switch (rc) { case YKCLIENT_OK: break; case YKCLIENT_BAD_OTP: case YKCLIENT_REPLAYED_OTP: retval = PAM_AUTH_ERR; goto done; default: retval = PAM_AUTHINFO_UNAVAIL; goto done; } /* authorize the user with supplied token id */ if (cfg->ldapserver != NULL || cfg->ldap_uri != NULL) valid_token = authorize_user_token_ldap (cfg, user, otp_id); else valid_token = authorize_user_token (cfg, user, otp_id); if (valid_token == 0) { DBG (("Yubikey not authorized to login as user")); retval = PAM_AUTHINFO_UNAVAIL; goto done; } retval = PAM_SUCCESS; done: if (ykc) ykclient_done (&ykc); if (cfg->alwaysok && retval != PAM_SUCCESS) { DBG (("alwaysok needed (otherwise return with %d)", retval)); retval = PAM_SUCCESS; } DBG (("done. [%s]", pam_strerror (pamh, retval))); pam_set_data (pamh, "yubico_setcred_return", (void*) (intptr_t) retval, NULL); return retval; }
/** * Sets the config. * * @param cfg The config object with the data to draw, see * http://www.wesnoth.org/wiki/GUICanvasWML for * more information. */ void set_cfg(const config& cfg) { parse_cfg(cfg); }
int main (int argc, char ** argv) { struct dirent ** plugin_list; unsigned int i; int plugin_count; char * plugin_dir = NULL; char * basename = NULL; if (argc == 1) { usage(argv[0]); return EXIT_FAILURE; } for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-l")) { if (argc > i + 1) { plugin_dir = (char *) malloc(strlen(argv[i + 1]) + 1); strcpy(plugin_dir, argv[i + 1]); i++; } } else if (!strcmp(argv[i], "-x")) { if (argc > i + 1) { basename = (char *) malloc(strlen(argv[i + 1]) + 1); strcpy(basename, argv[i + 1]); i++; } else { usage(argv[0]); free(plugin_dir); return EXIT_FAILURE; } } else { usage(argv[0]); free(basename); free(plugin_dir); return EXIT_FAILURE; } } if (plugin_dir == NULL) { plugin_dir = (char *) malloc(strlen(PLUGINDIR) + 1); strcpy(plugin_dir, PLUGINDIR); } if (!basename) { plugin_count = scandir(plugin_dir, &plugin_list, 0, alphasort); if (plugin_count < 0) { perror("scandir"); free(plugin_dir); return EXIT_FAILURE; } for (i = 0; i < plugin_count; i++) { if (fnmatch("*.cfg", plugin_list[i]->d_name, 0) == 0) { plugin_list[i]->d_name[strlen(plugin_list[i]->d_name) - 4] = 0; printf("%s\n", plugin_list[i]->d_name); } free(plugin_list[i]); } free(plugin_list); } else { char plugin_path[strlen(plugin_dir) + strlen(basename) + 5]; struct stat plugin_stat; sprintf(plugin_path, "%s/%s.cfg", plugin_dir, basename); if (stat(plugin_path, &plugin_stat) == -1) { perror("stat"); } else { PluginParam * plugin_param = parse_cfg(plugin_path); if (plugin_param == NULL) { printf("error parsing %s\n", plugin_path); } else { sprintf(plugin_path, "%s/%s.so", plugin_dir, basename); if (stat(plugin_path, &plugin_stat) == -1) { perror("stat"); } else { void * plugin_handle = dlopen(plugin_path, RTLD_NOW); if (plugin_handle == NULL) { printf("%s\n", dlerror()); } else { PluginExec plugin_exec = (PluginExec) dlsym(plugin_handle, "plugin_exec"); if (plugin_exec == NULL) { printf("%s\n", dlerror()); } else { PluginParam * next = plugin_param->next; plugin_exec(plugin_param); while (plugin_param != NULL) { free(plugin_param->val); free(plugin_param); if (next) { plugin_param = next; next = plugin_param->next; } else { plugin_param = NULL; } } dlclose(plugin_handle); if (fb != -1) { ioctl(fb, AVIA_GT_GV_HIDE); close(fb); } if (rc != -1) { close(rc); } if (lcd != -1) { close(lcd); } } } } } } free(basename); } free(plugin_dir); if (handles != NULL) { struct handles_s * cur = handles->first; struct handles_s * next = handles->first->next; while (cur != NULL) { printf("unloading %s\n", cur->path); dlclose(cur->handle); free(cur->path); free(cur); if (next != NULL) { cur = next; next = cur->next; } else { cur = NULL; } } } return EXIT_SUCCESS; }
Postagger::Postagger(ltp::utility::ConfigParser & cfg) : model(0), decoder(0) { parse_cfg(cfg); }
PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) { int retval, rc; dynalogin_client_t *session; const char *user = NULL; const char *password = NULL; char otp[MAX_OTP_LEN + 1]; int password_len = 0; struct pam_conv *conv; struct pam_message *pmsg[1], msg[1]; struct pam_response *resp; int nargs = 1; struct cfg cfg; char *query_prompt = NULL; char *onlypasswd = strdup (""); /* empty passwords never match */ parse_cfg (flags, argc, argv, &cfg); retval = pam_get_user (pamh, &user, NULL); if (retval != PAM_SUCCESS) { DBG (("get user returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("get user returned: %s", user)); if (cfg.try_first_pass || cfg.use_first_pass) { retval = pam_get_item (pamh, PAM_AUTHTOK, (const void **) &password); if (retval != PAM_SUCCESS) { DBG (("get password returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("get password returned: %s", password)); } if (cfg.use_first_pass && password == NULL) { DBG (("use_first_pass set and no password, giving up")); retval = PAM_AUTH_ERR; goto done; } session = dynalogin_session_start(cfg.server, cfg.port, cfg.ca_file); if (session == NULL) { DBG (("dynalogin_session_start() failed")); retval = PAM_AUTHINFO_UNAVAIL; goto done; } if (password == NULL) { retval = pam_get_item (pamh, PAM_CONV, (const void **) &conv); if (retval != PAM_SUCCESS) { DBG (("get conv returned error: %s", pam_strerror (pamh, retval))); goto done; } pmsg[0] = &msg[0]; { const char *query_template = "One-time password (OATH) for `%s': "; size_t len = strlen (query_template) + strlen (user); size_t wrote; query_prompt = malloc (len); if (!query_prompt) { retval = PAM_BUF_ERR; goto done; } wrote = snprintf (query_prompt, len, query_template, user); if (wrote < 0 || wrote >= len) { retval = PAM_BUF_ERR; goto done; } msg[0].msg = query_prompt; } msg[0].msg_style = PAM_PROMPT_ECHO_OFF; resp = NULL; retval = conv->conv (nargs, (const struct pam_message **) pmsg, &resp, conv->appdata_ptr); free (query_prompt); query_prompt = NULL; if (retval != PAM_SUCCESS) { DBG (("conv returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("conv returned: %s", resp->resp)); password = resp->resp; } if (password) password_len = strlen (password); else { DBG (("Could not read password")); retval = PAM_AUTH_ERR; goto done; } if (password_len < MIN_OTP_LEN) { DBG (("OTP too short: %s", password)); retval = PAM_AUTH_ERR; goto done; } else if (password_len > MAX_OTP_LEN) { DBG (("OTP too long: %s", password)); retval = PAM_AUTH_ERR; goto done; } else { strcpy (otp, password); password = NULL; } DBG (("OTP: %s", otp ? otp : "(null)")); { time_t last_otp; rc = dynalogin_session_authenticate( session, user, cfg.scheme, otp); DBG (("authenticate rc %d", rc)); } if (rc != 0) { DBG (("One-time password not authorized to login as user '%s'", user)); retval = PAM_AUTH_ERR; goto done; } retval = PAM_SUCCESS; done: dynalogin_session_stop(session); free (query_prompt); free (onlypasswd); if (cfg.alwaysok && retval != PAM_SUCCESS) { DBG (("alwaysok needed (otherwise return with %d)", retval)); retval = PAM_SUCCESS; } DBG (("done. [%s]", pam_strerror (pamh, retval))); return retval; }
static int fbsplash_load() { fb_fd = -1; last_pos = 0; /* Kick start our TTF library */ if (TTF_Init() < 0) { printk("Couldn't initialise TTF.\n"); } /* Find out the FB size */ if (get_fb_settings(0)) { printk("Couldn't get fb settings.\n"); return 1; } arg_vc = get_active_vt(); arg_mode = 's'; /* Read theme config file */ if (arg_theme == NULL) arg_theme = DEFAULT_THEME; config_file = get_cfg_file(arg_theme); if (!config_file) { printk("Couldn't load config file %s.\n", arg_theme); return 1; } else printk("Using configuration file %s.\n", config_file); parse_cfg(config_file); /* Prime the font cache with glyphs so we don't need to allocate them later */ TTF_PrimeCache("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 -.", global_font, TTF_STYLE_NORMAL); boot_message = rendermessage; fb_fd = open_fb(); if (fb_fd == -1) { printk("Couldn't open framebuffer device.\n"); return 1; } if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) set_directcolor_cmap(fb_fd); fbsplash_fd = open(SPLASH_DEV, O_WRONLY); /* Don't worry if it fails */ do_getpic(FB_SPLASH_IO_ORIG_USER, 1, 'v'); /* Don't worry if it fails */ if (do_getpic(FB_SPLASH_IO_ORIG_USER, 0, 's') == -1) no_silent_image = 1; /* We do care if this fails. */ /* These next two touch the kernel and are needed even for silent mode, to * get the colours right (even on 32-bit depth displays funnily enough. */ do_config(FB_SPLASH_IO_ORIG_USER); cmd_setstate(1, FB_SPLASH_IO_ORIG_USER); /* copy the silent pic to base_image for safe keeping */ if (!no_silent_image) { base_image_size = silent_img.width * silent_img.height * (silent_img.depth >> 3); base_image = malloc(base_image_size); if (!base_image) { printk("Couldn't get enough memory for framebuffer image.\n"); return 1; } memcpy(base_image, (void*)silent_img.data, base_image_size); }
PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) { int retval, rc; const char *user = NULL; const char *password = NULL; char otp[MAX_OTP_LEN + 1]; int password_len = 0; struct pam_conv *conv; struct pam_message *pmsg[1], msg[1]; struct pam_response *resp; int nargs = 1; struct cfg cfg; char *query_prompt = NULL; char *onlypasswd = strdup (""); /* empty passwords never match */ parse_cfg (flags, argc, argv, &cfg); retval = pam_get_user (pamh, &user, NULL); if (retval != PAM_SUCCESS) { DBG (("get user returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("get user returned: %s", user)); if (cfg.try_first_pass || cfg.use_first_pass) { retval = pam_get_item (pamh, PAM_AUTHTOK, (const void **) &password); if (retval != PAM_SUCCESS) { DBG (("get password returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("get password returned: %s", password)); } if (cfg.use_first_pass && password == NULL) { DBG (("use_first_pass set and no password, giving up")); retval = PAM_AUTH_ERR; goto done; } rc = oath_init (); if (rc != OATH_OK) { DBG (("oath_init() failed (%d)", rc)); retval = PAM_AUTHINFO_UNAVAIL; goto done; } if (password == NULL) { retval = pam_get_item (pamh, PAM_CONV, (const void **) &conv); if (retval != PAM_SUCCESS) { DBG (("get conv returned error: %s", pam_strerror (pamh, retval))); goto done; } pmsg[0] = &msg[0]; { const char *query_template = "One-time password (OATH) for `%s': "; size_t len = strlen (query_template) + strlen (user); size_t wrote; query_prompt = malloc (len); if (!query_prompt) { retval = PAM_BUF_ERR; goto done; } wrote = snprintf (query_prompt, len, query_template, user); if (wrote < 0 || wrote >= len) { retval = PAM_BUF_ERR; goto done; } msg[0].msg = query_prompt; } msg[0].msg_style = PAM_PROMPT_ECHO_OFF; resp = NULL; retval = conv->conv (nargs, (const struct pam_message **) pmsg, &resp, conv->appdata_ptr); free (query_prompt); query_prompt = NULL; if (retval != PAM_SUCCESS) { DBG (("conv returned error: %s", pam_strerror (pamh, retval))); goto done; } DBG (("conv returned: %s", resp->resp)); password = resp->resp; } if (password) password_len = strlen (password); else { DBG (("Could not read password")); retval = PAM_AUTH_ERR; goto done; } if (password_len < MIN_OTP_LEN) { DBG (("OTP too short: %s", password)); retval = PAM_AUTH_ERR; goto done; } else if (cfg.digits != 0 && password_len < cfg.digits) { DBG (("OTP shorter than digits=%d: %s", cfg.digits, password)); retval = PAM_AUTH_ERR; goto done; } else if (cfg.digits == 0 && password_len > MAX_OTP_LEN) { DBG (("OTP too long (and no digits=): %s", password)); retval = PAM_AUTH_ERR; goto done; } else if (cfg.digits != 0 && password_len > cfg.digits) { free (onlypasswd); onlypasswd = strdup (password); /* user entered their system password followed by generated OTP? */ onlypasswd[password_len - cfg.digits] = '\0'; DBG (("Password: %s ", onlypasswd)); memcpy (otp, password + password_len - cfg.digits, cfg.digits); otp[cfg.digits] = '\0'; retval = pam_set_item (pamh, PAM_AUTHTOK, onlypasswd); if (retval != PAM_SUCCESS) { DBG (("set_item returned error: %s", pam_strerror (pamh, retval))); goto done; } } else { strcpy (otp, password); password = NULL; } DBG (("OTP: %s", otp ? otp : "(null)")); { time_t last_otp; rc = oath_authenticate_usersfile (cfg.usersfile, user, otp, cfg.window, onlypasswd, &last_otp); DBG (("authenticate rc %d (%s: %s) last otp %s", rc, oath_strerror_name (rc) ? oath_strerror_name (rc) : "UNKNOWN", oath_strerror (rc), ctime (&last_otp))); } if (rc != OATH_OK) { DBG (("One-time password not authorized to login as user '%s'", user)); retval = PAM_AUTH_ERR; goto done; } retval = PAM_SUCCESS; done: oath_done (); free (query_prompt); free (onlypasswd); if (cfg.alwaysok && retval != PAM_SUCCESS) { DBG (("alwaysok needed (otherwise return with %d)", retval)); retval = PAM_SUCCESS; } DBG (("done. [%s]", pam_strerror (pamh, retval))); return retval; }
/* PAM entry point for authentication verification */ int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) { struct passwd *pw = NULL, pw_s; const char *user = NULL; cfg_t cfg_st; cfg_t *cfg = &cfg_st; char buffer[BUFSIZE]; char *buf = NULL; char *authfile_dir; int authfile_dir_len; int pgu_ret, gpn_ret; int retval = PAM_IGNORE; device_t *devices = NULL; unsigned n_devices = 0; parse_cfg(flags, argc, argv, cfg); if (!cfg->origin) { if (!strcpy(buffer, DEFAULT_ORIGIN_PREFIX)) { DBG(("Unable to create origin string")); goto done; } if (gethostname (buffer + strlen(DEFAULT_ORIGIN_PREFIX), BUFSIZE - strlen(DEFAULT_ORIGIN_PREFIX)) == -1) { DBG(("Unable to get host name")); goto done; } DBG(("Origin not specified, using \"%s\"", buffer)); cfg->origin = strdup(buffer); } if (!cfg->origin) { DBG(("Unable to allocate memory")); goto done; } if (!cfg->appid) { DBG(("Appid not specified, using the same value of origin (%s)", cfg->origin)); cfg->appid = strdup(cfg->origin); } if (!cfg->appid) { DBG(("Unable to allocate memory")); goto done; } if (cfg->max_devs == 0) { DBG(("Maximum devices number not set. Using default (%d)", MAX_DEVS)); cfg->max_devs = MAX_DEVS; } devices = malloc(sizeof(device_t) * cfg->max_devs); if (!devices) { DBG(("Unable to allocate memory")); return PAM_IGNORE; } pgu_ret = pam_get_user(pamh, &user, NULL); if (pgu_ret != PAM_SUCCESS || user == NULL) { DBG(("Unable to access user %s", user)); free(devices); devices = NULL; return PAM_CONV_ERR; } DBG(("Requesting authentication for user %s", user)); gpn_ret = getpwnam_r(user, &pw_s, buffer, sizeof(buffer), &pw); if (gpn_ret != 0 || pw == NULL || pw->pw_dir == NULL || pw->pw_dir[0] != '/') { DBG(("Unable to retrieve credentials for user %s, (%s)", user, strerror(errno))); retval = PAM_USER_UNKNOWN; goto done; } DBG(("Found user %s", user)); DBG(("Home directory for %s is %s", user, pw->pw_dir)); if (!cfg->auth_file) { buf = NULL; authfile_dir = secure_getenv(DEFAULT_AUTHFILE_DIR_VAR); if (!authfile_dir) { DBG(("Variable %s is not set. Using default value ($HOME/.config/)", DEFAULT_AUTHFILE_DIR_VAR)); authfile_dir_len = strlen(pw->pw_dir) + strlen("/.config") + strlen(DEFAULT_AUTHFILE) + 1; buf = malloc(sizeof(char) * (authfile_dir_len)); if (!buf) { DBG(("Unable to allocate memory")); retval = PAM_IGNORE; goto done; } strcpy(buf, pw->pw_dir); strcat(buf, "/.config"); strcat(buf, DEFAULT_AUTHFILE); } else { DBG(("Variable %s set to %s", DEFAULT_AUTHFILE_DIR_VAR, authfile_dir)); authfile_dir_len = strlen(authfile_dir) + strlen(DEFAULT_AUTHFILE) + 1; buf = malloc(sizeof(char) * (authfile_dir_len)); if (!buf) { DBG(("Unable to allocate memory")); retval = PAM_IGNORE; goto done; } strcpy(buf, authfile_dir); strcat(buf, DEFAULT_AUTHFILE); } DBG(("Using default authentication file %s", buf)); cfg->auth_file = strdup(buf); if (!cfg->auth_file) { DBG(("Unable to allocate memory")); retval = PAM_IGNORE; goto done; } free(buf); buf = NULL; } else { DBG(("Using authentication file %s", cfg->auth_file)); } retval = get_devices_from_authfile(cfg->auth_file, user, cfg->max_devs, cfg->debug, devices, &n_devices); if (retval != 1) { DBG(("Unable to get devices from file %s", cfg->auth_file)); retval = PAM_AUTHINFO_UNAVAIL; goto done; } if (n_devices == 0) { if (cfg->nouserok) { DBG(("Found no devices but nouserok specified. Skipping authentication")); retval = PAM_SUCCESS; goto done; } else { DBG(("Found no devices. Aborting.")); retval = PAM_AUTHINFO_UNAVAIL; goto done; } } if (cfg->manual == 0) { if (cfg->interactive) { converse(pamh, PAM_PROMPT_ECHO_ON, "Insert your U2F device, then press ENTER.\n"); } retval = do_authentication(cfg, devices, n_devices, pamh); } else { retval = do_manual_authentication(cfg, devices, n_devices, pamh); } if (retval != 1) { DBG(("do_authentication returned %d", retval)); retval = PAM_AUTH_ERR; goto done; } retval = PAM_SUCCESS; done: free_devices(devices, n_devices); if (buf) { free(buf); buf = NULL; } if (cfg->alwaysok && retval != PAM_SUCCESS) { DBG(("alwaysok needed (otherwise return with %d)", retval)); retval = PAM_SUCCESS; } DBG(("done. [%s]", pam_strerror(pamh, retval))); return retval; }