View | Details | Raw Unified | Return to bug 2246 | Differences between
and this patch

Collapse All | Expand All

(-)orig/auth-pam.c (+109 lines)
Lines 617-622 Link Here
617
	sshpam_handle = NULL;
617
	sshpam_handle = NULL;
618
}
618
}
619
619
620
#ifdef PAM_ENHANCEMENT
621
char *
622
derive_pam_service_name(Authctxt *authctxt)
623
{
624
	char *svcname = xmalloc(BUFSIZ);
625
626
	/*
627
	 * If PamServiceName is set we use that for everything, including
628
	 * SSHv1
629
	 */
630
	if (options.pam_service_name != NULL) {
631
		(void) strlcpy(svcname, options.pam_service_name, BUFSIZ);
632
		return (svcname);
633
	}
634
635
	if (compat20) {
636
		char *method_name = authctxt->authmethod_name;
637
638
		if (!method_name)
639
			fatal("Userauth method unknown while starting PAM");
640
641
		/*
642
		 * For SSHv2 we use "sshd-<userauth name>
643
		 * The "sshd" prefix can be changed via the PAMServicePrefix
644
		 * sshd_config option.
645
		 */
646
		if (strcmp(method_name, "none") == 0) {
647
			snprintf(svcname, BUFSIZ, "%s-none",
648
			    options.pam_service_prefix);
649
		}
650
		if (strcmp(method_name, "password") == 0) {
651
			snprintf(svcname, BUFSIZ, "%s-password",
652
			    options.pam_service_prefix);
653
		}
654
		if (strcmp(method_name, "keyboard-interactive") == 0) {
655
			/* "keyboard-interactive" is too long, shorten it */
656
			snprintf(svcname, BUFSIZ, "%s-kbdint",
657
			    options.pam_service_prefix);
658
		}
659
		if (strcmp(method_name, "publickey") == 0) {
660
			/* "publickey" is too long, shorten it */
661
			snprintf(svcname, BUFSIZ, "%s-pubkey",
662
			    options.pam_service_prefix);
663
		}
664
		if (strcmp(method_name, "hostbased") == 0) {
665
			snprintf(svcname, BUFSIZ, "%s-hostbased",
666
			    options.pam_service_prefix);
667
		}
668
		if (strncmp(method_name, "gssapi-", 7) == 0) {
669
		        /*
670
			 * Although OpenSSH only supports "gssapi-with-mic"
671
			 * for now. We will still map any userauth method
672
                         * prefixed with "gssapi-" to the gssapi PAM service.
673
			 */ 
674
			snprintf(svcname, BUFSIZ, "%s-gssapi",
675
			    options.pam_service_prefix);
676
		}
677
		return svcname;
678
	} else {
679
		/* SSHv1 doesn't get to be so cool */
680
	        snprintf(svcname, BUFSIZ, "sshd-v1");
681
	}
682
	return svcname;
683
}
684
#endif /* PAM_ENHANCEMENT */
685
620
static int
686
static int
621
sshpam_init(Authctxt *authctxt)
687
sshpam_init(Authctxt *authctxt)
622
{
688
{
Lines 624-641 Link Here
624
	const char *pam_rhost, *pam_user, *user = authctxt->user;
690
	const char *pam_rhost, *pam_user, *user = authctxt->user;
625
	const char **ptr_pam_user = &pam_user;
691
	const char **ptr_pam_user = &pam_user;
626
692
693
#ifdef PAM_ENHANCEMENT
694
	const char *pam_service;
695
        const char **ptr_pam_service = &pam_service;
696
	char *svc = NULL;
697
698
	svc = derive_pam_service_name(authctxt);
699
        debug3("PAM service is %s", svc);
700
#endif
701
627
	if (sshpam_handle != NULL) {
702
	if (sshpam_handle != NULL) {
703
#ifdef PAM_ENHANCEMENT
704
	        /* get the pam service name */
705
		sshpam_err = pam_get_item(sshpam_handle,
706
		    PAM_SERVICE, (sshpam_const void **)ptr_pam_service);
707
                if (sshpam_err != PAM_SUCCESS) 
708
		    fatal("Failed to get the PAM service name");
709
		debug3("Previous pam_service is %s", pam_service ?
710
                    pam_service : "NULL");
711
712
		/* get the pam user name */
713
		sshpam_err = pam_get_item(sshpam_handle,
714
		    PAM_USER, (sshpam_const void **)ptr_pam_user);
715
716
		/*
717
		 * only need to re-start if either user or service is 
718
                 * different.
719
                 */
720
		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0
721
		    && strncmp(svc, pam_service, strlen(svc)) == 0) {
722
		        free(svc);
723
			return (0);
724
                }
725
726
#else /* Original */
628
		/* We already have a PAM context; check if the user matches */
727
		/* We already have a PAM context; check if the user matches */
629
		sshpam_err = pam_get_item(sshpam_handle,
728
		sshpam_err = pam_get_item(sshpam_handle,
630
		    PAM_USER, (sshpam_const void **)ptr_pam_user);
729
		    PAM_USER, (sshpam_const void **)ptr_pam_user);
631
		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
730
		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
632
			return (0);
731
			return (0);
732
#endif /* PAM_ENHANCEMENT */
633
		pam_end(sshpam_handle, sshpam_err);
733
		pam_end(sshpam_handle, sshpam_err);
634
		sshpam_handle = NULL;
734
		sshpam_handle = NULL;
635
	}
735
	}
636
	debug("PAM: initializing for \"%s\"", user);
736
	debug("PAM: initializing for \"%s\"", user);
737
738
#ifdef PAM_ENHANCEMENT
739
        debug3("Starting PAM service %s for user %s method %s", svc, user,
740
            authctxt->authmethod_name);
637
	sshpam_err =
741
	sshpam_err =
742
	    pam_start(svc, user, &store_conv, &sshpam_handle);
743
	free(svc);
744
#else /* Original */
745
	sshpam_err =
638
	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
746
	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
747
#endif
639
	sshpam_authctxt = authctxt;
748
	sshpam_authctxt = authctxt;
640
749
641
	if (sshpam_err != PAM_SUCCESS) {
750
	if (sshpam_err != PAM_SUCCESS) {
(-)orig/auth.h (+3 lines)
Lines 76-81 Link Here
76
#endif
76
#endif
77
	Buffer		*loginmsg;
77
	Buffer		*loginmsg;
78
	void		*methoddata;
78
	void		*methoddata;
79
#ifdef PAM_ENHANCEMENT
80
        char            *authmethod_name;
81
#endif 
79
};
82
};
80
/*
83
/*
81
 * Every authentication method has to handle authentication requests for
84
 * Every authentication method has to handle authentication requests for
(-)orig/auth2.c (-2 / +15 lines)
Lines 249-258 Link Here
249
			PRIVSEP(audit_event(SSH_INVALID_USER));
249
			PRIVSEP(audit_event(SSH_INVALID_USER));
250
#endif
250
#endif
251
		}
251
		}
252
253
#ifndef PAM_ENHANCEMENT
252
#ifdef USE_PAM
254
#ifdef USE_PAM
253
		if (options.use_pam)
255
		if (options.use_pam)
254
			PRIVSEP(start_pam(authctxt));
256
			PRIVSEP(start_pam(authctxt));
255
#endif
257
#endif
258
#endif
256
		setproctitle("%s%s", authctxt->valid ? user : "unknown",
259
		setproctitle("%s%s", authctxt->valid ? user : "unknown",
257
		    use_privsep ? " [net]" : "");
260
		    use_privsep ? " [net]" : "");
258
		authctxt->service = xstrdup(service);
261
		authctxt->service = xstrdup(service);
Lines 286-291 Link Here
286
	/* try to authenticate user */
289
	/* try to authenticate user */
287
	m = authmethod_lookup(authctxt, method);
290
	m = authmethod_lookup(authctxt, method);
288
	if (m != NULL && authctxt->failures < options.max_authtries) {
291
	if (m != NULL && authctxt->failures < options.max_authtries) {
292
293
#ifdef PAM_ENHANCEMENT
294
                authctxt->authmethod_name = xstrdup(method);
295
                if (use_privsep)
296
                       mm_inform_authmethod(method);
297
		if (options.use_pam)
298
		       PRIVSEP(start_pam(authctxt));
299
#endif
289
		debug2("input_userauth_request: try method %s", method);
300
		debug2("input_userauth_request: try method %s", method);
290
		authenticated =	m->userauth(authctxt);
301
		authenticated =	m->userauth(authctxt);
291
	}
302
	}
Lines 303-308 Link Here
303
	char *methods;
314
	char *methods;
304
	int partial = 0;
315
	int partial = 0;
305
316
317
#ifdef  PAM_ENHANCEMENT
318
        debug3("%s: entering", __func__);
319
#endif
320
306
	if (!authctxt->valid && authenticated)
321
	if (!authctxt->valid && authenticated)
307
		fatal("INTERNAL ERROR: authenticated invalid user %s",
322
		fatal("INTERNAL ERROR: authenticated invalid user %s",
308
		    authctxt->user);
323
		    authctxt->user);
Lines 623-627 Link Here
623
		fatal("%s: method not in AuthenticationMethods", __func__);
638
		fatal("%s: method not in AuthenticationMethods", __func__);
624
	return 0;
639
	return 0;
625
}
640
}
626
627
(-)orig/monitor_wrap.c (+18 lines)
Lines 338-343 Link Here
338
	buffer_free(&m);
338
	buffer_free(&m);
339
}
339
}
340
340
341
#ifdef PAM_ENHANCEMENT
342
/* Inform the privileged process about the authentication method */
343
void
344
mm_inform_authmethod(char *authmethod)
345
{
346
	Buffer m;
347
348
	debug3("%s entering", __func__);
349
350
	buffer_init(&m);
351
	buffer_put_cstring(&m, authmethod);
352
353
	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHMETHOD, &m);
354
355
	buffer_free(&m);
356
}
357
#endif
358
341
/* Do the password authentication */
359
/* Do the password authentication */
342
int
360
int
343
mm_auth_password(Authctxt *authctxt, char *password)
361
mm_auth_password(Authctxt *authctxt, char *password)
(-)orig/monitor.c (+32 lines)
Lines 146-151 Link Here
146
int mm_answer_pwnamallow(int, Buffer *);
146
int mm_answer_pwnamallow(int, Buffer *);
147
int mm_answer_auth2_read_banner(int, Buffer *);
147
int mm_answer_auth2_read_banner(int, Buffer *);
148
int mm_answer_authserv(int, Buffer *);
148
int mm_answer_authserv(int, Buffer *);
149
#ifdef PAM_ENHANCEMENT
150
int mm_answer_authmethod(int, Buffer *);
151
#endif
149
int mm_answer_authpassword(int, Buffer *);
152
int mm_answer_authpassword(int, Buffer *);
150
int mm_answer_bsdauthquery(int, Buffer *);
153
int mm_answer_bsdauthquery(int, Buffer *);
151
int mm_answer_bsdauthrespond(int, Buffer *);
154
int mm_answer_bsdauthrespond(int, Buffer *);
Lines 225-234 Link Here
225
    {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
228
    {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
226
    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
229
    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
227
    {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
230
    {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
231
#ifdef PAM_ENHANCEMENT
232
    {MONITOR_REQ_AUTHMETHOD, MON_ISAUTH, mm_answer_authmethod},
233
#endif
228
    {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
234
    {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
229
    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
235
    {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
230
#ifdef USE_PAM
236
#ifdef USE_PAM
237
#ifdef PAM_ENHANCEMENT
238
    {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
239
#else
231
    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
240
    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
241
#endif
232
    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
242
    {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
233
    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
243
    {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
234
    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
244
    {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
Lines 828-833 Link Here
828
		/* Allow service/style information on the auth context */
838
		/* Allow service/style information on the auth context */
829
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
839
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
830
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
840
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
841
#ifdef PAM_ENHANCEMENT
842
                /* Allow authmethod information on the auth context */
843
		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHMETHOD, 1);
844
#endif
831
	}
845
	}
832
#ifdef USE_PAM
846
#ifdef USE_PAM
833
	if (options.use_pam)
847
	if (options.use_pam)
Lines 868-874 Link Here
868
	return (0);
882
	return (0);
869
}
883
}
870
884
885
#ifdef PAM_ENHANCEMENT
871
int
886
int
887
mm_answer_authmethod(int sock, Buffer *m)
888
{
889
	monitor_permit_authentications(1);
890
891
	authctxt->authmethod_name = buffer_get_string(m, NULL);
892
	debug3("%s: authmethod_name=%s", __func__, authctxt->authmethod_name);
893
894
	if (strlen(authctxt->authmethod_name) == 0) {
895
		free(authctxt->authmethod_name);
896
		authctxt->authmethod_name = NULL;
897
	}
898
899
	return (0);
900
}
901
#endif
902
903
int
872
mm_answer_authpassword(int sock, Buffer *m)
904
mm_answer_authpassword(int sock, Buffer *m)
873
{
905
{
874
	static int call_count;
906
	static int call_count;
(-)orig/monitor.h (+3 lines)
Lines 70-75 Link Here
70
	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
70
	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
71
	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
71
	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
72
72
73
#ifdef PAM_ENHANCEMENT
74
        MONITOR_REQ_AUTHMETHOD = 114,
75
#endif        
73
};
76
};
74
77
75
struct mm_master;
78
struct mm_master;
(-)orig/servconf.c (+41 lines)
Lines 154-159 Link Here
154
	options->ip_qos_interactive = -1;
154
	options->ip_qos_interactive = -1;
155
	options->ip_qos_bulk = -1;
155
	options->ip_qos_bulk = -1;
156
	options->version_addendum = NULL;
156
	options->version_addendum = NULL;
157
#ifdef PAM_ENHANCEMENT
158
	options->pam_service_name = NULL;
159
	options->pam_service_prefix = NULL;
160
#endif
157
}
161
}
158
162
159
void
163
void
Lines 303-308 Link Here
303
		options->ip_qos_bulk = IPTOS_THROUGHPUT;
307
		options->ip_qos_bulk = IPTOS_THROUGHPUT;
304
	if (options->version_addendum == NULL)
308
	if (options->version_addendum == NULL)
305
		options->version_addendum = xstrdup("");
309
		options->version_addendum = xstrdup("");
310
311
#ifdef PAM_ENHANCEMENT
312
        if (options->pam_service_prefix == NULL)
313
                options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX;
314
#endif
315
306
	/* Turn privilege separation on by default */
316
	/* Turn privilege separation on by default */
307
	if (use_privsep == -1)
317
	if (use_privsep == -1)
308
		use_privsep = PRIVSEP_NOSANDBOX;
318
		use_privsep = PRIVSEP_NOSANDBOX;
Lines 351-356 Link Here
351
	sKexAlgorithms, sIPQoS, sVersionAddendum,
361
	sKexAlgorithms, sIPQoS, sVersionAddendum,
352
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
362
	sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
353
	sAuthenticationMethods, sHostKeyAgent,
363
	sAuthenticationMethods, sHostKeyAgent,
364
#ifdef PAM_ENHANCEMENT
365
	sPAMServicePrefix, sPAMServiceName,
366
#endif
354
	sDeprecated, sUnsupported
367
	sDeprecated, sUnsupported
355
} ServerOpCodes;
368
} ServerOpCodes;
356
369
Lines 482-487 Link Here
482
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
495
	{ "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
483
	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
496
	{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
484
	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
497
	{ "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
498
#ifdef PAM_ENHANCEMENT
499
        { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL },
500
        { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL },
501
#endif
485
	{ NULL, sBadOption, 0 }
502
	{ NULL, sBadOption, 0 }
486
};
503
};
487
504
Lines 1632-1637 Link Here
1632
		}
1649
		}
1633
		return 0;
1650
		return 0;
1634
1651
1652
	case sPAMServicePrefix:
1653
		arg = strdelim(&cp);
1654
		if (!arg || *arg == '\0')
1655
			fatal("%s line %d: Missing argument.",
1656
			    filename, linenum);
1657
		if (options->pam_service_name != NULL)
1658
			fatal("%s line %d: PAMServiceName and PAMServicePrefix"
1659
			    " are mutually exclusive.", filename, linenum);
1660
		if (options->pam_service_prefix == NULL)
1661
			options->pam_service_prefix = xstrdup(arg);
1662
		break;
1663
1664
	case sPAMServiceName:
1665
		arg = strdelim(&cp);
1666
		if (!arg || *arg == '\0')
1667
			fatal("%s line %d: Missing argument.",
1668
			    filename, linenum);
1669
		if (options->pam_service_prefix != NULL)
1670
			fatal("%s line %d: PAMServiceName and PAMServicePrefix"
1671
			    " are mutually exclusive.", filename, linenum);
1672
		if (options->pam_service_name == NULL)
1673
			options->pam_service_name = xstrdup(arg);
1674
		break;
1675
1635
	case sDeprecated:
1676
	case sDeprecated:
1636
		logit("%s line %d: Deprecated option %s",
1677
		logit("%s line %d: Deprecated option %s",
1637
		    filename, linenum, arg);
1678
		    filename, linenum, arg);
(-)orig/servconf.h (+10 lines)
Lines 54-59 Link Here
54
/* Magic name for internal sftp-server */
54
/* Magic name for internal sftp-server */
55
#define INTERNAL_SFTP_NAME	"internal-sftp"
55
#define INTERNAL_SFTP_NAME	"internal-sftp"
56
56
57
#ifdef PAM_ENHANCEMENT
58
#define _SSH_PAM_SERVICE_PREFIX "sshd"
59
#endif
60
57
typedef struct {
61
typedef struct {
58
	u_int	num_ports;
62
	u_int	num_ports;
59
	u_int	ports_from_cmdline;
63
	u_int	ports_from_cmdline;
Lines 185-190 Link Here
185
189
186
	u_int	num_auth_methods;
190
	u_int	num_auth_methods;
187
	char   *auth_methods[MAX_AUTH_METHODS];
191
	char   *auth_methods[MAX_AUTH_METHODS];
192
193
#ifdef PAM_ENHANCEMENT
194
	char   *pam_service_prefix;
195
	char   *pam_service_name;
196
#endif
197
        
188
}       ServerOptions;
198
}       ServerOptions;
189
199
190
/* Information about the incoming connection as used by Match */
200
/* Information about the incoming connection as used by Match */
(-)orig/sshd_config.5 (+15 lines)
Lines 868-873 Link Here
868
are refused if the number of unauthenticated connections reaches
868
are refused if the number of unauthenticated connections reaches
869
.Dq full
869
.Dq full
870
(60).
870
(60).
871
.It Cm PAMServiceName
872
Specifies the PAM service name for the PAM session. The PAMServiceName and 
873
PAMServicePrefix options are mutually exclusive and if both set, sshd does not
874
start. If this option is set the service name is the same for all user 
875
authentication methods. The option has no default value. See PAMServicePrefix 
876
for more information.
877
.It Cm PAMServicePrefix
878
Specifies the PAM service name prefix for service names used for individual 
879
user authentication methods. The default is sshd. The PAMServiceName and 
880
PAMServicePrefix options are mutually exclusive and if both set, sshd does not 
881
start.
882
.Pp
883
For example, if this option is set to admincli, the service name for the 
884
keyboard-interactive authentication method is admincli-kbdint instead of the 
885
default sshd-kbdint.
871
.It Cm PasswordAuthentication
886
.It Cm PasswordAuthentication
872
Specifies whether password authentication is allowed.
887
Specifies whether password authentication is allowed.
873
The default is
888
The default is
(-)orig/sshd.8 (+27 lines)
Lines 951-956 Link Here
951
started last).
951
started last).
952
The content of this file is not sensitive; it can be world-readable.
952
The content of this file is not sensitive; it can be world-readable.
953
.El
953
.El
954
955
.Sh SECURITY
956
sshd uses pam(3PAM) for password and keyboard-interactive methods as well as 
957
for account management, session management, and the password management for all
958
authentication methods.
959
.Pp
960
Each SSHv2 userauth type has its own PAM service name:
961
962
.Bd -literal -offset 3n
963
964
-----------------------------------------------
965
| SSHv2 Userauth       | PAM Service Name     |
966
-----------------------------------------------
967
| none                 | sshd-none            |
968
-----------------------------------------------
969
| password             | sshd-password        |
970
-----------------------------------------------
971
| keyboard-interactive | sshd-kbdint          |
972
-----------------------------------------------
973
| pubkey               | sshd-pubkey          |
974
-----------------------------------------------
975
| hostbased            | sshd-hostbased       |
976
-----------------------------------------------
977
| gssapi-with-mic      | sshd-gssapi          |
978
-----------------------------------------------
979
.Ed
980
954
.Sh SEE ALSO
981
.Sh SEE ALSO
955
.Xr scp 1 ,
982
.Xr scp 1 ,
956
.Xr sftp 1 ,
983
.Xr sftp 1 ,

Return to bug 2246