📄 winbind.c
字号:
/************************************************************************* winbind.c** WINBIND plugin for pppd. Performs PAP, CHAP, MS-CHAP, MS-CHAPv2* authentication using WINBIND to contact a NT-style PDC.* * Based on the structure of the radius module.** Copyright (C) 2003 Andrew Bartlet <abartlet@samba.org>** Copyright 1999 Paul Mackerras, Alan Curry. * (pipe read code from passpromt.c)** Copyright (C) 2002 Roaring Penguin Software Inc.** Based on a patch for ipppd, which is:* Copyright (C) 1996, Matjaz Godec <gody@elgo.si>* Copyright (C) 1996, Lars Fenneberg <in5y050@public.uni-hamburg.de>* Copyright (C) 1997, Miguel A.L. Paraz <map@iphil.net>** Uses radiusclient library, which is:* Copyright (C) 1995,1996,1997,1998 Lars Fenneberg <lf@elemental.net>* Copyright (C) 2002 Roaring Penguin Software Inc.** MPPE support is by Ralf Hofmann, <ralf.hofmann@elvido.net>, with* modification from Frank Cusack, <frank@google.com>.** Updated on 2003-12-12 to support updated PPP plugin API from latest CVS* Copyright (C) 2003, Sean E. Millichamp <sean at bruenor dot org>** This plugin may be distributed according to the terms of the GNU* General Public License, version 2 or (at your option) any later version.************************************************************************/#include "pppd.h"#include "chap-new.h"#include "chap_ms.h"#ifdef MPPE#include "md5.h"#endif#include "fsm.h"#include "ipcp.h"#include <syslog.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/time.h>#include <sys/wait.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <ctype.h>#define BUF_LEN 1024#define NOT_AUTHENTICATED 0#define AUTHENTICATED 1static char *ntlm_auth = NULL;static int set_ntlm_auth(char **argv){ char *p; p = argv[0]; if (p[0] != '/') { option_error("ntlm_auth-helper argument must be full path"); return 0; } p = strdup(p); if (p == NULL) { novm("ntlm_auth-helper argument"); return 0; } if (ntlm_auth != NULL) free(ntlm_auth); ntlm_auth = p; return 1;}static option_t Options[] = { { "ntlm_auth-helper", o_special, (void *) &set_ntlm_auth, "Path to ntlm_auth executable", OPT_PRIV }, { NULL }};static intwinbind_secret_check(void);static int winbind_pap_auth(char *user, char *passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts);static int winbind_chap_verify(char *user, char *ourname, int id, struct chap_digest_type *digest, unsigned char *challenge, unsigned char *response, char *message, int message_space);static int winbind_allowed_address(u_int32_t addr); char pppd_version[] = VERSION;/*********************************************************************** %FUNCTION: plugin_init* %ARGUMENTS:* None* %RETURNS:* Nothing* %DESCRIPTION:* Initializes WINBIND plugin.***********************************************************************/voidplugin_init(void){ pap_check_hook = winbind_secret_check; pap_auth_hook = winbind_pap_auth; chap_check_hook = winbind_secret_check; chap_verify_hook = winbind_chap_verify; allowed_address_hook = winbind_allowed_address; /* Don't ask the peer for anything other than MS-CHAP or MS-CHAP V2 */ chap_mdtype_all &= (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT); add_options(Options); info("WINBIND plugin initialized.");}/** Routine to get hex characters and turn them into a 16 byte array. the array can be variable length, and any non-hex-numeric characters are skipped. "0xnn" or "0Xnn" is specially catered for. valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"**//* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Andrew Tridgell 1992-2001 Copyright (C) Simo Sorce 2001-2002 Copyright (C) Martin Pool 2003 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.*/size_t strhex_to_str(char *p, size_t len, const char *strhex){ size_t i; size_t num_chars = 0; unsigned char lonybble, hinybble; const char *hexchars = "0123456789ABCDEF"; char *p1 = NULL, *p2 = NULL; for (i = 0; i < len && strhex[i] != 0; i++) { if (strncmp(hexchars, "0x", 2) == 0) { i++; /* skip two chars */ continue; } if (!(p1 = strchr(hexchars, toupper(strhex[i])))) break; i++; /* next hex digit */ if (!(p2 = strchr(hexchars, toupper(strhex[i])))) break; /* get the two nybbles */ hinybble = (p1 - hexchars); lonybble = (p2 - hexchars); p[num_chars] = (hinybble << 4) | lonybble; num_chars++; p1 = NULL; p2 = NULL; } return num_chars;}static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";/** * Encode a base64 string into a malloc()ed string caller to free. * *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments **/char * base64_encode(const char *data){ size_t out_cnt = 0; size_t len = strlen(data); size_t output_len = 4 * ((len + 2) / 3) + 2; const unsigned char *ptr = (const unsigned char *) data; char *result = malloc(output_len); /* get us plenty of space */ unsigned int bits; for (; len >= 3; len -= 3) { bits = (ptr[0] << 16) + (ptr[1] << 8) + ptr[2]; ptr += 3; result[out_cnt++] = b64[bits >> 18]; result[out_cnt++] = b64[(bits >> 12) & 0x3f]; result[out_cnt++] = b64[(bits >> 6) & 0x3f]; result[out_cnt++] = b64[bits & 0x3f]; } if (len != 0) { bits = ptr[0] << 16; if (len > 1) bits |= ptr[1] << 8; result[out_cnt++] = b64[bits >> 18]; result[out_cnt++] = b64[(bits >> 12) & 0x3f]; result[out_cnt++] = (len > 1)? b64[(bits >> 6) & 0x3f]: '='; result[out_cnt++] = '='; } result[out_cnt] = '\0'; /* terminate */ return result;}unsigned int run_ntlm_auth(const char *username, const char *domain, const char *full_username, const char *plaintext_password, const u_char *challenge, size_t challenge_length, const u_char *lm_response, size_t lm_response_length, const u_char *nt_response, size_t nt_response_length, u_char nt_key[16], char **error_string) { pid_t forkret; int child_in[2]; int child_out[2]; int status; int authenticated = NOT_AUTHENTICATED; /* not auth */ int got_user_session_key = 0; /* not got key */ char buffer[1024]; FILE *pipe_in; FILE *pipe_out; int i; char *challenge_hex; char *lm_hex_hash; char *nt_hex_hash; /* First see if we have a program to run... */ if (ntlm_auth == NULL) return NOT_AUTHENTICATED; /* Make first child */ if (pipe(child_out) == -1) { error("pipe creation failed for child OUT!"); return NOT_AUTHENTICATED; } if (pipe(child_in) == -1) { error("pipe creation failed for child IN!"); return NOT_AUTHENTICATED; } forkret = safe_fork(child_in[0], child_out[1], 2); if (forkret == -1) { if (error_string) { *error_string = strdup("fork failed!"); } return NOT_AUTHENTICATED; } if (forkret == 0) { /* child process */ uid_t uid; close(child_out[0]); close(child_in[1]); /* run winbind as the user that invoked pppd */ setgid(getgid()); uid = getuid(); if (setuid(uid) == -1 || getuid() != uid) fatal("pppd/winbind: could not setuid to %d: %m", uid); execl("/bin/sh", "sh", "-c", ntlm_auth, NULL); fatal("pppd/winbind: could not exec /bin/sh: %m"); } /* parent */ close(child_out[1]); close(child_in[0]); /* Need to write the User's info onto the pipe */ pipe_in = fdopen(child_in[1], "w"); pipe_out = fdopen(child_out[0], "r"); /* look for session key coming back */ if (username) { char *b64_username = base64_encode(username); fprintf(pipe_in, "Username:: %s\n", b64_username); free(b64_username); } if (domain) { char *b64_domain = base64_encode(domain); fprintf(pipe_in, "NT-Domain:: %s\n", b64_domain); free(b64_domain); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -